Skip to content

Commit

Permalink
chore: refactor api
Browse files Browse the repository at this point in the history
  • Loading branch information
potts99 committed Nov 12, 2024
1 parent 97ddf60 commit 00b4155
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 89 deletions.
100 changes: 58 additions & 42 deletions apps/api/src/controllers/webhooks.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,94 @@
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { checkToken } from "../lib/jwt";
import { prisma } from "../prisma";
import { FastifyInstance } from "fastify";
import { track } from "../lib/hog";
import { Hook, prisma } from "../prisma";

// Type definitions
interface WebhookPayload {
name: string;
url: string;
type: Hook;
active: boolean;
secret: string;
}

export function webhookRoutes(fastify: FastifyInstance) {
// Create a new webhook
fastify.post(
fastify.post<{ Body: WebhookPayload }>(
"/api/v1/webhook/create",
async (request, reply) => {
try {
const { name, url, type, active, secret } = request.body;

async (request: FastifyRequest, reply: FastifyReply) => {
const bearer = request.headers.authorization!.split(" ")[1];
const token = checkToken(bearer);

if (token) {
const { name, url, type, active, secret }: any = request.body;
await prisma.webhooks.create({
const webhook = await prisma.webhooks.create({
data: {
name,
url,
type,
active,
secret,
createdBy: "375f7799-5485-40ff-ba8f-0a28e0855ecf",
createdBy: "375f7799-5485-40ff-ba8f-0a28e0855ecf", // TODO: Get from authenticated user
},
});

const client = track();

client.capture({
await client.capture({
event: "webhook_created",
distinctId: "uuid",
distinctId: webhook.id, // Use actual webhook ID
});
await client.shutdownAsync();

client.shutdownAsync();

reply.status(200).send({ message: "Hook created!", success: true });
return reply.status(201).send({
data: webhook,
success: true,
});
} catch (error) {
return reply.status(400).send({
error:
error instanceof Error ? error.message : "Failed to create webhook",
success: false,
});
}
}
);

// Get all webhooks
fastify.get(
"/api/v1/webhooks/all",

async (request: FastifyRequest, reply: FastifyReply) => {
const bearer = request.headers.authorization!.split(" ")[1];
const token = checkToken(bearer);

if (token) {
const webhooks = await prisma.webhooks.findMany({});
fastify.get("/api/v1/webhooks/all", async (request, reply) => {
try {
const webhooks = await prisma.webhooks.findMany();

reply.status(200).send({ webhooks: webhooks, success: true });
}
return reply.status(200).send({
data: webhooks,
success: true,
});
} catch (error) {
return reply.status(400).send({
error:
error instanceof Error ? error.message : "Failed to fetch webhooks",
success: false,
});
}
);
});

// Delete a webhook

fastify.delete(
fastify.delete<{ Params: { id: string } }>(
"/api/v1/admin/webhook/:id/delete",
async (request, reply) => {
try {
const { id } = request.params;

async (request: FastifyRequest, reply: FastifyReply) => {
const bearer = request.headers.authorization!.split(" ")[1];
const token = checkToken(bearer);

if (token) {
const { id }: any = request.params;
await prisma.webhooks.delete({
where: {
id: id,
},
where: { id },
});

reply.status(200).send({ success: true });
return reply.status(200).send({
success: true,
});
} catch (error) {
return reply.status(400).send({
error:
error instanceof Error ? error.message : "Failed to delete webhook",
success: false,
});
}
}
);
Expand Down
82 changes: 35 additions & 47 deletions apps/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import fs from "fs";
import { exec } from "child_process";
import { track } from "./lib/hog";
import { getEmails } from "./lib/imap";
import { checkToken } from "./lib/jwt";
import { prisma } from "./prisma";
import { registerRoutes } from "./routes";

// Ensure the directory exists
const logFilePath = './logs.log'; // Update this path to a writable location
const logFilePath = "./logs.log"; // Update this path to a writable location

// Create a writable stream
const logStream = fs.createWriteStream(logFilePath, { flags: 'a' });
const logStream = fs.createWriteStream(logFilePath, { flags: "a" });

// Initialize Fastify with logger
const server: FastifyInstance = Fastify({
Expand All @@ -26,62 +27,49 @@ const server: FastifyInstance = Fastify({
});
server.register(cors, {
origin: "*",

methods: ["GET", "POST", "PUT", "DELETE"],
allowedHeaders: ["Content-Type", "Authorization", "Accept"],
});

server.register(require("@fastify/swagger"), {
swagger: {
info: {
title: "Peppermint API DOCS",
description: "Peppermint swagger API",
version: "0.1.0",
},
externalDocs: {
url: "https://swagger.io",
description: "Find more info here",
},
mode: "static",
host: "localhost",
schemes: ["http"],
consumes: ["application/json"],
produces: ["application/json"],
tags: [
{ name: "user", description: "User related end-points" },
{ name: "code", description: "Code related end-points" },
],
exposeRoute: true,
definitions: {
User: {
type: "object",
required: ["id", "email"],
properties: {
id: { type: "string", format: "uuid" },
firstName: { type: "string" },
lastName: { type: "string" },
email: { type: "string", format: "email" },
},
},
},
securityDefinitions: {
apiKey: {
type: "apiKey",
name: "apiKey",
in: "header",
},
},
},
});

server.register(multer.contentParser);

registerRoutes(server);

server.get("/", async function (request, response) {
server.get("/", {
schema: {
tags: ['health'], // This groups the endpoint under a category
description: 'Health check endpoint',
response: {
200: {
type: 'object',
properties: {
healthy: { type: 'boolean' }
}
}
}
}
}, async function (request, response) {
response.send({ healthy: true });
});

server.addHook("preHandler", async (request, reply) => {
if (request.url.startsWith("/api/public") || request.url.startsWith("/documentation")) {
return;
}

try {
const bearer = request.headers.authorization?.split(" ")[1];
if (!bearer) throw new Error("No authorization token provided");
await checkToken(bearer);
} catch (error) {
reply.status(401).send({
error: "Authentication failed",
success: false,
});
}
});

const start = async () => {
try {
// Run prisma generate and migrate commands before starting the server
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/prisma.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import { PrismaClient } from "@prisma/client";
export const prisma: PrismaClient = new PrismaClient();
export type Hook = "ticket_created" | "ticket_status_changed";

0 comments on commit 00b4155

Please sign in to comment.