summaryrefslogtreecommitdiffhomepage
path: root/cloud/core/src/key.ts
diff options
context:
space:
mode:
authorFrank <[email protected]>2025-08-28 16:44:55 -0400
committerFrank <[email protected]>2025-08-28 16:44:55 -0400
commitc6ef92634d0ae026a59e023e69847b481975462b (patch)
treec88bfbbabf1f46ca922e3212dd929b34d6229a1a /cloud/core/src/key.ts
parentf97fdceb01c69ca563e755c6d50312ef7352f663 (diff)
downloadopencode-c6ef92634d0ae026a59e023e69847b481975462b.tar.gz
opencode-c6ef92634d0ae026a59e023e69847b481975462b.zip
wip cloud
Diffstat (limited to 'cloud/core/src/key.ts')
-rw-r--r--cloud/core/src/key.ts79
1 files changed, 79 insertions, 0 deletions
diff --git a/cloud/core/src/key.ts b/cloud/core/src/key.ts
new file mode 100644
index 000000000..cf4f6e410
--- /dev/null
+++ b/cloud/core/src/key.ts
@@ -0,0 +1,79 @@
+import { z } from "zod"
+import { fn } from "./util/fn"
+import { Actor } from "./actor"
+import { and, Database, eq, sql } from "./drizzle"
+import { Identifier } from "./identifier"
+import { KeyTable } from "./schema/key.sql"
+
+export namespace Key {
+ export const list = async () => {
+ const user = Actor.assert("user")
+ const keys = await Database.use((tx) =>
+ tx
+ .select({
+ id: KeyTable.id,
+ name: KeyTable.name,
+ key: KeyTable.key,
+ userID: KeyTable.userID,
+ timeCreated: KeyTable.timeCreated,
+ timeUsed: KeyTable.timeUsed,
+ })
+ .from(KeyTable)
+ .where(eq(KeyTable.workspaceID, user.properties.workspaceID))
+ .orderBy(sql`${KeyTable.timeCreated} DESC`),
+ )
+ return keys
+ }
+
+ export const create = fn(z.object({ name: z.string().min(1).max(255) }), async (input) => {
+ const user = Actor.assert("user")
+ const { name } = input
+
+ // Generate secret key: sk- + 64 random characters (upper, lower, numbers)
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ let randomPart = ""
+ for (let i = 0; i < 64; i++) {
+ randomPart += chars.charAt(Math.floor(Math.random() * chars.length))
+ }
+ const secretKey = `sk-${randomPart}`
+
+ const keyRecord = await Database.use((tx) =>
+ tx
+ .insert(KeyTable)
+ .values({
+ id: Identifier.create("key"),
+ workspaceID: user.properties.workspaceID,
+ userID: user.properties.userID,
+ name,
+ key: secretKey,
+ timeUsed: null,
+ })
+ .returning(),
+ )
+
+ return {
+ key: secretKey,
+ id: keyRecord[0].id,
+ name: keyRecord[0].name,
+ created: keyRecord[0].timeCreated,
+ }
+ })
+
+ export const remove = fn(z.object({ id: z.string() }), async (input) => {
+ const user = Actor.assert("user")
+ const { id } = input
+
+ const result = await Database.use((tx) =>
+ tx
+ .delete(KeyTable)
+ .where(and(eq(KeyTable.id, id), eq(KeyTable.workspaceID, user.properties.workspaceID)))
+ .returning({ id: KeyTable.id }),
+ )
+
+ if (result.length === 0) {
+ throw new Error("Key not found")
+ }
+
+ return { id: result[0].id }
+ })
+}