Skip to content
Open
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
10 changes: 0 additions & 10 deletions libs/accounts/errors/src/app-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
DEFAULT_ERRROR,
IGNORED_ERROR_NUMBERS,
DEBUGGABLE_PAYLOAD_KEYS,
OAUTH_ERRNO,
} from './constants';
import { OauthError } from './oauth-error';
import type { Request as HapiRequest } from 'hapi';
Expand Down Expand Up @@ -1256,15 +1255,6 @@ export class AppError extends Error {
});
}

static oauthNotPublicClient() {
return new AppError({
code: 400,
error: 'Bad Request',
errno: OAUTH_ERRNO.NOT_PUBLIC_CLIENT,
message: 'Not a public client',
});
}

static redisConflict() {
return new AppError({
code: 409,
Expand Down
28 changes: 28 additions & 0 deletions libs/accounts/errors/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,34 @@ export const OAUTH_ERRNO = {
DISABLED_CLIENT_ID: 202,
};

export const OAUTH_ERROR_MESSAGES: Record<keyof typeof OAUTH_ERRNO, string> = {
UNKNOWN_CLIENT: 'Unknown client',
INCORRECT_SECRET: 'Incorrect secret',
INCORRECT_REDIRECT: 'Incorrect redirect_uri',
INVALID_ASSERTION: 'Invalid assertion',
UNKNOWN_CODE: 'Unknown code',
INCORRECT_CODE: 'Incorrect code',
EXPIRED_CODE: 'Expired code',
INVALID_TOKEN: 'Invalid token',
INVALID_PARAMETER: 'Invalid request parameter',
INVALID_RESPONSE_TYPE: 'Invalid response_type',
UNAUTHORIZED: 'Unauthorized for route',
FORBIDDEN: 'Forbidden',
INVALID_CONTENT_TYPE:
'Content-Type must be either application/json or application/x-www-form-urlencoded',
INVALID_SCOPES: 'Requested scopes are not allowed',
EXPIRED_TOKEN: 'Expired token',
NOT_PUBLIC_CLIENT: 'Not a public client',
INCORRECT_CODE_CHALLENGE: 'Incorrect code_challenge',
MISSING_PKCE_PARAMETERS: 'Public clients require PKCE OAuth parameters',
STALE_AUTH_AT: 'Stale authentication timestamp',
MISMATCH_ACR_VALUES: 'Mismatch acr value',
INVALID_GRANT_TYPE: 'Invalid grant_type',
UNKNOWN_TOKEN: 'Unknown token',
SERVER_UNAVAILABLE: 'System unavailable, try again soon',
DISABLED_CLIENT_ID: 'This client has been temporarily disabled',
};

/**
* Takes an object and swaps keys with values. Useful when a value -> key look up is needed.
* @param obj - Object to swap keys and values on
Expand Down
96 changes: 47 additions & 49 deletions libs/accounts/errors/src/oauth-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { DEFAULT_ERRROR } from './constants';
import { DEFAULT_ERRROR, OAUTH_ERRNO, OAUTH_ERROR_MESSAGES } from './constants';

const hex = (v: Buffer | string): string =>
Buffer.isBuffer(v) ? v.toString('hex') : v;
Expand Down Expand Up @@ -141,8 +141,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 101,
message: 'Unknown client',
errno: OAUTH_ERRNO.UNKNOWN_CLIENT,
message: OAUTH_ERROR_MESSAGES.UNKNOWN_CLIENT,
},
{
clientId: hex(clientId),
Expand All @@ -155,8 +155,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 102,
message: 'Incorrect secret',
errno: OAUTH_ERRNO.INCORRECT_SECRET,
message: OAUTH_ERROR_MESSAGES.INCORRECT_SECRET,
},
{
clientId: hex(clientId),
Expand All @@ -169,8 +169,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 103,
message: 'Incorrect redirect_uri',
errno: OAUTH_ERRNO.INCORRECT_REDIRECT,
message: OAUTH_ERROR_MESSAGES.INCORRECT_REDIRECT,
},
{
redirectUri: uri,
Expand All @@ -182,8 +182,8 @@ export class OauthError extends Error {
return new OauthError({
code: 401,
error: 'Bad Request',
errno: 104,
message: 'Invalid assertion',
errno: OAUTH_ERRNO.INVALID_ASSERTION,
message: OAUTH_ERROR_MESSAGES.INVALID_ASSERTION,
});
}

Expand All @@ -192,8 +192,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 105,
message: 'Unknown code',
errno: OAUTH_ERRNO.UNKNOWN_CODE,
message: OAUTH_ERROR_MESSAGES.UNKNOWN_CODE,
},
{
requestCode: code,
Expand All @@ -206,8 +206,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 106,
message: 'Incorrect code',
errno: OAUTH_ERRNO.INCORRECT_CODE,
message: OAUTH_ERROR_MESSAGES.INCORRECT_CODE,
},
{
requestCode: hex(code),
Expand All @@ -221,8 +221,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 107,
message: 'Expired code',
errno: OAUTH_ERRNO.EXPIRED_CODE,
message: OAUTH_ERROR_MESSAGES.EXPIRED_CODE,
},
{
requestCode: hex(code),
Expand All @@ -235,8 +235,8 @@ export class OauthError extends Error {
return new OauthError({
code: 400,
error: 'Bad Request',
errno: 108,
message: 'Invalid token',
errno: OAUTH_ERRNO.INVALID_TOKEN,
message: OAUTH_ERROR_MESSAGES.INVALID_TOKEN,
});
}

Expand All @@ -245,8 +245,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 109,
message: 'Invalid request parameter',
errno: OAUTH_ERRNO.INVALID_PARAMETER,
message: OAUTH_ERROR_MESSAGES.INVALID_PARAMETER,
},
{
validation: val,
Expand All @@ -258,8 +258,8 @@ export class OauthError extends Error {
return new OauthError({
code: 400,
error: 'Bad Request',
errno: 110,
message: 'Invalid response_type',
errno: OAUTH_ERRNO.INVALID_RESPONSE_TYPE,
message: OAUTH_ERROR_MESSAGES.INVALID_RESPONSE_TYPE,
});
}

Expand All @@ -268,8 +268,8 @@ export class OauthError extends Error {
{
code: 401,
error: 'Unauthorized',
errno: 111,
message: 'Unauthorized for route',
errno: OAUTH_ERRNO.UNAUTHORIZED,
message: OAUTH_ERROR_MESSAGES.UNAUTHORIZED,
},
{
detail: reason,
Expand All @@ -281,19 +281,17 @@ export class OauthError extends Error {
return new OauthError({
code: 403,
error: 'Forbidden',
errno: 112,
message: 'Forbidden',
errno: OAUTH_ERRNO.FORBIDDEN,
message: OAUTH_ERROR_MESSAGES.FORBIDDEN,
});
}

static invalidContentType() {
return new OauthError({
code: 415,
error: 'Unsupported Media Type',
errno: 113,
message:
'Content-Type must be either application/json or ' +
'application/x-www-form-urlencoded',
errno: OAUTH_ERRNO.INVALID_CONTENT_TYPE,
message: OAUTH_ERROR_MESSAGES.INVALID_CONTENT_TYPE,
});
}

Expand All @@ -302,8 +300,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Invalid scopes',
errno: 114,
message: 'Requested scopes are not allowed',
errno: OAUTH_ERRNO.INVALID_SCOPES,
message: OAUTH_ERROR_MESSAGES.INVALID_SCOPES,
},
{
invalidScopes: scopes,
Expand All @@ -316,8 +314,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 115,
message: 'Expired token',
errno: OAUTH_ERRNO.EXPIRED_TOKEN,
message: OAUTH_ERROR_MESSAGES.EXPIRED_TOKEN,
},
{
expiredAt: expiredAt,
Expand All @@ -330,8 +328,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 116,
message: 'Not a public client',
errno: OAUTH_ERRNO.NOT_PUBLIC_CLIENT,
message: OAUTH_ERROR_MESSAGES.NOT_PUBLIC_CLIENT,
},
{
clientId: hex(clientId),
Expand All @@ -344,8 +342,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 117,
message: 'Incorrect code_challenge',
errno: OAUTH_ERRNO.INCORRECT_CODE_CHALLENGE,
message: OAUTH_ERROR_MESSAGES.INCORRECT_CODE_CHALLENGE,
},
{
requestCodeChallenge: pkceHashValue,
Expand All @@ -357,8 +355,8 @@ export class OauthError extends Error {
return new OauthError({
code: 400,
error: 'PKCE parameters missing',
errno: 118,
message: 'Public clients require PKCE OAuth parameters',
errno: OAUTH_ERRNO.MISSING_PKCE_PARAMETERS,
message: OAUTH_ERROR_MESSAGES.MISSING_PKCE_PARAMETERS,
});
}

Expand All @@ -367,8 +365,8 @@ export class OauthError extends Error {
{
code: 401,
error: 'Bad Request',
errno: 119,
message: 'Stale authentication timestamp',
errno: OAUTH_ERRNO.STALE_AUTH_AT,
message: OAUTH_ERROR_MESSAGES.STALE_AUTH_AT,
},
{
authAt: authAt,
Expand All @@ -381,8 +379,8 @@ export class OauthError extends Error {
{
code: 400,
error: 'Bad Request',
errno: 120,
message: 'Mismatch acr value',
errno: OAUTH_ERRNO.MISMATCH_ACR_VALUES,
message: OAUTH_ERROR_MESSAGES.MISMATCH_ACR_VALUES,
},
{ foundValue }
);
Expand All @@ -392,17 +390,17 @@ export class OauthError extends Error {
return new OauthError({
code: 400,
error: 'Bad Request',
errno: 121,
message: 'Invalid grant_type',
errno: OAUTH_ERRNO.INVALID_GRANT_TYPE,
message: OAUTH_ERROR_MESSAGES.INVALID_GRANT_TYPE,
});
}

static unknownToken() {
return new OauthError({
code: 400,
error: 'Bad Request',
errno: 122,
message: 'Unknown token',
errno: OAUTH_ERRNO.UNKNOWN_TOKEN,
message: OAUTH_ERROR_MESSAGES.UNKNOWN_TOKEN,
});
}

Expand All @@ -414,8 +412,8 @@ export class OauthError extends Error {
{
code: 503,
error: 'Client Disabled',
errno: 202, // TODO reconcile this with the auth-server version
message: 'This client has been temporarily disabled',
errno: OAUTH_ERRNO.DISABLED_CLIENT_ID,
message: OAUTH_ERROR_MESSAGES.DISABLED_CLIENT_ID,
},
{ clientId }
);
Expand Down
4 changes: 2 additions & 2 deletions packages/fxa-auth-server/lib/routes/oauth/introspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/*jshint camelcase: false*/
const Joi = require('joi');
const validators = require('../../oauth/validators');
const { AppError } = require('@fxa/accounts/errors');
const { OauthError } = require('@fxa/accounts/errors');
const { getTokenId } = require('../../oauth/token');
const OAUTH_SERVER_DOCS =
require('../../../docs/swagger/oauth-server-api').default;
Expand Down Expand Up @@ -79,7 +79,7 @@ module.exports = ({ oauthDB }) => ({
// in the future other clients should be able to use it
// by providing client_secret in the Authentication header
if (!client || !client.publicClient) {
throw AppError.oauthNotPublicClient();
throw OauthError.notPublicClient(token.clientId);
}
}
}
Expand Down
Loading