diff --git a/apps/web/app/oauth/consent/page.tsx b/apps/web/app/oauth/consent/page.tsx index 1b476404..d0e5e284 100644 --- a/apps/web/app/oauth/consent/page.tsx +++ b/apps/web/app/oauth/consent/page.tsx @@ -12,6 +12,32 @@ import { Suspense, useState } from "react" const API_URL = process.env.NEXT_PUBLIC_BACKEND_URL ?? "https://api.supermemory.ai" +// Phase 1 is one coarse grant — every approved client gets all of these. +const DATA_CAPABILITIES = [ + "Read and search your saved memories", + "Add new memories and delete existing ones", + "See your spaces (container tags) and create new ones", +] as const + +function shortClientId(id: string): string { + return id.length > 12 ? `${id.slice(0, 4)}…${id.slice(-4)}` : id +} + +// `offline_access` (refresh token) is intentionally not surfaced — it's bundled, +// not a separate choice, and the MCP exchange hands out a long-lived key anyway. +function accountAccessLabels(scopes: string[]): string[] { + const labels: string[] = [] + const wantsName = scopes.includes("profile") + const wantsEmail = scopes.includes("email") + if (wantsName && wantsEmail) labels.push("See your name and email address") + else if (wantsName) labels.push("See your name and profile info") + else if (wantsEmail) labels.push("See your email address") + for (const s of scopes) + if (!["openid", "profile", "email", "offline_access"].includes(s)) + labels.push(s) + return labels +} + function OAuthConsentContent() { const params = useSearchParams() const { data: session } = useSession() @@ -28,6 +54,7 @@ function OAuthConsentContent() { const canSwitchOrg = (organizations?.length ?? 0) > 1 const clientId = params.get("client_id") ?? "" const scopes = (params.get("scope") ?? "").split(/\s+/).filter(Boolean) + const accountAccess = accountAccessLabels(scopes) // A valid consent page is reached only via /oauth2/authorize, which appends a // signed (`sig`) + short-lived (`exp`) query. Without that it can't succeed. const expSeconds = Number(params.get("exp")) @@ -219,34 +246,40 @@ function OAuthConsentContent() { Authorize access

- An application is requesting access to your Supermemory account. + An application wants to connect to your Supermemory account.

- {clientId && ( -

- Client ID:{" "} - {clientId} +

+

+ It will be able to

- )} - - {scopes.length > 0 && ( -
-

- Requested permissions -

- -
- )} + + {accountAccess.length > 0 && ( + <> +
+ + + )} +
{error &&

{error}

} @@ -288,6 +321,12 @@ function OAuthConsentContent() {
+ + {clientId && ( +

+ App ID · {shortClientId(clientId)} +

+ )}