Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
1.8 kB ยท 61 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162// oxlint-disable-next-line unicorn/prefer-node-protocol -- some error with buildimport crypto from "crypto";
import { deleteIntegration, listIntegrations,} from "@openstatus/services/integration";import { z } from "zod";
import { toServiceCtx, toTRPCError } from "../service-adapter";import { createTRPCRouter, protectedProcedure } from "../trpc";
/** * Slack install-token generation stays router-local: no DB work, no * workspace-scoped business rule โ it's just HMAC plumbing against an env * secret and better kept alongside the Slack OAuth surface than inflated * into a service verb. */function signInstallToken(args: { workspaceId: number; userId: number; ts: number;}): string { const secret = process.env.SLACK_SIGNING_SECRET; if (!secret) throw new Error("Slack not configured"); const payload = JSON.stringify(args); const sig = crypto.createHmac("sha256", secret).update(payload).digest("hex"); return Buffer.from(`${payload}.${sig}`).toString("base64url");}
export const integrationRouter = createTRPCRouter({ list: protectedProcedure.query(async ({ ctx }) => { try { return await listIntegrations({ ctx: toServiceCtx(ctx) }); } catch (err) { toTRPCError(err); } }),
generateInstallToken: protectedProcedure.mutation(async ({ ctx }) => { const token = signInstallToken({ workspaceId: ctx.workspace.id, userId: ctx.user.id, ts: Date.now(), }); return { token }; }),
deleteIntegration: protectedProcedure .input(z.object({ integrationId: z.number() })) .mutation(async ({ ctx, input }) => { try { await deleteIntegration({ ctx: toServiceCtx(ctx), input: { id: input.integrationId }, }); } catch (err) { toTRPCError(err); } }),});