Profiles·Public

simple-oauth2

semver>=4.0.0 <6.0.0postconditions9functions4last verified2026-04-17coverage score100%

Postconditions — what we check

  • getToken · network-error
    error
    WhenNetwork error, connection timeout, or DNS resolution failure when contacting the OAuth2 server
    ThrowsError with network error details (no response body)
    Required handlingCaller MUST wrap getToken() in try-catch to handle network failures. Network errors have no response body; check error.message for details. Implement retry with exponential backoff for transient network failures.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • getToken · invalid-credentials
    error
    WhenOAuth2 server returns 401 Unauthorized (invalid client_id, client_secret, or credentials)
    ThrowsError with response body containing OAuth2 error description
    Required handlingCaller MUST catch this error and handle configuration failures. DO NOT retry invalid credentials automatically — this indicates a configuration error. Error object includes response.status and OAuth2 error details in the message.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • getToken · server-error
    error
    WhenOAuth2 server returns 4xx or 5xx status code
    ThrowsError with HTTP status and response body
    Required handlingCaller MUST catch and inspect the error. For 5xx errors, implement retry logic. For 4xx client errors, log and surface to operations — retrying without fixing the configuration will not resolve the issue.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • refresh · refresh-token-expired-or-invalid
    error
    WhenThe refresh token has expired, been revoked, or is invalid
    ThrowsError with OAuth2 error response (typically 400 Bad Request with invalid_grant)
    Required handlingCaller MUST catch refresh errors and handle re-authentication. When refresh fails with invalid_grant, the user MUST re-authenticate from scratch. DO NOT retry refresh token errors — the token is invalid and a new authorization flow is required.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • refresh · network-error
    error
    WhenNetwork error when contacting the OAuth2 server during refresh
    ThrowsError with network error details
    Required handlingCaller MUST wrap refresh() in try-catch and implement retry logic for network failures. Distinguish between network errors (retry safe) and OAuth2 errors (not retry safe).
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • revoke · revoke-network-error
    error
    WhenNetwork error when contacting the OAuth2 server during revocation
    ThrowsError with network error details
    Required handlingCaller MUST wrap revoke() in try-catch. Network errors during revocation do not guarantee whether the token was revoked or not. Log the error and treat the token as potentially still valid.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • revoke · revoke-server-error
    error
    WhenOAuth2 server returns error during revocation
    ThrowsError with HTTP status and OAuth2 error response
    Required handlingCaller MUST catch errors from revoke() and handle revocation failures gracefully. If revocation fails, do not assume the token is invalid on the server side.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • revokeAll · revokeall-partial-failure
    error
    WhenrevokeAll() is called and the first internal revoke call (for the access_token) throws a network error, timeout, or HTTP error from the OAuth2 server. The second revoke call (for the refresh_token) is never executed because revokeAll() uses sequential await without try-catch between the two calls. As a result: - If access_token revoke fails: BOTH tokens may still be valid on the server - If access_token revoke succeeds but is not confirmed: the refresh_token is still valid and can be used to obtain new access tokens This creates a security-critical partial logout state — the user appears logged out on the client but their refresh token can still mint new access tokens.
    ThrowsBoom.Boom error (isBoom: true) with one of: - output.statusCode 502 (Boom.badGateway): network error (ECONNREFUSED, DNS failure) - output.statusCode 504 (Boom.gatewayTimeout): request timeout - output.statusCode matching HTTP status: OAuth2 server returned 4xx/5xx All Boom errors have .isBoom === true, .message with details, and .output.statusCode with the effective HTTP status code.
    Required handlingNEVER use revokeAll() for security-sensitive logout flows without error handling. Wrap revokeAll() in try-catch AND consider calling revoke() twice separately to handle partial failures: // Preferred: handle each revocation independently try { await accessToken.revoke('access_token'); } catch (err) { console.error('access_token revocation failed:', err.message); // Decide: continue to refresh_token revoke? Or abort? } try { await accessToken.revoke('refresh_token'); } catch (err) { console.error('refresh_token revocation failed:', err.message); } If using revokeAll(), always catch and treat the session as potentially still valid — force re-authentication on the next request: try { await accessToken.revokeAll(); } catch (err) { // CRITICAL: refresh token may still be valid. // Mark the session as potentially compromised and // require re-authentication. logger.error('Token revocation incomplete:', err.message); throw new Error('Logout incomplete — please re-authenticate'); }
    costhighin prodsilent failureusers seesecurity breachvisibilitysilent
    Sources[1][3][4]
  • revokeAll · revokeall-network-error
    error
    WhenNetwork error or timeout occurs when revokeAll() attempts the first HTTP request to the OAuth2 token revocation endpoint. The OAuth2 server is unreachable due to DNS failure, connection refused, socket timeout, or TLS error. Because revokeAll() does not retry or fallback, a transient network blip prevents any token from being revoked.
    ThrowsBoom.Boom error (isBoom: true): - Boom.badGateway (502): 'Client request error: <ECONNREFUSED|ENOTFOUND|...>' - Boom.gatewayTimeout (504): 'Client request timeout' Check: err.isBoom === true && err.output.statusCode in [502, 504]
    Required handlingCaller MUST wrap revokeAll() in try-catch. For network errors during logout, log the failure and implement a retry mechanism or fallback strategy (e.g., invalidate the session server-side even if the OAuth2 server could not be notified). Do not silently ignore revocation failures. try { await accessToken.revokeAll(); } catch (err) { if (err.isBoom && [502, 504].includes(err.output?.statusCode)) { // Network failure — could not reach revocation endpoint logger.warn('Token revocation network failure, session may persist:', err.message); // Invalidate server-side session anyway for security } throw err; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][4]

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]github.com/lelylan/simple-oauth2https://github.com/lelylan/simple-oauth2/blob/master/API.md
  2. [2]oauth.com/oauth2-servers/making-authenticated-requestshttps://www.oauth.com/oauth2-servers/making-authenticated-requests/refreshing-an-access-token/
  3. [3]github.com/lelylan/simple-oauth2https://github.com/lelylan/simple-oauth2/blob/master/lib/access-token.js
  4. [4]github.com/hapijs/wreckhttps://github.com/hapijs/wreck/blob/master/lib/index.js
Need a different package?
Request a profile