11import { type NextRequest , NextResponse } from "next/server" ;
22import { db } from "@onecli/db" ;
33import { getServerSession } from "@/lib/auth/server" ;
4+ import { verifyAndResolveIdentity } from "@/lib/validate-jwt" ;
45import { logger } from "@/lib/logger" ;
56import { DEFAULT_AGENT_NAME } from "@/lib/constants" ;
67import { seedDemoSecret } from "@/lib/services/secret-service" ;
@@ -12,37 +13,57 @@ import { getSessionAttributes, onUserCreated } from "@/lib/auth/session-hooks";
1213 * GET /api/auth/sync
1314 *
1415 * Single endpoint that handles the full auth → DB sync flow:
15- * 1. Reads the auth session (cookie/token)
16+ * 1. Reads the auth session (cookie/token) or validates a JWT Bearer token
1617 * 2. Upserts the user in the database
1718 * 3. Ensures the user has an Account + AccountMember + ApiKey
1819 * 4. Seeds defaults (agent, demo secret) into the account
1920 * 5. Returns the user profile
2021 *
21- * Called by the login page after auth and by the dashboard layout on mount.
22- * Returns 401 if no valid session exists.
22+ * Called by the login page after auth, by the dashboard layout on mount,
23+ * or by API clients with a JWT access token to provision their account.
24+ * Returns 401 if no valid session or token exists.
2325 */
2426export const GET = async ( request : NextRequest ) => {
2527 try {
28+ // Try session auth first, then JWT Bearer token
2629 const session = await getServerSession ( ) ;
27- if ( ! session || ! session . email ) {
28- return NextResponse . json ( { error : "Not authenticated" } , { status : 401 } ) ;
30+
31+ let authId : string ;
32+ let email : string ;
33+ let name : string | null | undefined ;
34+
35+ if ( session ?. email ) {
36+ authId = session . id ;
37+ email = session . email ;
38+ name = session . name ;
39+ } else {
40+ const identity = await verifyAndResolveIdentity ( request ) ;
41+ if ( ! identity ) {
42+ return NextResponse . json (
43+ { error : "Not authenticated" } ,
44+ { status : 401 } ,
45+ ) ;
46+ }
47+ authId = identity . sub ;
48+ email = identity . email ;
49+ name = identity . name ;
2950 }
3051
3152 const extra = getSessionAttributes ( request ) ;
3253
3354 // Upsert user by email — creates on first login, updates on subsequent.
3455 const user = await db . user . upsert ( {
35- where : { email : session . email } ,
56+ where : { email } ,
3657 create : {
37- externalAuthId : session . id ,
38- email : session . email ,
39- name : session . name ,
58+ externalAuthId : authId ,
59+ email,
60+ name : name ?? null ,
4061 lastLoginAt : new Date ( ) ,
4162 ...extra ,
4263 } ,
4364 update : {
44- externalAuthId : session . id ,
45- name : session . name ,
65+ externalAuthId : authId ,
66+ name : name ?? null ,
4667 lastLoginAt : new Date ( ) ,
4768 ...extra ,
4869 } ,
0 commit comments