Repository: cloudflare/wildebeest
File: backend/src/access/index.ts (TypeScript)

Code before:
		}
		const jwk = keys.find((key) => key.kid === kid)
		if (!jwk) {
			throw new Error('Could not find matching signing key.')
		}
		if (jwk.kty !== 'RSA' || jwk.alg !== 'RS256') {
			throw new Error('Unknown key type of algorithm.')
		}

		const key = await crypto.subtle.importKey('jwk', jwk, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, [
			'verify',
		])

		const unroundedSecondsSinceEpoch = Date.now() / 1000

		const payloadObj = JSON.parse(textDecoder.decode(base64URLDecode(payload)))

		// For testing disable JWT checks.
		// Ideally we match the production behavior in testing but that
		// requires using local key pair to generate a valid JWT token.
		// For now, let's keep it simple.
		if (!isTesting) {
			if (payloadObj.iss && payloadObj.iss !== certsURL.origin) {
				throw new Error('JWT issuer is incorrect.')
			}
			if (payloadObj.aud && !(payloadObj.aud as string).includes(aud)) {
				throw new Error('JWT audience is incorrect.')
			}
			if (payloadObj.exp && Math.floor(unroundedSecondsSinceEpoch) >= payloadObj.exp) {
				throw new Error('JWT has expired.')
			}
			if (payloadObj.nbf && Math.ceil(unroundedSecondsSinceEpoch) < payloadObj.nbf) {
				throw new Error('JWT is not yet valid.')
			}
		}

		const verified = await crypto.subtle.verify(
			'RSASSA-PKCS1-v1_5',
			key,
			base64URLDecode(signature),
			asciiToUint8Array(`${header}.${payload}`)
		)
		if (!verified) {
			throw new Error('Could not verify JWT.')
		}

		return { payload: payloadObj }
	}

export const getIdentity = async ({ jwt, domain }: { jwt: string; domain: string }): Promise<undefined | Identity> => {
	const identityURL = new URL('/cdn-cgi/access/get-identity', 'https://' + domain)

Review comment (suggestion):
Instead of casting here, we should cast the construction of the payloadObj on line 124 above with `as JWTPayload`.

(Or even better reuse, somehow, the `getPayload()` function rather than re-parsing it here.)

Code after:
		}
		const jwk = keys.find((key) => key.kid === kid)
		if (!jwk) {
			throw new Error('Could not find matching signing key.')
		}
		if (jwk.kty !== 'RSA' || jwk.alg !== 'RS256') {
			throw new Error('Unknown key type of algorithm.')
		}

		const key = await crypto.subtle.importKey('jwk', jwk, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, [
			'verify',
		])

		const unroundedSecondsSinceEpoch = Date.now() / 1000

		const payloadObj = JSON.parse(textDecoder.decode(base64URLDecode(payload))) as JWTPayload

		// For testing disable JWT checks.
		// Ideally we match the production behavior in testing but that
		// requires using local key pair to generate a valid JWT token.
		// For now, let's keep it simple.
		if (!isTesting) {
			if (payloadObj.iss && payloadObj.iss !== certsURL.origin) {
				throw new Error('JWT issuer is incorrect.')
			}
			if (payloadObj.aud && !payloadObj.aud.includes(aud)) {
				throw new Error('JWT audience is incorrect.')
			}
			if (payloadObj.exp && Math.floor(unroundedSecondsSinceEpoch) >= payloadObj.exp) {
				throw new Error('JWT has expired.')
			}
			if (payloadObj.nbf && Math.ceil(unroundedSecondsSinceEpoch) < payloadObj.nbf) {
				throw new Error('JWT is not yet valid.')
			}
		}

		const verified = await crypto.subtle.verify(
			'RSASSA-PKCS1-v1_5',
			key,
			base64URLDecode(signature),
			asciiToUint8Array(`${header}.${payload}`)
		)
		if (!verified) {
			throw new Error('Could not verify JWT.')
		}

		return { payload: payloadObj }
	}

export const getIdentity = async ({ jwt, domain }: { jwt: string; domain: string }): Promise<undefined | Identity> => {
	const identityURL = new URL('/cdn-cgi/access/get-identity', 'https://' + domain)