Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/GoTrueClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2968,7 +2968,7 @@ export default class GoTrueClient {
})
}

private async fetchJwk(kid: string, jwks: { keys: JWK[] } = { keys: [] }): Promise<JWK> {
private async fetchJwk(kid: string, jwks: { keys: JWK[] } = { keys: [] }): Promise<JWK | null> {
// try fetching from the supplied jwks
let jwk = jwks.keys.find((key) => key.kid === kid)
if (jwk) {
Expand All @@ -2992,7 +2992,7 @@ export default class GoTrueClient {
throw error
}
if (!data.keys || data.keys.length === 0) {
throw new AuthInvalidJwtError('JWKS is empty')
return null
}

this.jwks = data
Expand All @@ -3001,7 +3001,7 @@ export default class GoTrueClient {
// Find the signing key
jwk = data.keys.find((key: any) => key.kid === kid)
if (!jwk) {
throw new AuthInvalidJwtError('No matching signing key found in JWKS')
return null
}
return jwk
}
Expand Down Expand Up @@ -3066,12 +3066,16 @@ export default class GoTrueClient {
validateExp(payload.exp)
}

// If symmetric algorithm or WebCrypto API is unavailable, fallback to getUser()
if (
const signingKey =
!header.alg ||
header.alg.startsWith('HS') ||
!header.kid ||
header.alg === 'HS256' ||
!('crypto' in globalThis && 'subtle' in globalThis.crypto)
) {
? null
: await this.fetchJwk(header.kid, options?.keys ? { keys: options.keys } : options?.jwks)

// If symmetric algorithm or WebCrypto API is unavailable, fallback to getUser()
if (!signingKey) {
const { error } = await this.getUser(token)
if (error) {
throw error
Expand All @@ -3088,10 +3092,6 @@ export default class GoTrueClient {
}

const algorithm = getAlgorithm(header.alg)
const signingKey = await this.fetchJwk(
header.kid,
options?.keys ? { keys: options.keys } : options?.jwks
)

// Convert JWK to CryptoKey
const publicKey = await crypto.subtle.importKey('jwk', signingKey, algorithm, true, [
Expand Down
4 changes: 3 additions & 1 deletion src/lib/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,9 @@ export function validateExp(exp: number) {
}
}

export function getAlgorithm(alg: 'RS256' | 'ES256'): RsaHashedImportParams | EcKeyImportParams {
export function getAlgorithm(
alg: 'HS256' | 'RS256' | 'ES256'
): RsaHashedImportParams | EcKeyImportParams {
switch (alg) {
case 'RS256':
return {
Expand Down
Loading