mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-08-20 22:14:11 +00:00
feat(auth): AgentID sign-in button on the web login page (#1467)
## What?
Adds a "Continue with AgentID" button to the web app's login page, matching the existing Google/GitHub buttons (same `ExternalAuthButton` pattern, PostHog `login_attempt` capture, last-used badge).
- `packages/lib/auth.ts`: adds the `genericOAuthClient` plugin — generic OAuth providers sign in via `signIn.oauth2({ providerId })`, not `signIn.social`.
- `apps/web/app/(auth)/login/page.tsx`: the button, gated the same way as the other social buttons — always shown on cloud (`NEXT_PUBLIC_HOST_ID === "supermemory"`), opt-in elsewhere via `NEXT_PUBLIC_AGENTID_AUTH_ENABLED` (added to `.env.example`).
## Why?
Companion to supermemoryai/mono#2908, which registers an `agentid` generic OAuth provider (OIDC against auth.agentid.com) on the API so agents can authenticate with their AgentID identity. The consumer app talks to the same better-auth server, so it gets the same sign-in option. mono#2916 additionally auto-invites the agent's verified human owner to the agent's workspace.
Requires mono#2908 to be deployed for the button to work; until then the API rejects the unknown provider and the page shows its normal error state.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches authentication entry points and OAuth client configuration; risk is moderate because it extends login surface area but follows existing social sign-in patterns and is feature-flagged.
>
> **Overview**
> Adds **Continue with AgentID** on the web login page, using the same `ExternalAuthButton` flow as Google/GitHub (PostHog `login_attempt`, last-used badge, loading/error handling).
>
> The button calls **`signIn.oauth2({ providerId: "agentid" })`** instead of `signIn.social`, enabled by registering **`genericOAuthClient`** on the shared better-auth client in `packages/lib/auth.ts`.
>
> Visibility matches other social providers: shown on cloud when `NEXT_PUBLIC_HOST_ID === "supermemory"`, or elsewhere when **`NEXT_PUBLIC_AGENTID_AUTH_ENABLED`** is set (documented in `.env.example`). Depends on the API registering the `agentid` generic OAuth provider.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 90a32786a3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This commit is contained in:
parent
d14b209f7c
commit
5d2b5855fe
3 changed files with 77 additions and 1 deletions
|
|
@ -1,4 +1,5 @@
|
|||
NEXT_PUBLIC_BACKEND_URL=https://api.supermemory.ai
|
||||
NEXT_PUBLIC_POSTHOG_KEY=
|
||||
EXA_API_KEY=
|
||||
XAI_API_KEY=
|
||||
XAI_API_KEY=
|
||||
NEXT_PUBLIC_AGENTID_AUTH_ENABLED=
|
||||
|
|
|
|||
|
|
@ -591,6 +591,79 @@ export default function LoginPage() {
|
|||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{process.env.NEXT_PUBLIC_HOST_ID === "supermemory" ||
|
||||
process.env.NEXT_PUBLIC_AGENTID_AUTH_ENABLED ? (
|
||||
<div className="w-full">
|
||||
<LastUsedBadge show={lastUsedMethod === "agentid"} />
|
||||
<ExternalAuthButton
|
||||
authIcon={
|
||||
<svg
|
||||
className="size-4 sm:size-5 text-foreground"
|
||||
fill="none"
|
||||
height="25"
|
||||
viewBox="0 0 24 25"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<title>AgentID</title>
|
||||
<rect
|
||||
height="11"
|
||||
rx="2.5"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.8"
|
||||
width="14"
|
||||
x="5"
|
||||
y="8.21"
|
||||
/>
|
||||
<path
|
||||
d="M12 8.21V4.71M12 4.71a1.5 1.5 0 1 0-.01-3 1.5 1.5 0 0 0 .01 3Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.8"
|
||||
/>
|
||||
<circle
|
||||
cx="9.25"
|
||||
cy="13.21"
|
||||
fill="currentColor"
|
||||
r="1.25"
|
||||
/>
|
||||
<circle
|
||||
cx="14.75"
|
||||
cy="13.21"
|
||||
fill="currentColor"
|
||||
r="1.25"
|
||||
/>
|
||||
<path
|
||||
d="M9 16.21h6"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="1.8"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
authProvider="AgentID"
|
||||
className="w-full"
|
||||
disabled={Boolean(loadingMessage)}
|
||||
onClick={() => {
|
||||
if (loadingMessage) return
|
||||
setIsLoading(true)
|
||||
posthog.capture("login_attempt", {
|
||||
method: "social",
|
||||
provider: "agentid",
|
||||
})
|
||||
setPendingLoginMethod("agentid")
|
||||
signIn
|
||||
.oauth2({
|
||||
callbackURL: getCallbackURL(),
|
||||
providerId: "agentid",
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
setError(getErrorMessage(err))
|
||||
setIsLoading(false)
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<TextSeparator
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import {
|
|||
anonymousClient,
|
||||
apiKeyClient,
|
||||
emailOTPClient,
|
||||
genericOAuthClient,
|
||||
magicLinkClient,
|
||||
organizationClient,
|
||||
usernameClient,
|
||||
|
|
@ -19,6 +20,7 @@ export const authClient = createAuthClient({
|
|||
usernameClient(),
|
||||
magicLinkClient(),
|
||||
emailOTPClient(),
|
||||
genericOAuthClient(),
|
||||
apiKeyClient(),
|
||||
adminClient(),
|
||||
organizationClient(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue