Openstatus www.openstatus.dev
at 0580c562a6f62100a34f50c6aa910ff8fdb7d519 90 lines 2.6 kB view raw
1import { UnkeyCore } from "@unkey/api/core"; 2import { apisListKeys } from "@unkey/api/funcs/apisListKeys"; 3import { keysCreateKey } from "@unkey/api/funcs/keysCreateKey"; 4import { keysDeleteKey } from "@unkey/api/funcs/keysDeleteKey"; 5import { z } from "zod"; 6 7import { Events } from "@openstatus/analytics"; 8import { db, eq } from "@openstatus/db"; 9import { user, usersToWorkspaces, workspace } from "@openstatus/db/src/schema"; 10 11import { TRPCError } from "@trpc/server"; 12import { env } from "../env"; 13import { createTRPCRouter, protectedProcedure } from "../trpc"; 14 15export const apiKeyRouter = createTRPCRouter({ 16 create: protectedProcedure 17 .meta({ track: Events.CreateAPI }) 18 .input(z.object({ ownerId: z.number() })) 19 .mutation(async ({ input, ctx }) => { 20 const unkey = new UnkeyCore({ rootKey: env.UNKEY_TOKEN }); 21 22 const allowedWorkspaces = await db 23 .select() 24 .from(usersToWorkspaces) 25 .innerJoin(user, eq(user.id, usersToWorkspaces.userId)) 26 .innerJoin(workspace, eq(workspace.id, usersToWorkspaces.workspaceId)) 27 .where(eq(user.id, ctx.user.id)) 28 .all(); 29 30 const allowedIds = allowedWorkspaces.map((i) => i.workspace.id); 31 32 if (!allowedIds.includes(input.ownerId)) { 33 throw new TRPCError({ 34 code: "UNAUTHORIZED", 35 message: "Unauthorized", 36 }); 37 } 38 39 const res = await keysCreateKey(unkey, { 40 apiId: env.UNKEY_API_ID, 41 externalId: String(input.ownerId), 42 prefix: "os", 43 }); 44 45 if (!res.ok) { 46 throw new TRPCError({ 47 code: "BAD_REQUEST", 48 message: res.error.message, 49 }); 50 } 51 52 return res.value.data; 53 }), 54 55 revoke: protectedProcedure 56 .meta({ track: Events.RevokeAPI }) 57 .input(z.object({ keyId: z.string() })) 58 .mutation(async ({ input }) => { 59 const unkey = new UnkeyCore({ rootKey: env.UNKEY_TOKEN }); 60 61 const res = await keysDeleteKey(unkey, { keyId: input.keyId }); 62 63 if (!res.ok) { 64 throw new TRPCError({ 65 code: "BAD_REQUEST", 66 message: res.error.message, 67 }); 68 } 69 70 return res.value; 71 }), 72 73 get: protectedProcedure.query(async ({ ctx }) => { 74 const unkey = new UnkeyCore({ rootKey: env.UNKEY_TOKEN }); 75 76 const res = await apisListKeys(unkey, { 77 externalId: String(ctx.workspace.id), 78 apiId: env.UNKEY_API_ID, 79 }); 80 81 if (!res.ok) { 82 throw new TRPCError({ 83 code: "BAD_REQUEST", 84 message: res.error.message, 85 }); 86 } 87 88 return res.value.data[0]; 89 }), 90});