diff options
| author | Frank <[email protected]> | 2025-09-18 10:59:01 -0400 |
|---|---|---|
| committer | Frank <[email protected]> | 2025-09-18 10:59:01 -0400 |
| commit | 4ceabdffa07b1af8d99eb73622a4d549d99ec6d2 (patch) | |
| tree | 72e2ae62084a9e24cc76caffbd1f30dafc69ea56 /packages/console/core/src/key.ts | |
| parent | c87480cf931a6f8f8b55552558ef521f1918b578 (diff) | |
| download | opencode-4ceabdffa07b1af8d99eb73622a4d549d99ec6d2.tar.gz opencode-4ceabdffa07b1af8d99eb73622a4d549d99ec6d2.zip | |
wip: zen
Diffstat (limited to 'packages/console/core/src/key.ts')
| -rw-r--r-- | packages/console/core/src/key.ts | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/packages/console/core/src/key.ts b/packages/console/core/src/key.ts new file mode 100644 index 000000000..28643a521 --- /dev/null +++ b/packages/console/core/src/key.ts @@ -0,0 +1,75 @@ +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" + +export namespace Key { + export const list = async () => { + const workspace = Actor.workspace() + const keys = await Database.use((tx) => + tx + .select() + .from(KeyTable) + .where(and(eq(KeyTable.workspaceID, workspace), isNull(KeyTable.timeDeleted))) + .orderBy(sql`${KeyTable.timeCreated} DESC`), + ) + return keys + } + + export const create = fn(z.object({ name: z.string().min(1).max(255) }), async (input) => { + const workspaceID = Actor.workspace() + const { name } = input + + // Generate secret key: sk- + 64 random characters (upper, lower, numbers) + 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: Actor.use(), + name, + key: secretKey, + timeUsed: null, + }), + ).catch((e: any) => { + if (e.message.match(/Duplicate entry '.*' for key 'key.name'/)) + throw new Error("A key with this name already exists. Please choose a different name.") + throw e + }) + + return keyID + }) + + export const remove = fn(z.object({ id: z.string() }), async (input) => { + const workspace = Actor.workspace() + await Database.transaction(async (tx) => { + const row = await tx + .select({ + name: KeyTable.name, + }) + .from(KeyTable) + .where(and(eq(KeyTable.id, input.id), eq(KeyTable.workspaceID, workspace))) + .then((rows) => rows[0]) + if (!row) return + + await tx + .update(KeyTable) + .set({ + timeDeleted: sql`now()`, + oldName: row.name, + name: input.id, // Use the key ID as the name + }) + .where(and(eq(KeyTable.id, input.id), eq(KeyTable.workspaceID, workspace))) + }) + }) +} |
