Build the agent-native compute CRM platform
CI / verify (push) Successful in 3m6s

This commit is contained in:
2026-08-13 01:39:01 -07:00
parent bfd2f8d95a
commit 853bde2265
160 changed files with 61812 additions and 483 deletions
+43
View File
@@ -0,0 +1,43 @@
/**
* Authentication-provider boundary.
*
* Providers prove an external identity. They do not decide whether that
* identity belongs to PIG; workspace membership remains a database decision
* in the authenticator and signup route.
*/
import { createRemoteJWKSet, jwtVerify } from 'jose';
import type { Config } from './config';
export interface VerifiedIdentity {
subject: string;
email?: string;
}
export interface AuthProvider {
verifyAccessToken(token: string): Promise<VerifiedIdentity>;
}
export function createSupabaseAuthProvider(supabaseUrl: string): AuthProvider {
const issuer = `${supabaseUrl}/auth/v1`;
// `jose` fetches lazily and caches this set, including safe key rotation.
// Sharing one provider instance avoids a remote lookup path per handler.
const jwks = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`));
return {
async verifyAccessToken(token: string): Promise<VerifiedIdentity> {
const { payload } = await jwtVerify(token, jwks, { issuer });
if (!payload.sub) throw new Error('token has no subject');
return {
subject: payload.sub,
email: typeof payload.email === 'string' ? payload.email : undefined,
};
},
};
}
export function createConfiguredAuthProvider(
config: Pick<Config, 'SUPABASE_URL'>,
): AuthProvider | null {
return config.SUPABASE_URL ? createSupabaseAuthProvider(config.SUPABASE_URL) : null;
}