diff --git a/cloud/function/src/auth.ts b/cloud/function/src/auth.ts index 5eacb7a7..fe31651e 100644 --- a/cloud/function/src/auth.ts +++ b/cloud/function/src/auth.ts @@ -2,7 +2,9 @@ import { Resource } from "sst" import { z } from "zod" import { issuer } from "@openauthjs/openauth" import { createSubjects } from "@openauthjs/openauth/subject" +import { CodeProvider } from "@openauthjs/openauth/provider/code" import { GithubProvider } from "@openauthjs/openauth/provider/github" +import { GoogleOidcProvider } from "@openauthjs/openauth/provider/google" import { CloudflareStorage } from "@openauthjs/openauth/storage/cloudflare" import { Account } from "@opencode/cloud-core/account.js" @@ -30,6 +32,53 @@ export default { clientSecret: Resource.GITHUB_CLIENT_SECRET_CONSOLE.value, scopes: ["read:user", "user:email"], }), + google: GoogleOidcProvider({ + clientID: Resource.GOOGLE_CLIENT_ID.value, + scopes: ["openid", "email"], + }), + // email: CodeProvider({ + // async request(req, state, form, error) { + // console.log(state) + // const params = new URLSearchParams() + // if (error) { + // params.set("error", error.type) + // } + // if (state.type === "start") { + // return Response.redirect(process.env.AUTH_FRONTEND_URL + "/auth/email?" + params.toString(), 302) + // } + // + // if (state.type === "code") { + // return Response.redirect(process.env.AUTH_FRONTEND_URL + "/auth/code?" + params.toString(), 302) + // } + // + // return new Response("ok") + // }, + // async sendCode(claims, code) { + // const email = z.string().email().parse(claims.email) + // const cmd = new SendEmailCommand({ + // Destination: { + // ToAddresses: [email], + // }, + // FromEmailAddress: `SST `, + // Content: { + // Simple: { + // Body: { + // Html: { + // Data: `Your pin code is ${code}`, + // }, + // Text: { + // Data: `Your pin code is ${code}`, + // }, + // }, + // Subject: { + // Data: "SST Console Pin Code: " + code, + // }, + // }, + // }, + // }) + // await ses.send(cmd) + // }, + // }), }, storage: CloudflareStorage({ namespace: env.AuthStorage, @@ -50,7 +99,14 @@ export default { }) const user = (await userResponse.json()) as { email: string } email = user.email - } else throw new Error("Unsupported provider") + } else if (response.provider === "google") { + if (!response.id.email_verified) throw new Error("Google email not verified") + email = response.id.email as string + } + //if (response.provider === "email") { + // email = response.claims.email + //} + else throw new Error("Unsupported provider") if (!email) throw new Error("No email found") diff --git a/cloud/function/sst-env.d.ts b/cloud/function/sst-env.d.ts index 4e2b1592..520a033f 100644 --- a/cloud/function/sst-env.d.ts +++ b/cloud/function/sst-env.d.ts @@ -50,6 +50,10 @@ declare module "sst" { "type": "sst.sst.Secret" "value": string } + "GOOGLE_CLIENT_ID": { + "type": "sst.sst.Secret" + "value": string + } "OPENAI_API_KEY": { "type": "sst.sst.Secret" "value": string diff --git a/cloud/web/src/pages/index.tsx b/cloud/web/src/pages/index.tsx index 903a3afd..116ed156 100644 --- a/cloud/web/src/pages/index.tsx +++ b/cloud/web/src/pages/index.tsx @@ -24,9 +24,12 @@ export default function Index() {
-
+
auth.authorize({ provider: "github" })}>Sign in with GitHub
+
+ auth.authorize({ provider: "google" })}>Sign in with Google +
diff --git a/cloud/web/src/pages/lander.module.css b/cloud/web/src/pages/lander.module.css index b66ed5fa..251e243f 100644 --- a/cloud/web/src/pages/lander.module.css +++ b/cloud/web/src/pages/lander.module.css @@ -80,90 +80,4 @@ border-left: 2px solid var(--color-border); } } - - [data-slot="images"] { - display: flex; - flex-direction: row; - align-items: stretch; - justify-content: space-between; - border-top: 2px solid var(--color-border); - - & > div { - flex: 1; - display: flex; - flex-direction: column; - gap: calc(var(--padding) / 4); - padding: calc(var(--padding) / 2); - border-width: 0; - border-style: solid; - border-color: var(--color-border); - - & > div, a { - flex: 1; - display: flex; - align-items: center; - } - } - - p { - letter-spacing: -0.03125rem; - text-transform: uppercase; - color: var(--color-text-dimmed); - } - - & > div + div { - border-width: 0 0 0 2px; - } - - @media (max-width: 30rem) { - & { - flex-direction: column; - } - & > div + div { - border-width: 2px 0 0 0; - } - } - } - - [data-slot="content"] { - border-top: 2px solid var(--color-border); - padding: var(--padding); - - & > p { - line-height: var(--font-line-height); - } - - ol { - margin-top: calc(var(--vertical-padding) / 2); - padding-left: 2.5rem; - list-style-type: decimal; - line-height: var(--font-line-height); - - & > li + li { - margin-top: calc(var(--vertical-padding) / 2); - } - - & > li b { - text-transform: uppercase; - } - } - - } - - [data-slot="footer"] { - border-top: 2px solid var(--color-border); - display: flex; - flex-direction: row; - - & > div { - flex: 1; - text-align: center; - text-transform: uppercase; - padding: calc(var(--padding) / 2) 0.5rem; - } - - & > div + div { - border-left: 2px solid var(--color-border); - } - } } diff --git a/infra/cloud.ts b/infra/cloud.ts index 4625bb28..1d93d58d 100644 --- a/infra/cloud.ts +++ b/infra/cloud.ts @@ -56,12 +56,13 @@ new sst.x.DevCommand("Studio", { const GITHUB_CLIENT_ID_CONSOLE = new sst.Secret("GITHUB_CLIENT_ID_CONSOLE") const GITHUB_CLIENT_SECRET_CONSOLE = new sst.Secret("GITHUB_CLIENT_SECRET_CONSOLE") +const GOOGLE_CLIENT_ID = new sst.Secret("GOOGLE_CLIENT_ID") const authStorage = new sst.cloudflare.Kv("AuthStorage") export const auth = new sst.cloudflare.Worker("AuthApi", { domain: `auth.${domain}`, handler: "cloud/function/src/auth.ts", url: true, - link: [database, authStorage, GITHUB_CLIENT_ID_CONSOLE, GITHUB_CLIENT_SECRET_CONSOLE], + link: [database, authStorage, GITHUB_CLIENT_ID_CONSOLE, GITHUB_CLIENT_SECRET_CONSOLE, GOOGLE_CLIENT_ID], }) const ANTHROPIC_API_KEY = new sst.Secret("ANTHROPIC_API_KEY") diff --git a/packages/function/sst-env.d.ts b/packages/function/sst-env.d.ts index 4e2b1592..520a033f 100644 --- a/packages/function/sst-env.d.ts +++ b/packages/function/sst-env.d.ts @@ -50,6 +50,10 @@ declare module "sst" { "type": "sst.sst.Secret" "value": string } + "GOOGLE_CLIENT_ID": { + "type": "sst.sst.Secret" + "value": string + } "OPENAI_API_KEY": { "type": "sst.sst.Secret" "value": string diff --git a/sst-env.d.ts b/sst-env.d.ts index ffc049c9..3af3f82c 100644 --- a/sst-env.d.ts +++ b/sst-env.d.ts @@ -63,6 +63,10 @@ declare module "sst" { "type": "sst.sst.Secret" "value": string } + "GOOGLE_CLIENT_ID": { + "type": "sst.sst.Secret" + "value": string + } "GatewayApi": { "type": "sst.cloudflare.Worker" "url": string