From 183e0911b76025a1f2a82e979d9834fec2131d0e Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 8 Aug 2025 13:22:54 -0400 Subject: wip: gateway --- cloud/function/src/auth.ts | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 cloud/function/src/auth.ts (limited to 'cloud/function/src/auth.ts') diff --git a/cloud/function/src/auth.ts b/cloud/function/src/auth.ts new file mode 100644 index 000000000..5eacb7a72 --- /dev/null +++ b/cloud/function/src/auth.ts @@ -0,0 +1,68 @@ +import { Resource } from "sst" +import { z } from "zod" +import { issuer } from "@openauthjs/openauth" +import { createSubjects } from "@openauthjs/openauth/subject" +import { GithubProvider } from "@openauthjs/openauth/provider/github" +import { CloudflareStorage } from "@openauthjs/openauth/storage/cloudflare" +import { Account } from "@opencode/cloud-core/account.js" + +type Env = { + AuthStorage: KVNamespace +} + +export const subjects = createSubjects({ + account: z.object({ + accountID: z.string(), + email: z.string(), + }), + user: z.object({ + userID: z.string(), + workspaceID: z.string(), + }), +}) + +export default { + async fetch(request: Request, env: Env, ctx: ExecutionContext) { + return issuer({ + providers: { + github: GithubProvider({ + clientID: Resource.GITHUB_CLIENT_ID_CONSOLE.value, + clientSecret: Resource.GITHUB_CLIENT_SECRET_CONSOLE.value, + scopes: ["read:user", "user:email"], + }), + }, + storage: CloudflareStorage({ + namespace: env.AuthStorage, + }), + subjects, + async success(ctx, response) { + console.log(response) + + let email: string | undefined + + if (response.provider === "github") { + const userResponse = await fetch("https://api.github.com/user", { + headers: { + Authorization: `Bearer ${response.tokenset.access}`, + "User-Agent": "opencode", + Accept: "application/vnd.github+json", + }, + }) + const user = (await userResponse.json()) as { email: string } + email = user.email + } else throw new Error("Unsupported provider") + + if (!email) throw new Error("No email found") + + let accountID = await Account.fromEmail(email).then((x) => x?.id) + if (!accountID) { + console.log("creating account for", email) + accountID = await Account.create({ + email: email!, + }) + } + return ctx.subject("account", accountID, { accountID, email }) + }, + }).fetch(request, env, ctx) + }, +} -- cgit v1.2.3