Skip to content

Commit

Permalink
refactor: userInfoRequest should not reject www-authenticate
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Oct 7, 2024
1 parent e16254f commit e373ec3
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 34 deletions.
8 changes: 3 additions & 5 deletions conformance/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,10 @@ export const flow = (options?: MacroOptions) => {
DPoP,
})
}
let response: Response
let response = await request()
try {
response = await request()
let result = await oauth.processUserInfoResponse(as, client, sub!, response)
t.log('userinfo endpoint response', { ...result })
} catch (err) {
t.log('error', inspect(err, { depth: Infinity }))
if (DPoP && err instanceof oauth.WWWAuthenticateChallengeError) {
Expand All @@ -464,9 +465,6 @@ export const flow = (options?: MacroOptions) => {
throw err
}
}

const result = await oauth.processUserInfoResponse(as, client, sub!, response)
t.log('userinfo endpoint response', { ...result })
}

if (accounts_endpoint) {
Expand Down
70 changes: 41 additions & 29 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2618,23 +2618,7 @@ export interface ProtectedResourceRequestOptions
[clockSkew]?: number
}

/**
* Performs a protected resource request at an arbitrary URL.
*
* Authorization Header is used to transmit the Access Token value.
*
* @param accessToken The Access Token for the request.
* @param method The HTTP method for the request.
* @param url Target URL for the request.
* @param headers Headers for the request.
* @param body Request body compatible with the Fetch API and the request's method.
*
* @group Accessing Protected Resources
*
* @see [RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750.html#section-2.1)
* @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-protected-resource-access)
*/
export async function protectedResourceRequest(
async function resourceRequest(
accessToken: string,
method: string,
url: URL,
Expand Down Expand Up @@ -2672,18 +2656,46 @@ export async function protectedResourceRequest(
method,
redirect: 'manual',
signal: options?.signal ? signal(options.signal) : null,
}).then(processDpopNonce)
}

/**
* Performs a protected resource request at an arbitrary URL.
*
* Authorization Header is used to transmit the Access Token value.
*
* @param accessToken The Access Token for the request.
* @param method The HTTP method for the request.
* @param url Target URL for the request.
* @param headers Headers for the request.
* @param body Request body compatible with the Fetch API and the request's method.
*
* @returns Resolves with a {@link !Response} instance. WWW-Authenticate HTTP Header challenges are
* rejected with {@link WWWAuthenticateChallengeError}.
*
* @group Accessing Protected Resources
*
* @see [RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750.html#section-2.1)
* @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-protected-resource-access)
*/
export async function protectedResourceRequest(
accessToken: string,
method: string,
url: URL,
headers?: Headers,
body?: ProtectedResourceRequestBody,
options?: ProtectedResourceRequestOptions,
): Promise<Response> {
return resourceRequest(accessToken, method, url, headers, body, options).then((response) => {
let challenges: WWWAuthenticateChallenge[] | undefined
if ((challenges = parseWwwAuthenticateChallenges(response))) {
throw new WWWAuthenticateChallengeError(
'server responded with a challenge in the WWW-Authenticate HTTP Header',
{ cause: challenges, response },
)
}
return response
})
.then(processDpopNonce)
.then((response) => {
let challenges: WWWAuthenticateChallenge[] | undefined
if ((challenges = parseWwwAuthenticateChallenges(response))) {
throw new WWWAuthenticateChallengeError(
'server responded with a challenge in the WWW-Authenticate HTTP Header',
{ cause: challenges, response },
)
}
return response
})
}

export interface UserInfoRequestOptions extends HttpRequestOptions<'GET'>, DPoPRequestOptions {}
Expand Down Expand Up @@ -2728,7 +2740,7 @@ export async function userInfoRequest(
headers.append('accept', 'application/jwt')
}

return protectedResourceRequest(accessToken, 'GET', url, headers, null, {
return resourceRequest(accessToken, 'GET', url, headers, null, {
...options,
[clockSkew]: getClockSkew(client),
} as ProtectedResourceRequestOptions)
Expand Down

0 comments on commit e373ec3

Please sign in to comment.