Skip to content

Commit 3af71b7

Browse files
committed
chore(): additional cleanup for AppError/OauthError code
1 parent 4f18ae8 commit 3af71b7

5 files changed

Lines changed: 115 additions & 144 deletions

File tree

libs/accounts/errors/src/app-error.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
DEFAULT_ERRROR,
1111
IGNORED_ERROR_NUMBERS,
1212
DEBUGGABLE_PAYLOAD_KEYS,
13-
OAUTH_ERRNO,
1413
} from './constants';
1514
import { OauthError } from './oauth-error';
1615
import type { Request as HapiRequest } from 'hapi';
@@ -1256,15 +1255,6 @@ export class AppError extends Error {
12561255
});
12571256
}
12581257

1259-
static oauthNotPublicClient() {
1260-
return new AppError({
1261-
code: 400,
1262-
error: 'Bad Request',
1263-
errno: OAUTH_ERRNO.NOT_PUBLIC_CLIENT,
1264-
message: 'Not a public client',
1265-
});
1266-
}
1267-
12681258
static redisConflict() {
12691259
return new AppError({
12701260
code: 409,

libs/accounts/errors/src/constants.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,34 @@ export const OAUTH_ERRNO = {
160160
DISABLED_CLIENT_ID: 202,
161161
};
162162

163+
export const OAUTH_ERROR_MESSAGES: Record<keyof typeof OAUTH_ERRNO, string> = {
164+
UNKNOWN_CLIENT: 'Unknown client',
165+
INCORRECT_SECRET: 'Incorrect secret',
166+
INCORRECT_REDIRECT: 'Incorrect redirect_uri',
167+
INVALID_ASSERTION: 'Invalid assertion',
168+
UNKNOWN_CODE: 'Unknown code',
169+
INCORRECT_CODE: 'Incorrect code',
170+
EXPIRED_CODE: 'Expired code',
171+
INVALID_TOKEN: 'Invalid token',
172+
INVALID_PARAMETER: 'Invalid request parameter',
173+
INVALID_RESPONSE_TYPE: 'Invalid response_type',
174+
UNAUTHORIZED: 'Unauthorized for route',
175+
FORBIDDEN: 'Forbidden',
176+
INVALID_CONTENT_TYPE:
177+
'Content-Type must be either application/json or application/x-www-form-urlencoded',
178+
INVALID_SCOPES: 'Requested scopes are not allowed',
179+
EXPIRED_TOKEN: 'Expired token',
180+
NOT_PUBLIC_CLIENT: 'Not a public client',
181+
INCORRECT_CODE_CHALLENGE: 'Incorrect code_challenge',
182+
MISSING_PKCE_PARAMETERS: 'Public clients require PKCE OAuth parameters',
183+
STALE_AUTH_AT: 'Stale authentication timestamp',
184+
MISMATCH_ACR_VALUES: 'Mismatch acr value',
185+
INVALID_GRANT_TYPE: 'Invalid grant_type',
186+
UNKNOWN_TOKEN: 'Unknown token',
187+
SERVER_UNAVAILABLE: 'System unavailable, try again soon',
188+
DISABLED_CLIENT_ID: 'This client has been temporarily disabled',
189+
};
190+
163191
/**
164192
* Takes an object and swaps keys with values. Useful when a value -> key look up is needed.
165193
* @param obj - Object to swap keys and values on

libs/accounts/errors/src/oauth-error.ts

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import { DEFAULT_ERRROR } from './constants';
5+
import { DEFAULT_ERRROR, OAUTH_ERRNO, OAUTH_ERROR_MESSAGES } from './constants';
66

77
const hex = (v: Buffer | string): string =>
88
Buffer.isBuffer(v) ? v.toString('hex') : v;
@@ -141,8 +141,8 @@ export class OauthError extends Error {
141141
{
142142
code: 400,
143143
error: 'Bad Request',
144-
errno: 101,
145-
message: 'Unknown client',
144+
errno: OAUTH_ERRNO.UNKNOWN_CLIENT,
145+
message: OAUTH_ERROR_MESSAGES.UNKNOWN_CLIENT,
146146
},
147147
{
148148
clientId: hex(clientId),
@@ -155,8 +155,8 @@ export class OauthError extends Error {
155155
{
156156
code: 400,
157157
error: 'Bad Request',
158-
errno: 102,
159-
message: 'Incorrect secret',
158+
errno: OAUTH_ERRNO.INCORRECT_SECRET,
159+
message: OAUTH_ERROR_MESSAGES.INCORRECT_SECRET,
160160
},
161161
{
162162
clientId: hex(clientId),
@@ -169,8 +169,8 @@ export class OauthError extends Error {
169169
{
170170
code: 400,
171171
error: 'Bad Request',
172-
errno: 103,
173-
message: 'Incorrect redirect_uri',
172+
errno: OAUTH_ERRNO.INCORRECT_REDIRECT,
173+
message: OAUTH_ERROR_MESSAGES.INCORRECT_REDIRECT,
174174
},
175175
{
176176
redirectUri: uri,
@@ -182,8 +182,8 @@ export class OauthError extends Error {
182182
return new OauthError({
183183
code: 401,
184184
error: 'Bad Request',
185-
errno: 104,
186-
message: 'Invalid assertion',
185+
errno: OAUTH_ERRNO.INVALID_ASSERTION,
186+
message: OAUTH_ERROR_MESSAGES.INVALID_ASSERTION,
187187
});
188188
}
189189

@@ -192,8 +192,8 @@ export class OauthError extends Error {
192192
{
193193
code: 400,
194194
error: 'Bad Request',
195-
errno: 105,
196-
message: 'Unknown code',
195+
errno: OAUTH_ERRNO.UNKNOWN_CODE,
196+
message: OAUTH_ERROR_MESSAGES.UNKNOWN_CODE,
197197
},
198198
{
199199
requestCode: code,
@@ -206,8 +206,8 @@ export class OauthError extends Error {
206206
{
207207
code: 400,
208208
error: 'Bad Request',
209-
errno: 106,
210-
message: 'Incorrect code',
209+
errno: OAUTH_ERRNO.INCORRECT_CODE,
210+
message: OAUTH_ERROR_MESSAGES.INCORRECT_CODE,
211211
},
212212
{
213213
requestCode: hex(code),
@@ -221,8 +221,8 @@ export class OauthError extends Error {
221221
{
222222
code: 400,
223223
error: 'Bad Request',
224-
errno: 107,
225-
message: 'Expired code',
224+
errno: OAUTH_ERRNO.EXPIRED_CODE,
225+
message: OAUTH_ERROR_MESSAGES.EXPIRED_CODE,
226226
},
227227
{
228228
requestCode: hex(code),
@@ -235,8 +235,8 @@ export class OauthError extends Error {
235235
return new OauthError({
236236
code: 400,
237237
error: 'Bad Request',
238-
errno: 108,
239-
message: 'Invalid token',
238+
errno: OAUTH_ERRNO.INVALID_TOKEN,
239+
message: OAUTH_ERROR_MESSAGES.INVALID_TOKEN,
240240
});
241241
}
242242

@@ -245,8 +245,8 @@ export class OauthError extends Error {
245245
{
246246
code: 400,
247247
error: 'Bad Request',
248-
errno: 109,
249-
message: 'Invalid request parameter',
248+
errno: OAUTH_ERRNO.INVALID_PARAMETER,
249+
message: OAUTH_ERROR_MESSAGES.INVALID_PARAMETER,
250250
},
251251
{
252252
validation: val,
@@ -258,8 +258,8 @@ export class OauthError extends Error {
258258
return new OauthError({
259259
code: 400,
260260
error: 'Bad Request',
261-
errno: 110,
262-
message: 'Invalid response_type',
261+
errno: OAUTH_ERRNO.INVALID_RESPONSE_TYPE,
262+
message: OAUTH_ERROR_MESSAGES.INVALID_RESPONSE_TYPE,
263263
});
264264
}
265265

@@ -268,8 +268,8 @@ export class OauthError extends Error {
268268
{
269269
code: 401,
270270
error: 'Unauthorized',
271-
errno: 111,
272-
message: 'Unauthorized for route',
271+
errno: OAUTH_ERRNO.UNAUTHORIZED,
272+
message: OAUTH_ERROR_MESSAGES.UNAUTHORIZED,
273273
},
274274
{
275275
detail: reason,
@@ -281,19 +281,17 @@ export class OauthError extends Error {
281281
return new OauthError({
282282
code: 403,
283283
error: 'Forbidden',
284-
errno: 112,
285-
message: 'Forbidden',
284+
errno: OAUTH_ERRNO.FORBIDDEN,
285+
message: OAUTH_ERROR_MESSAGES.FORBIDDEN,
286286
});
287287
}
288288

289289
static invalidContentType() {
290290
return new OauthError({
291291
code: 415,
292292
error: 'Unsupported Media Type',
293-
errno: 113,
294-
message:
295-
'Content-Type must be either application/json or ' +
296-
'application/x-www-form-urlencoded',
293+
errno: OAUTH_ERRNO.INVALID_CONTENT_TYPE,
294+
message: OAUTH_ERROR_MESSAGES.INVALID_CONTENT_TYPE,
297295
});
298296
}
299297

@@ -302,8 +300,8 @@ export class OauthError extends Error {
302300
{
303301
code: 400,
304302
error: 'Invalid scopes',
305-
errno: 114,
306-
message: 'Requested scopes are not allowed',
303+
errno: OAUTH_ERRNO.INVALID_SCOPES,
304+
message: OAUTH_ERROR_MESSAGES.INVALID_SCOPES,
307305
},
308306
{
309307
invalidScopes: scopes,
@@ -316,8 +314,8 @@ export class OauthError extends Error {
316314
{
317315
code: 400,
318316
error: 'Bad Request',
319-
errno: 115,
320-
message: 'Expired token',
317+
errno: OAUTH_ERRNO.EXPIRED_TOKEN,
318+
message: OAUTH_ERROR_MESSAGES.EXPIRED_TOKEN,
321319
},
322320
{
323321
expiredAt: expiredAt,
@@ -330,8 +328,8 @@ export class OauthError extends Error {
330328
{
331329
code: 400,
332330
error: 'Bad Request',
333-
errno: 116,
334-
message: 'Not a public client',
331+
errno: OAUTH_ERRNO.NOT_PUBLIC_CLIENT,
332+
message: OAUTH_ERROR_MESSAGES.NOT_PUBLIC_CLIENT,
335333
},
336334
{
337335
clientId: hex(clientId),
@@ -344,8 +342,8 @@ export class OauthError extends Error {
344342
{
345343
code: 400,
346344
error: 'Bad Request',
347-
errno: 117,
348-
message: 'Incorrect code_challenge',
345+
errno: OAUTH_ERRNO.INCORRECT_CODE_CHALLENGE,
346+
message: OAUTH_ERROR_MESSAGES.INCORRECT_CODE_CHALLENGE,
349347
},
350348
{
351349
requestCodeChallenge: pkceHashValue,
@@ -357,8 +355,8 @@ export class OauthError extends Error {
357355
return new OauthError({
358356
code: 400,
359357
error: 'PKCE parameters missing',
360-
errno: 118,
361-
message: 'Public clients require PKCE OAuth parameters',
358+
errno: OAUTH_ERRNO.MISSING_PKCE_PARAMETERS,
359+
message: OAUTH_ERROR_MESSAGES.MISSING_PKCE_PARAMETERS,
362360
});
363361
}
364362

@@ -367,8 +365,8 @@ export class OauthError extends Error {
367365
{
368366
code: 401,
369367
error: 'Bad Request',
370-
errno: 119,
371-
message: 'Stale authentication timestamp',
368+
errno: OAUTH_ERRNO.STALE_AUTH_AT,
369+
message: OAUTH_ERROR_MESSAGES.STALE_AUTH_AT,
372370
},
373371
{
374372
authAt: authAt,
@@ -381,8 +379,8 @@ export class OauthError extends Error {
381379
{
382380
code: 400,
383381
error: 'Bad Request',
384-
errno: 120,
385-
message: 'Mismatch acr value',
382+
errno: OAUTH_ERRNO.MISMATCH_ACR_VALUES,
383+
message: OAUTH_ERROR_MESSAGES.MISMATCH_ACR_VALUES,
386384
},
387385
{ foundValue }
388386
);
@@ -392,17 +390,17 @@ export class OauthError extends Error {
392390
return new OauthError({
393391
code: 400,
394392
error: 'Bad Request',
395-
errno: 121,
396-
message: 'Invalid grant_type',
393+
errno: OAUTH_ERRNO.INVALID_GRANT_TYPE,
394+
message: OAUTH_ERROR_MESSAGES.INVALID_GRANT_TYPE,
397395
});
398396
}
399397

400398
static unknownToken() {
401399
return new OauthError({
402400
code: 400,
403401
error: 'Bad Request',
404-
errno: 122,
405-
message: 'Unknown token',
402+
errno: OAUTH_ERRNO.UNKNOWN_TOKEN,
403+
message: OAUTH_ERROR_MESSAGES.UNKNOWN_TOKEN,
406404
});
407405
}
408406

@@ -414,8 +412,8 @@ export class OauthError extends Error {
414412
{
415413
code: 503,
416414
error: 'Client Disabled',
417-
errno: 202, // TODO reconcile this with the auth-server version
418-
message: 'This client has been temporarily disabled',
415+
errno: OAUTH_ERRNO.DISABLED_CLIENT_ID,
416+
message: OAUTH_ERROR_MESSAGES.DISABLED_CLIENT_ID,
419417
},
420418
{ clientId }
421419
);

packages/fxa-auth-server/lib/routes/oauth/introspect.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/*jshint camelcase: false*/
66
const Joi = require('joi');
77
const validators = require('../../oauth/validators');
8-
const { AppError } = require('@fxa/accounts/errors');
8+
const { OauthError } = require('@fxa/accounts/errors');
99
const { getTokenId } = require('../../oauth/token');
1010
const OAUTH_SERVER_DOCS =
1111
require('../../../docs/swagger/oauth-server-api').default;
@@ -79,7 +79,7 @@ module.exports = ({ oauthDB }) => ({
7979
// in the future other clients should be able to use it
8080
// by providing client_secret in the Authentication header
8181
if (!client || !client.publicClient) {
82-
throw AppError.oauthNotPublicClient();
82+
throw OauthError.notPublicClient(token.clientId);
8383
}
8484
}
8585
}

0 commit comments

Comments
 (0)