| import { z } from "zod" |
| import { fn } from "./util/fn" |
| import { Actor } from "./actor" |
| import { and, Database, eq, isNull, sql } from "./drizzle" |
| import { Identifier } from "./identifier" |
| import { KeyTable } from "./schema/key.sql" |
| import { UserTable } from "./schema/user.sql" |
| import { AuthTable } from "./schema/auth.sql" |
|
|
| export namespace Key { |
| export const list = fn(z.void(), async () => { |
| const keys = await Database.use((tx) => |
| tx |
| .select({ |
| id: KeyTable.id, |
| name: KeyTable.name, |
| key: KeyTable.key, |
| timeUsed: KeyTable.timeUsed, |
| userID: KeyTable.userID, |
| email: AuthTable.subject, |
| }) |
| .from(KeyTable) |
| .innerJoin(UserTable, and(eq(KeyTable.userID, UserTable.id), eq(KeyTable.workspaceID, UserTable.workspaceID))) |
| .innerJoin(AuthTable, and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email"))) |
| .where( |
| and( |
| eq(KeyTable.workspaceID, Actor.workspace()), |
| isNull(KeyTable.timeDeleted), |
| ...(Actor.userRole() === "admin" ? [] : [eq(KeyTable.userID, Actor.userID())]), |
| ), |
| ) |
| .orderBy(sql`${KeyTable.name} DESC`), |
| ) |
| |
| return keys.map((key) => ({ |
| ...key, |
| key: key.userID === Actor.userID() ? key.key : undefined, |
| keyDisplay: `${key.key.slice(0, 7)}...${key.key.slice(-4)}`, |
| })) |
| }) |
|
|
| export const create = fn( |
| z.object({ |
| userID: z.string(), |
| name: z.string().min(1).max(255), |
| }), |
| async (input) => { |
| const { name } = input |
|
|
| |
| const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
| let secretKey = "sk-" |
| const array = new Uint32Array(64) |
| crypto.getRandomValues(array) |
| for (let i = 0, l = array.length; i < l; i++) { |
| secretKey += chars[array[i] % chars.length] |
| } |
| const keyID = Identifier.create("key") |
|
|
| await Database.use((tx) => |
| tx.insert(KeyTable).values({ |
| id: keyID, |
| workspaceID: Actor.workspace(), |
| userID: input.userID, |
| name, |
| key: secretKey, |
| timeUsed: null, |
| }), |
| ) |
|
|
| return keyID |
| }, |
| ) |
|
|
| export const remove = fn(z.object({ id: z.string() }), async (input) => { |
| |
| await Database.use((tx) => |
| tx |
| .update(KeyTable) |
| .set({ |
| timeDeleted: sql`now()`, |
| }) |
| .where( |
| and( |
| eq(KeyTable.id, input.id), |
| eq(KeyTable.workspaceID, Actor.workspace()), |
| ...(Actor.userRole() === "admin" ? [] : [eq(KeyTable.userID, Actor.userID())]), |
| ), |
| ), |
| ) |
| }) |
| } |
|
|