Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { ContextProvider, RequestData } from "genkit/context";
- import { UserFacingError } from "genkit/beta";
- import * as jwt from "jsonwebtoken";
- import jwksClient from "jwks-rsa";
- // Initialize the JWKS client with caching
- // Replace <PROJECT_ID> with your actual Supabase Project ID or use an env var
- const SUPABASE_PROJECT_ID = process.env.SUPABASE_PROJECT_ID;
- const jwksUri =
- `https://${SUPABASE_PROJECT_ID}.supabase.co/auth/v1/.well-known/jwks.json`;
- const client = jwksClient({
- jwksUri: jwksUri,
- cache: true,
- rateLimit: true,
- jwksRequestsPerMinute: 5,
- });
- // Helper to retrieve the signing key based on the 'kid' in the JWT header
- const getKey: jwt.GetPublicKeyOrSecret = (header, callback) => {
- client.getSigningKey(header.kid, (err, key) => {
- if (err) {
- callback(err);
- } else {
- const signingKey = key?.getPublicKey();
- callback(null, signingKey);
- }
- });
- };
- export const supabaseAuthContextProvider: ContextProvider<any> = async (
- req: RequestData,
- ): Promise<any> => {
- const authHeader = req.headers["authorization"];
- if (!authHeader) {
- throw new UserFacingError("UNAUTHENTICATED", "Missing Header");
- }
- const [scheme, token] = authHeader.split(" ");
- if (scheme.toLowerCase() !== "bearer" || !token) {
- throw new UserFacingError("INVALID_ARGUMENT", "Malformed Header");
- }
- return new Promise((resolve, reject) => {
- jwt.verify(token, getKey, {
- algorithms: ["ES256", "RS256"], // Supabase uses ES256 for ECC
- issuer: `https://${SUPABASE_PROJECT_ID}.supabase.co/auth/v1`,
- }, (err, decoded: any) => {
- if (err) {
- console.error("JWT Verification Error:", err.message);
- return reject(
- new UserFacingError("PERMISSION_DENIED", "Invalid Token"),
- );
- }
- // Supabase JWTs usually have 'authenticated' as the audience (aud)
- if (decoded.aud !== "authenticated") {
- return reject(
- new UserFacingError(
- "PERMISSION_DENIED",
- "Invalid Audience",
- ),
- );
- }
- resolve({
- auth: {
- isAuthenticated: true,
- userId: decoded.sub,
- email: decoded.email,
- },
- });
- });
- });
- };
Advertisement