@@ -24,10 +24,12 @@ import type { APIContext } from 'astro';
2424
2525import { authAsyncStorage } from '#async-local-storage' ;
2626
27+ import { canUseKeyless } from '../utils/feature-flags' ;
2728import { buildClerkHotloadScript } from './build-clerk-hotload-script' ;
2829import { clerkClient } from './clerk-client' ;
2930import { createCurrentUser } from './current-user' ;
3031import { getClientSafeEnv , getSafeEnv } from './get-safe-env' ;
32+ import { resolveKeysWithKeylessFallback } from './keyless/utils' ;
3133import { serverRedirectWithAuth } from './server-redirect-with-auth' ;
3234import type {
3335 AstroMiddleware ,
@@ -49,7 +51,7 @@ type ClerkAstroMiddlewareHandler = (
4951 next : AstroMiddlewareNextParam ,
5052) => AstroMiddlewareReturn | undefined ;
5153
52- type ClerkAstroMiddlewareOptions = AuthenticateRequestOptions ;
54+ export type ClerkAstroMiddlewareOptions = AuthenticateRequestOptions ;
5355
5456/**
5557 * Middleware for Astro that handles authentication and authorization with Clerk.
@@ -79,9 +81,42 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {
7981
8082 const clerkRequest = createClerkRequest ( context . request ) ;
8183
84+ // Resolve keyless URLs per-request in development
85+ let keylessClaimUrl : string | undefined ;
86+ let keylessApiKeysUrl : string | undefined ;
87+ let keylessOptions = options ;
88+
89+ if ( canUseKeyless ) {
90+ try {
91+ const env = getSafeEnv ( context ) ;
92+ const configuredPublishableKey = options ?. publishableKey || env . pk ;
93+ const configuredSecretKey = options ?. secretKey || env . sk ;
94+
95+ const keylessResult = await resolveKeysWithKeylessFallback (
96+ configuredPublishableKey ,
97+ configuredSecretKey ,
98+ context ,
99+ ) ;
100+
101+ keylessClaimUrl = keylessResult . claimUrl ;
102+ keylessApiKeysUrl = keylessResult . apiKeysUrl ;
103+
104+ // Override keys with keyless values if returned
105+ if ( keylessResult . publishableKey || keylessResult . secretKey ) {
106+ keylessOptions = {
107+ ...options ,
108+ ...( keylessResult . publishableKey && { publishableKey : keylessResult . publishableKey } ) ,
109+ ...( keylessResult . secretKey && { secretKey : keylessResult . secretKey } ) ,
110+ } ;
111+ }
112+ } catch {
113+ // Silently fail - continue without keyless
114+ }
115+ }
116+
82117 const requestState = await clerkClient ( context ) . authenticateRequest (
83118 clerkRequest ,
84- createAuthenticateRequestOptions ( clerkRequest , options , context ) ,
119+ createAuthenticateRequestOptions ( clerkRequest , keylessOptions , context ) ,
85120 ) ;
86121
87122 const locationHeader = requestState . headers . get ( constants . Headers . Location ) ;
@@ -104,6 +139,16 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {
104139
105140 decorateAstroLocal ( clerkRequest , authObjectFn , context , requestState ) ;
106141
142+ // Store keyless data for injection into client
143+ if ( keylessClaimUrl || keylessApiKeysUrl ) {
144+ context . locals . keylessClaimUrl = keylessClaimUrl ;
145+ context . locals . keylessApiKeysUrl = keylessApiKeysUrl ;
146+ // Also store the resolved publishable key so client can use it
147+ if ( keylessOptions ?. publishableKey ) {
148+ context . locals . keylessPublishableKey = keylessOptions . publishableKey ;
149+ }
150+ }
151+
107152 /**
108153 * ALS is crucial for guaranteeing SSR in UI frameworks like React.
109154 * This currently powers the `useAuth()` React hook and any other hook or Component that depends on it.
0 commit comments