import { parse } from "cookie" ; import { JWK , JWS } from "node-jose" ; import { createAudVerifier } from "./aud" ; import { createExpVerifier } from "./exp" ; import { decodeJWSPayload } from "./decodeJWSPayload" ; import { createIssVerifier } from "./iss" ; export type JWTPayload = { aud : string | string [ ] ; email : string ; sub : string ; iss : string ; iat : number ; exp : number ; nonce : string ; identity_nonce ? : string ; custom ? : any ; } ; type VerifierOpts = { aud ? : string | string [ ] ; iss ? : string ; tolerance ? : number ; } ; export type Handler = ( ( jws : JWS . VerificationResult ) => Promise < unknown > ) | { complete ( jws ) : Promise < unknown > ; } | undefined ; type Handlers = { handlers : { aud ? : Handler ; iss ? : Handler ; exp : Handler ; } ; } ; const extractJWTFromRequest = ( request ) : string | undefined => { if ( request . headers . has ( "Cookie" ) ) return parse ( request . headers . get ( "Cookie" ) ) . CF_Authorization ; } ; const authenticate = ( verifier ) => async ( request ) : Promise < false | JWTPayload > => { const jwt = extractJWTFromRequest ( request ) ; if ( jwt ) { try { const jws = await verifier . verify ( jwt ) ; return decodeJWSPayload ( jws ) ; } catch ( e ) { } } return false ; } ; const createHandlers = ( opts ) : Handlers => { const aud = createAudVerifier ( opts . aud ) ; const iss = createIssVerifier ( opts . iss ) ; const exp = createExpVerifier ( opts . tolerance ) ; return { handlers : { aud , iss , exp , } , } ; } ; const generateCertsEndpoint = ( authentication_domain ) => `https://${ authentication_domain }/cdn-cgi/access/certs` ; const generateIss = ( authentication_domain ) => `https://${ authentication_domain }` ; export const createAuthenticator = async ( authentication_domain , opts = { } ) => { const response = await fetch ( generateCertsEndpoint ( authentication_domain ) ) ; const keys = await response . json ( ) ; const keystore = await JWK . asKeyStore ( keys ) ; opts . iss = opts . iss || generateIss ( authentication_domain ) ; const handlers = createHandlers ( opts ) ; const verifier = JWS . createVerify ( keystore , handlers ) ; return authenticate ( verifier ) ; } ;