From c1c4e92791c470dbc4132274adf680a8de4c2d79 Mon Sep 17 00:00:00 2001 From: Lisa Chan Date: Thu, 19 May 2022 12:43:48 -0400 Subject: [PATCH] Remove unnecessary .label()s --- .../fxa-auth-server/lib/routes/account.ts | 282 +++++++--------- .../lib/routes/attached-clients.js | 86 ++--- .../lib/routes/devices-and-sessions.js | 310 ++++++++---------- packages/fxa-auth-server/lib/routes/emails.js | 201 +++++------- .../lib/routes/linked-accounts.ts | 4 +- .../fxa-auth-server/lib/routes/newsletters.js | 2 +- .../lib/routes/oauth/authorization.js | 11 +- .../oauth/authorized-clients/destroy.js | 2 +- .../routes/oauth/authorized-clients/list.js | 24 +- .../lib/routes/oauth/client/get.js | 2 +- .../lib/routes/oauth/destroy.js | 5 +- .../lib/routes/oauth/id_token_verify.js | 5 +- .../lib/routes/oauth/introspect.js | 30 +- .../lib/routes/oauth/key_data.js | 6 +- .../fxa-auth-server/lib/routes/oauth/token.js | 38 +-- .../lib/routes/oauth/verify.js | 4 +- .../fxa-auth-server/lib/routes/password.js | 175 +++++----- .../lib/routes/recovery-codes.js | 42 +-- .../lib/routes/recovery-key.js | 44 +-- .../fxa-auth-server/lib/routes/session.js | 89 +++-- packages/fxa-auth-server/lib/routes/sign.js | 46 ++- .../lib/routes/subscriptions/stripe.ts | 40 +-- .../lib/routes/subscriptions/support.ts | 40 +-- packages/fxa-auth-server/lib/routes/totp.js | 58 ++-- .../lib/routes/unblock-codes.js | 43 +-- .../fxa-auth-server/lib/routes/validators.js | 205 ++++++------ 26 files changed, 788 insertions(+), 1006 deletions(-) diff --git a/packages/fxa-auth-server/lib/routes/account.ts b/packages/fxa-auth-server/lib/routes/account.ts index 40409066d4e..bf8491577b7 100644 --- a/packages/fxa-auth-server/lib/routes/account.ts +++ b/packages/fxa-auth-server/lib/routes/account.ts @@ -1579,43 +1579,36 @@ export const accountRoutes = ( keys: isA.boolean().optional().description(DESCRIPTION.keys), service: validators.service.description(DESCRIPTION.service), }), - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.email), - authPW: validators.authPW.description(DESCRIPTION.authPW), - service: validators.service.description(DESCRIPTION.service), - redirectTo: validators - .redirectTo(config.smtp.redirectDomain) - .optional() - .description(DESCRIPTION.redirectTo), - resume: isA - .string() - .max(2048) - .optional() - .description(DESCRIPTION.resume), - metricsContext: METRICS_CONTEXT_SCHEMA, - style: isA.string().allow(['trailhead']).optional(), - verificationMethod: validators.verificationMethod.optional(), - // preVerified is not available in production mode. - ...(!(config as any).isProduction && { - preVerified: isA.boolean(), - }), - }) - .label('Account.create_payload'), + payload: isA.object({ + email: validators.email().required().description(DESCRIPTION.email), + authPW: validators.authPW.description(DESCRIPTION.authPW), + service: validators.service.description(DESCRIPTION.service), + redirectTo: validators + .redirectTo(config.smtp.redirectDomain) + .optional() + .description(DESCRIPTION.redirectTo), + resume: isA + .string() + .max(2048) + .optional() + .description(DESCRIPTION.resume), + metricsContext: METRICS_CONTEXT_SCHEMA, + style: isA.string().allow(['trailhead']).optional(), + verificationMethod: validators.verificationMethod.optional(), + // preVerified is not available in production mode. + ...(!(config as any).isProduction && { + preVerified: isA.boolean(), + }), + }), }, response: { - schema: isA - .object({ - uid: isA.string().regex(HEX_STRING).required(), - sessionToken: isA.string().regex(HEX_STRING).required(), - keyFetchToken: isA.string().regex(HEX_STRING).optional(), - authAt: isA.number().integer().description(DESCRIPTION.authAt), - verificationMethod: validators.verificationMethod.optional(), - }) - .label('Account.create_response'), + schema: isA.object({ + uid: isA.string().regex(HEX_STRING).required(), + sessionToken: isA.string().regex(HEX_STRING).required(), + keyFetchToken: isA.string().regex(HEX_STRING).optional(), + authAt: isA.number().integer().description(DESCRIPTION.authAt), + verificationMethod: validators.verificationMethod.optional(), + }), }, }, handler: (request: AuthRequest) => accountHandler.accountCreate(request), @@ -1626,13 +1619,11 @@ export const accountRoutes = ( options: { ...MISC_DOCS.ACCOUNT_STUB_POST, validate: { - payload: isA - .object({ - email: validators.email().required(), - clientId: validators.clientId.required(), - metricsContext: METRICS_CONTEXT_SCHEMA, - }) - .label('Account.stub_payload'), + payload: isA.object({ + email: validators.email().required(), + clientId: validators.clientId.required(), + metricsContext: METRICS_CONTEXT_SCHEMA, + }), }, }, handler: (request: AuthRequest) => accountHandler.accountStub(request), @@ -1643,12 +1634,10 @@ export const accountRoutes = ( options: { ...MISC_DOCS.ACCOUNT_FINISH_SETUP_POST, validate: { - payload: isA - .object({ - token: validators.jwt, - authPW: validators.authPW, - }) - .label('Account.finishSetup_payload'), + payload: isA.object({ + token: validators.jwt, + authPW: validators.authPW, + }), }, }, handler: (request: AuthRequest) => accountHandler.finishSetup(request), @@ -1677,56 +1666,49 @@ export const accountRoutes = ( .optional() .description(DESCRIPTION.verificationMethod), }), - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.email), - authPW: validators.authPW.description(DESCRIPTION.authPW), - service: validators.service.description(DESCRIPTION.service), - redirectTo: validators - .redirectTo(config.smtp.redirectDomain) - .optional(), - resume: isA.string().optional().description(DESCRIPTION.resume), - reason: isA - .string() - .max(16) - .optional() - .description(DESCRIPTION.reason), - unblockCode: signinUtils.validators.UNBLOCK_CODE.description( - DESCRIPTION.unblockCode - ), - metricsContext: METRICS_CONTEXT_SCHEMA, - originalLoginEmail: validators - .email() - .optional() - .description(DESCRIPTION.originalLoginEmail), - verificationMethod: validators.verificationMethod - .optional() - .description(DESCRIPTION.verificationMethod), - }) - .label('Account.login_payload'), + payload: isA.object({ + email: validators.email().required().description(DESCRIPTION.email), + authPW: validators.authPW.description(DESCRIPTION.authPW), + service: validators.service.description(DESCRIPTION.service), + redirectTo: validators + .redirectTo(config.smtp.redirectDomain) + .optional(), + resume: isA.string().optional().description(DESCRIPTION.resume), + reason: isA + .string() + .max(16) + .optional() + .description(DESCRIPTION.reason), + unblockCode: signinUtils.validators.UNBLOCK_CODE.description( + DESCRIPTION.unblockCode + ), + metricsContext: METRICS_CONTEXT_SCHEMA, + originalLoginEmail: validators + .email() + .optional() + .description(DESCRIPTION.originalLoginEmail), + verificationMethod: validators.verificationMethod + .optional() + .description(DESCRIPTION.verificationMethod), + }), }, response: { - schema: isA - .object({ - uid: isA.string().regex(HEX_STRING).required(), - sessionToken: isA.string().regex(HEX_STRING).required(), - keyFetchToken: isA.string().regex(HEX_STRING).optional(), - verificationMethod: isA - .string() - .optional() - .description(DESCRIPTION.verificationMethod), - verificationReason: isA - .string() - .optional() - .description(DESCRIPTION.verificationReason), - verified: isA.boolean().required(), - authAt: isA.number().integer().description(DESCRIPTION.authAt), - metricsEnabled: isA.boolean().required(), - }) - .label('Account.login_response'), + schema: isA.object({ + uid: isA.string().regex(HEX_STRING).required(), + sessionToken: isA.string().regex(HEX_STRING).required(), + keyFetchToken: isA.string().regex(HEX_STRING).optional(), + verificationMethod: isA + .string() + .optional() + .description(DESCRIPTION.verificationMethod), + verificationReason: isA + .string() + .optional() + .description(DESCRIPTION.verificationReason), + verified: isA.boolean().required(), + authAt: isA.number().integer().description(DESCRIPTION.authAt), + metricsEnabled: isA.boolean().required(), + }), }, }, handler: (request: AuthRequest) => accountHandler.login(request), @@ -1754,20 +1736,16 @@ export const accountRoutes = ( options: { ...ACCOUNT_DOCS.ACCOUNT_STATUS_POST, validate: { - payload: isA - .object({ - email: validators.email().required(), - checkDomain: isA.optional(), - }) - .label('AccountStatusCheck_payload'), + payload: isA.object({ + email: validators.email().required(), + checkDomain: isA.optional(), + }), }, response: { - schema: isA - .object({ - exists: isA.boolean().required(), - invalidDomain: isA.boolean().optional(), - }) - .label('AccountStausCheck_response'), + schema: isA.object({ + exists: isA.boolean().required(), + invalidDomain: isA.boolean().optional(), + }), }, }, handler: (request: AuthRequest) => @@ -1782,20 +1760,18 @@ export const accountRoutes = ( strategies: ['sessionToken', 'oauthToken'], }, response: { - schema: isA - .object({ - email: isA.string().optional(), - locale: isA.string().optional().allow(null), - authenticationMethods: isA - .array() - .items(isA.string().required()) - .optional(), - authenticatorAssuranceLevel: isA.number().min(0), - subscriptionsByClientId: isA.object().unknown(true).optional(), - profileChangedAt: isA.number().min(0), - metricsEnabled: isA.boolean().optional(), - }) - .label('Account.profile_response'), + schema: isA.object({ + email: isA.string().optional(), + locale: isA.string().optional().allow(null), + authenticationMethods: isA + .array() + .items(isA.string().required()) + .optional(), + authenticatorAssuranceLevel: isA.number().min(0), + subscriptionsByClientId: isA.object().unknown(true).optional(), + profileChangedAt: isA.number().min(0), + metricsEnabled: isA.boolean().optional(), + }), }, }, handler: (request: AuthRequest) => accountHandler.profile(request), @@ -1809,14 +1785,12 @@ export const accountRoutes = ( strategy: 'keyFetchTokenWithVerificationStatus', }, response: { - schema: isA - .object({ - bundle: isA - .string() - .regex(HEX_STRING) - .description(DESCRIPTION.bundle), - }) - .label('Account.keys_response'), + schema: isA.object({ + bundle: isA + .string() + .regex(HEX_STRING) + .description(DESCRIPTION.bundle), + }), }, }, handler: (request: AuthRequest) => accountHandler.keys(request), @@ -1872,8 +1846,7 @@ export const accountRoutes = ( .optional() .description(DESCRIPTION.sessionToken), }) - .and('wrapKb', 'recoveryKeyId') - .label('Account.reset_payload'), + .and('wrapKb', 'recoveryKeyId'), }, }, handler: (request: AuthRequest) => accountHandler.reset(request), @@ -1888,15 +1861,10 @@ export const accountRoutes = ( strategy: 'sessionToken', }, validate: { - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.email), - authPW: validators.authPW.description(DESCRIPTION.authPW), - }) - .label('Account.destroy_payload'), + payload: isA.object({ + email: validators.email().required().description(DESCRIPTION.email), + authPW: validators.authPW.description(DESCRIPTION.authPW), + }), }, }, handler: (request: AuthRequest) => accountHandler.destroy(request), @@ -1910,23 +1878,21 @@ export const accountRoutes = ( strategy: 'sessionToken', }, response: { - schema: isA - .object({ - // This endpoint is evolving, it's not just for subscriptions. - // Ultimately we want it to become a one-stop shop for all of - // the account data needed by the settings screen, so that we - // can drastically reduce how many requests are made to the - // backend. Discussion in: - // - // https://github.com/mozilla/fxa/issues/1808 - subscriptions: isA - .array() - .items( - validators.subscriptionsSubscriptionValidator, - validators.subscriptionsGooglePlaySubscriptionValidator - ), - }) - .label('Account.subscriptions'), + schema: isA.object({ + // This endpoint is evolving, it's not just for subscriptions. + // Ultimately we want it to become a one-stop shop for all of + // the account data needed by the settings screen, so that we + // can drastically reduce how many requests are made to the + // backend. Discussion in: + // + // https://github.com/mozilla/fxa/issues/1808 + subscriptions: isA + .array() + .items( + validators.subscriptionsSubscriptionValidator, + validators.subscriptionsGooglePlaySubscriptionValidator + ), + }), }, }, handler: (request: AuthRequest) => accountHandler.getAccount(request), diff --git a/packages/fxa-auth-server/lib/routes/attached-clients.js b/packages/fxa-auth-server/lib/routes/attached-clients.js index d465ed5bbae..77e363803cb 100644 --- a/packages/fxa-auth-server/lib/routes/attached-clients.js +++ b/packages/fxa-auth-server/lib/routes/attached-clients.js @@ -27,54 +27,41 @@ module.exports = (log, db, devices, clientUtils) => { strategy: 'sessionToken', }, response: { - schema: isA - .array() - .items( - isA - .object({ - clientId: isA - .string() - .regex(HEX_STRING) - .allow(null) - .required(), - deviceId: DEVICES_SCHEMA.id.allow(null).required(), - sessionTokenId: isA - .string() - .regex(HEX_STRING) - .allow(null) - .required(), - refreshTokenId: isA - .string() - .regex(HEX_STRING) - .allow(null) - .required(), - isCurrentSession: isA.boolean().required(), - deviceType: DEVICES_SCHEMA.type.allow(null).required(), - name: DEVICES_SCHEMA.nameResponse - .allow('') - .allow(null) - .required(), - createdTime: isA.number().min(0).required().allow(null), - createdTimeFormatted: isA.string().optional().allow(''), - lastAccessTime: isA.number().min(0).required().allow(null), - lastAccessTimeFormatted: isA.string().optional().allow(''), - approximateLastAccessTime: isA.number().min(0).optional(), - approximateLastAccessTimeFormatted: isA - .string() - .optional() - .allow(''), - scope: isA - .array() - .items(validators.scope) - .required() - .allow(null), - location: DEVICES_SCHEMA.location, - userAgent: isA.string().max(255).required().allow(''), - os: isA.string().max(255).allow('').allow(null), - }) - .label('Account.attachedClient_model') - ) - .label('Account.attachedClients_response'), + schema: isA.array().items( + isA.object({ + clientId: isA.string().regex(HEX_STRING).allow(null).required(), + deviceId: DEVICES_SCHEMA.id.allow(null).required(), + sessionTokenId: isA + .string() + .regex(HEX_STRING) + .allow(null) + .required(), + refreshTokenId: isA + .string() + .regex(HEX_STRING) + .allow(null) + .required(), + isCurrentSession: isA.boolean().required(), + deviceType: DEVICES_SCHEMA.type.allow(null).required(), + name: DEVICES_SCHEMA.nameResponse + .allow('') + .allow(null) + .required(), + createdTime: isA.number().min(0).required().allow(null), + createdTimeFormatted: isA.string().optional().allow(''), + lastAccessTime: isA.number().min(0).required().allow(null), + lastAccessTimeFormatted: isA.string().optional().allow(''), + approximateLastAccessTime: isA.number().min(0).optional(), + approximateLastAccessTimeFormatted: isA + .string() + .optional() + .allow(''), + scope: isA.array().items(validators.scope).required().allow(null), + location: DEVICES_SCHEMA.location, + userAgent: isA.string().max(255).required().allow(''), + os: isA.string().max(255).allow('').allow(null), + }) + ), }, }, handler: async function (request) { @@ -127,8 +114,7 @@ module.exports = (log, db, devices, clientUtils) => { deviceId: DEVICES_SCHEMA.id.allow(null).optional(), }) .or('clientId', 'sessionTokenId', 'refreshTokenId', 'deviceId') - .with('refreshTokenId', ['clientId']) - .label('Account.attachedClientDestroy_payload'), + .with('refreshTokenId', ['clientId']), }, response: { schema: {}, diff --git a/packages/fxa-auth-server/lib/routes/devices-and-sessions.js b/packages/fxa-auth-server/lib/routes/devices-and-sessions.js index eb10ee9f9c9..ac12a55f1d3 100644 --- a/packages/fxa-auth-server/lib/routes/devices-and-sessions.js +++ b/packages/fxa-auth-server/lib/routes/devices-and-sessions.js @@ -116,8 +116,7 @@ module.exports = ( // We accept but ignore it. capabilities: isA.array().length(0).optional(), }) - .and('pushCallback', 'pushPublicKey', 'pushAuthKey') - .label('Account.device_payload'), + .and('pushCallback', 'pushPublicKey', 'pushAuthKey'), }, response: { schema: isA @@ -133,8 +132,7 @@ module.exports = ( DEVICES_SCHEMA.pushEndpointExpired.optional(), availableCommands: DEVICES_SCHEMA.availableCommands.optional(), }) - .and('pushCallback', 'pushPublicKey', 'pushAuthKey') - .label('Account.device_response'), + .and('pushCallback', 'pushPublicKey', 'pushAuthKey'), }, }, handler: async function (request) { @@ -221,24 +219,21 @@ module.exports = ( messages: isA .array() .items( - isA - .object({ - index: isA.number().required(), - data: isA - .object({ - command: isA.string().max(255).required(), - payload: isA.object().required(), - sender: DEVICES_SCHEMA.id.optional(), - }) - .required(), - }) - .label('message') + isA.object({ + index: isA.number().required(), + data: isA + .object({ + command: isA.string().max(255).required(), + payload: isA.object().required(), + sender: DEVICES_SCHEMA.id.optional(), + }) + .required(), + }) ) .optional() .description(DESCRIPTION.messages), }) - .and('last', 'messages') - .label('Account.deviceCommands_response'), + .and('last', 'messages'), }, }, handler: async function (request) { @@ -284,31 +279,27 @@ module.exports = ( strategies: ['sessionToken', 'refreshToken'], }, validate: { - payload: isA - .object({ - target: DEVICES_SCHEMA.id - .required() - .description(DESCRIPTION.target), - command: isA.string().required().description(DESCRIPTION.command), - payload: isA.object().required().description(DESCRIPTION.payload), - ttl: isA - .number() - .integer() - .min(0) - .max(10000000) - .optional() - .description(DESCRIPTION.ttl), - }) - .label('Account.invokeDeviceCommand_payload'), + payload: isA.object({ + target: DEVICES_SCHEMA.id + .required() + .description(DESCRIPTION.target), + command: isA.string().required().description(DESCRIPTION.command), + payload: isA.object().required().description(DESCRIPTION.payload), + ttl: isA + .number() + .integer() + .min(0) + .max(10000000) + .optional() + .description(DESCRIPTION.ttl), + }), }, response: { - schema: isA - .object({ - enqueued: isA.boolean().optional(), - notified: isA.boolean().optional(), - notifyError: isA.string().optional(), - }) - .label('Account.invokeDeviceCommand_response'), + schema: isA.object({ + enqueued: isA.boolean().optional(), + notified: isA.boolean().optional(), + notifyError: isA.string().optional(), + }), }, }, handler: async function (request) { @@ -406,35 +397,33 @@ module.exports = ( }, validate: { payload: isA.alternatives().try( - isA - .object({ - to: isA - .string() - .valid('all') - .required() - .description(DESCRIPTION.to), - _endpointAction: isA.string().valid('accountVerify').optional(), - excluded: isA - .array() - .items(isA.string().length(32).regex(HEX_STRING)) - .optional() - .description(DESCRIPTION.excluded), - payload: isA - .object() - .when('_endpointAction', { - is: 'accountVerify', - then: isA.required(), - otherwise: isA.required(), - }) - .description(DESCRIPTION.pushPayload), - TTL: isA - .number() - .integer() - .min(0) - .optional() - .description(DESCRIPTION.ttlPushNotification), - }) - .label('Account.devicesNotify_payload'), + isA.object({ + to: isA + .string() + .valid('all') + .required() + .description(DESCRIPTION.to), + _endpointAction: isA.string().valid('accountVerify').optional(), + excluded: isA + .array() + .items(isA.string().length(32).regex(HEX_STRING)) + .optional() + .description(DESCRIPTION.excluded), + payload: isA + .object() + .when('_endpointAction', { + is: 'accountVerify', + then: isA.required(), + otherwise: isA.required(), + }) + .description(DESCRIPTION.pushPayload), + TTL: isA + .number() + .integer() + .min(0) + .optional() + .description(DESCRIPTION.ttlPushNotification), + }), isA.object({ to: isA .array() @@ -549,41 +538,34 @@ module.exports = ( strategies: ['sessionToken', 'refreshToken'], }, response: { - schema: isA - .array() - .items( - isA - .object({ - id: DEVICES_SCHEMA.id.required(), - isCurrentDevice: isA.boolean().required(), - lastAccessTime: isA.number().min(0).required().allow(null), - lastAccessTimeFormatted: isA.string().optional().allow(''), - approximateLastAccessTime: isA.number().min(0).optional(), - approximateLastAccessTimeFormatted: isA - .string() - .optional() - .allow(''), - location: DEVICES_SCHEMA.location, - name: DEVICES_SCHEMA.nameResponse.allow('').required(), - type: DEVICES_SCHEMA.type.required(), - pushCallback: DEVICES_SCHEMA.pushCallback - .allow(null) - .optional(), - pushPublicKey: DEVICES_SCHEMA.pushPublicKey - .allow(null) - .optional(), - pushAuthKey: DEVICES_SCHEMA.pushAuthKey - .allow(null) - .optional(), - pushEndpointExpired: - DEVICES_SCHEMA.pushEndpointExpired.optional(), - availableCommands: - DEVICES_SCHEMA.availableCommands.optional(), - }) - .and('pushPublicKey', 'pushAuthKey') - .label('Account.device_model') - ) - .label('Account.devices_response'), + schema: isA.array().items( + isA + .object({ + id: DEVICES_SCHEMA.id.required(), + isCurrentDevice: isA.boolean().required(), + lastAccessTime: isA.number().min(0).required().allow(null), + lastAccessTimeFormatted: isA.string().optional().allow(''), + approximateLastAccessTime: isA.number().min(0).optional(), + approximateLastAccessTimeFormatted: isA + .string() + .optional() + .allow(''), + location: DEVICES_SCHEMA.location, + name: DEVICES_SCHEMA.nameResponse.allow('').required(), + type: DEVICES_SCHEMA.type.required(), + pushCallback: DEVICES_SCHEMA.pushCallback + .allow(null) + .optional(), + pushPublicKey: DEVICES_SCHEMA.pushPublicKey + .allow(null) + .optional(), + pushAuthKey: DEVICES_SCHEMA.pushAuthKey.allow(null).optional(), + pushEndpointExpired: + DEVICES_SCHEMA.pushEndpointExpired.optional(), + availableCommands: DEVICES_SCHEMA.availableCommands.optional(), + }) + .and('pushPublicKey', 'pushAuthKey') + ), }, }, handler: async function (request) { @@ -669,51 +651,46 @@ module.exports = ( ], }, response: { - schema: isA - .array() - .items( - isA - .object({ - id: isA.string().regex(HEX_STRING).required(), - lastAccessTime: isA.number().min(0).required().allow(null), - lastAccessTimeFormatted: isA.string().optional().allow(''), - approximateLastAccessTime: isA.number().min(0).optional(), - approximateLastAccessTimeFormatted: isA - .string() - .optional() - .allow(''), - createdTime: isA.number().min(0).required().allow(null), - createdTimeFormatted: isA.string().optional().allow(''), - location: DEVICES_SCHEMA.location, - userAgent: isA.string().max(255).required().allow(''), - os: isA.string().max(255).allow('').allow(null), - deviceId: DEVICES_SCHEMA.id.allow(null).required(), - deviceName: DEVICES_SCHEMA.nameResponse - .allow('') - .allow(null) - .required(), - deviceAvailableCommands: DEVICES_SCHEMA.availableCommands - .allow(null) - .required(), - deviceType: DEVICES_SCHEMA.type.allow(null).required(), - deviceCallbackURL: DEVICES_SCHEMA.pushCallback - .allow(null) - .required(), - deviceCallbackPublicKey: DEVICES_SCHEMA.pushPublicKey - .allow(null) - .required(), - deviceCallbackAuthKey: DEVICES_SCHEMA.pushAuthKey - .allow(null) - .required(), - deviceCallbackIsExpired: DEVICES_SCHEMA.pushEndpointExpired - .allow(null) - .required(), - isDevice: isA.boolean().required(), - isCurrentDevice: isA.boolean().required(), - }) - .label('Account.session_model') - ) - .label('Account.session_response'), + schema: isA.array().items( + isA.object({ + id: isA.string().regex(HEX_STRING).required(), + lastAccessTime: isA.number().min(0).required().allow(null), + lastAccessTimeFormatted: isA.string().optional().allow(''), + approximateLastAccessTime: isA.number().min(0).optional(), + approximateLastAccessTimeFormatted: isA + .string() + .optional() + .allow(''), + createdTime: isA.number().min(0).required().allow(null), + createdTimeFormatted: isA.string().optional().allow(''), + location: DEVICES_SCHEMA.location, + userAgent: isA.string().max(255).required().allow(''), + os: isA.string().max(255).allow('').allow(null), + deviceId: DEVICES_SCHEMA.id.allow(null).required(), + deviceName: DEVICES_SCHEMA.nameResponse + .allow('') + .allow(null) + .required(), + deviceAvailableCommands: DEVICES_SCHEMA.availableCommands + .allow(null) + .required(), + deviceType: DEVICES_SCHEMA.type.allow(null).required(), + deviceCallbackURL: DEVICES_SCHEMA.pushCallback + .allow(null) + .required(), + deviceCallbackPublicKey: DEVICES_SCHEMA.pushPublicKey + .allow(null) + .required(), + deviceCallbackAuthKey: DEVICES_SCHEMA.pushAuthKey + .allow(null) + .required(), + deviceCallbackIsExpired: DEVICES_SCHEMA.pushEndpointExpired + .allow(null) + .required(), + isDevice: isA.boolean().required(), + isCurrentDevice: isA.boolean().required(), + }) + ), }, }, handler: async function (request) { @@ -778,11 +755,9 @@ module.exports = ( strategies: ['sessionToken', 'refreshToken'], }, validate: { - payload: isA - .object({ - id: DEVICES_SCHEMA.id.required(), - }) - .label('Account.deviceDestroy_payload'), + payload: isA.object({ + id: DEVICES_SCHEMA.id.required(), + }), }, response: { schema: {}, @@ -809,21 +784,16 @@ module.exports = ( }, }, response: { - schema: isA - .array() - .items( - isA - .object({ - city: isA.string().required().allow(null), - state: isA.string().required().allow(null), - stateCode: isA.string().required().allow(null), - country: isA.string().required().allow(null), - countryCode: isA.string().required().allow(null), - lastAccessTime: isA.number().required(), - }) - .label('Account.sessionsLocation') - ) - .label('Account.sessionsLocations_response'), + schema: isA.array().items( + isA.object({ + city: isA.string().required().allow(null), + state: isA.string().required().allow(null), + stateCode: isA.string().required().allow(null), + country: isA.string().required().allow(null), + countryCode: isA.string().required().allow(null), + lastAccessTime: isA.number().required(), + }) + ), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/emails.js b/packages/fxa-auth-server/lib/routes/emails.js index ebfc22dd8bb..d2a9bb18e5b 100644 --- a/packages/fxa-auth-server/lib/routes/emails.js +++ b/packages/fxa-auth-server/lib/routes/emails.js @@ -112,16 +112,14 @@ module.exports = ( }, }, response: { - schema: isA - .object({ - // There's code in the handler that checks for a valid email, - // no point adding overhead by doing it again here. - email: isA.string().required(), - verified: isA.boolean().required(), - sessionVerified: isA.boolean().optional(), - emailVerified: isA.boolean().optional(), - }) - .label('Account.RecoveryEmailStatus_response'), + schema: isA.object({ + // There's code in the handler that checks for a valid email, + // no point adding overhead by doing it again here. + email: isA.string().required(), + verified: isA.boolean().required(), + sessionVerified: isA.boolean().optional(), + emailVerified: isA.boolean().optional(), + }), }, }, handler: async function (request) { @@ -218,27 +216,25 @@ module.exports = ( .allow(['upgradeSession']) .optional(), }), - payload: isA - .object({ - email: validators.email().optional(), - service: validators.service.description(DESCRIPTION.service), - redirectTo: validators - .redirectTo(config.smtp.redirectDomain) - .optional(), - resume: isA - .string() - .max(2048) - .optional() - .description(DESCRIPTION.resume), - style: isA.string().allow(['trailhead']).optional(), - type: isA - .string() - .max(32) - .alphanum() - .allow(['upgradeSession']) - .optional(), - }) - .label('Account.RecoveryEmailResend_payload'), + payload: isA.object({ + email: validators.email().optional(), + service: validators.service.description(DESCRIPTION.service), + redirectTo: validators + .redirectTo(config.smtp.redirectDomain) + .optional(), + resume: isA + .string() + .max(2048) + .optional() + .description(DESCRIPTION.resume), + style: isA.string().allow(['trailhead']).optional(), + type: isA + .string() + .max(32) + .alphanum() + .allow(['upgradeSession']) + .optional(), + }), }, }, handler: async function (request) { @@ -374,28 +370,26 @@ module.exports = ( options: { ...EMAILS_DOCS.RECOVERY_EMAIL_VERIFY_CODE_POST, validate: { - payload: isA - .object({ - uid: isA.string().max(32).regex(HEX_STRING).required(), - code: isA.string().min(32).max(32).regex(HEX_STRING).required(), - service: validators.service.description(DESCRIPTION.service), - reminder: isA - .string() - .regex(REMINDER_PATTERN) - .optional() - .description(DESCRIPTION.reminder), - type: isA - .string() - .max(32) - .alphanum() - .optional() - .description(DESCRIPTION.type), - style: isA.string().allow(['trailhead']).optional(), - // The `marketingOptIn` is safe to remove after train-167+ - marketingOptIn: isA.boolean().optional(), - newsletters: validators.newsletters, - }) - .label('Account.RecoveryEmailVerify_payload'), + payload: isA.object({ + uid: isA.string().max(32).regex(HEX_STRING).required(), + code: isA.string().min(32).max(32).regex(HEX_STRING).required(), + service: validators.service.description(DESCRIPTION.service), + reminder: isA + .string() + .regex(REMINDER_PATTERN) + .optional() + .description(DESCRIPTION.reminder), + type: isA + .string() + .max(32) + .alphanum() + .optional() + .description(DESCRIPTION.type), + style: isA.string().allow(['trailhead']).optional(), + // The `marketingOptIn` is safe to remove after train-167+ + marketingOptIn: isA.boolean().optional(), + newsletters: validators.newsletters, + }), }, }, handler: async function (request) { @@ -519,18 +513,13 @@ module.exports = ( strategy: 'sessionToken', }, response: { - schema: isA - .array() - .items( - isA - .object({ - verified: isA.boolean().required(), - isPrimary: isA.boolean().required(), - email: validators.email().required(), - }) - .label('Account.RecoveryEmail') - ) - .label('Account.RecoveryEmailEmails_response'), + schema: isA.array().items( + isA.object({ + verified: isA.boolean().required(), + isPrimary: isA.boolean().required(), + email: validators.email().required(), + }) + ), }, }, handler: async function (request) { @@ -557,14 +546,12 @@ module.exports = ( payload: 'required', }, validate: { - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.emailAdd), - }) - .label('Account.RecoveryEmailCreate_payload'), + payload: isA.object({ + email: validators + .email() + .required() + .description(DESCRIPTION.emailAdd), + }), }, response: {}, }, @@ -710,14 +697,12 @@ module.exports = ( payload: 'required', }, validate: { - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.emailDelete), - }) - .label('Account.RecoveryEmailDestroy_payload'), + payload: isA.object({ + email: validators + .email() + .required() + .description(DESCRIPTION.emailDelete), + }), }, response: {}, }, @@ -774,14 +759,12 @@ module.exports = ( payload: 'required', }, validate: { - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.emailNewPrimary), - }) - .label('Account.RecoveryEmailSetPrimary_payload'), + payload: isA.object({ + email: validators + .email() + .required() + .description(DESCRIPTION.emailNewPrimary), + }), }, response: {}, }, @@ -885,14 +868,12 @@ module.exports = ( payload: 'required', }, validate: { - payload: isA - .object({ - email: validators - .email() - .description(DESCRIPTION.emailSecondaryVerify) - .required(), - }) - .label('Account.RecoveryEmailSecondaryResend_payload'), + payload: isA.object({ + email: validators + .email() + .description(DESCRIPTION.emailSecondaryVerify) + .required(), + }), }, response: {}, }, @@ -972,20 +953,18 @@ module.exports = ( payload: 'required', }, validate: { - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.emailSecondaryVerify), - code: isA - .string() - .max(32) - .regex(validators.DIGITS) - .description(DESCRIPTION.code) - .required(), - }) - .label('Account.RecoveryEmailSecondaryVerify_payload'), + payload: isA.object({ + email: validators + .email() + .required() + .description(DESCRIPTION.emailSecondaryVerify), + code: isA + .string() + .max(32) + .regex(validators.DIGITS) + .description(DESCRIPTION.code) + .required(), + }), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/linked-accounts.ts b/packages/fxa-auth-server/lib/routes/linked-accounts.ts index e7c1e1cab9b..675c08d89c3 100644 --- a/packages/fxa-auth-server/lib/routes/linked-accounts.ts +++ b/packages/fxa-auth-server/lib/routes/linked-accounts.ts @@ -316,7 +316,7 @@ export const linkedAccountRoutes = ( provider: validators.thirdPartyProvider, code: validators.thirdPartyOAuthCode, metricsContext: METRICS_CONTEXT_SCHEMA, - }).label('LinkedAccount.login_payload'), + }), }, }, handler: async (request: AuthRequest) => @@ -333,7 +333,7 @@ export const linkedAccountRoutes = ( validate: { payload: Joi.object({ provider: validators.thirdPartyProvider, - }).label('LinkedAccount.unlink_payload'), + }), }, }, handler: (request: AuthRequest) => handler.unlinkAccount(request), diff --git a/packages/fxa-auth-server/lib/routes/newsletters.js b/packages/fxa-auth-server/lib/routes/newsletters.js index 4a1215b47f3..8a824e43ce9 100644 --- a/packages/fxa-auth-server/lib/routes/newsletters.js +++ b/packages/fxa-auth-server/lib/routes/newsletters.js @@ -25,7 +25,7 @@ module.exports = (log, db) => { validate: { payload: Joi.object({ newsletters: validators.newsletters.required(), - }).label('Newsletters_payload'), + }), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/oauth/authorization.js b/packages/fxa-auth-server/lib/routes/oauth/authorization.js index c110f8bafcb..ba5288bafba 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/authorization.js +++ b/packages/fxa-auth-server/lib/routes/oauth/authorization.js @@ -265,7 +265,7 @@ module.exports = ({ log, oauthDB, config }) => { then: Joi.optional(), otherwise: Joi.forbidden(), }), - }).label('Authorization_payload'), + }), }, response: { schema: Joi.object() @@ -286,8 +286,7 @@ module.exports = ({ log, oauthDB, config }) => { 'expires_in', ]) .with('code', ['state', 'redirect']) - .without('code', ['access_token']) - .label('Authorization_response'), + .without('code', ['access_token']), }, handler: function (req) { // Refuse to generate new codes or tokens for disabled clients. @@ -348,16 +347,14 @@ module.exports = ({ log, oauthDB, config }) => { .description(DESCRIPTION.acrValues), assertion: Joi.forbidden(), resource: Joi.forbidden(), - }) - .and('code_challenge', 'code_challenge_method') - .label('Oauth.authorization_payload'), + }).and('code_challenge', 'code_challenge_method'), }, response: { schema: Joi.object({ redirect: Joi.string(), code: Joi.string(), state: Joi.string().max(512), - }).label('Oauth.authorization_response'), + }), }, }, handler: async function (req) { diff --git a/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/destroy.js b/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/destroy.js index d730c4a9455..84e557e882a 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/destroy.js +++ b/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/destroy.js @@ -19,7 +19,7 @@ module.exports = () => ({ client_id: validators.clientId, refresh_token_id: validators.token.optional(), assertion: validators.assertion, - }).label('AuthorizedClients.destroy_payload'), + }), }, handler: async function (req) { const claims = await verifyAssertion(req.payload.assertion); diff --git a/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/list.js b/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/list.js index 0c37b7b056d..baf0988c496 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/list.js +++ b/packages/fxa-auth-server/lib/routes/oauth/authorized-clients/list.js @@ -18,21 +18,19 @@ module.exports = () => ({ validate: { payload: Joi.object({ assertion: validators.assertion.required(), - }).label('AuthorizedClients_payload'), + }), }, response: { - schema: Joi.array() - .items( - Joi.object({ - client_id: validators.clientId, - refresh_token_id: validators.token.optional(), - client_name: Joi.string().required(), - created_time: Joi.number().min(0).required(), - last_access_time: Joi.number().min(0).required().allow(null), - scope: Joi.array().items(Joi.string()).required(), - }).label('AuthorizedClient') - ) - .label('AuthorizedClients_response'), + schema: Joi.array().items( + Joi.object({ + client_id: validators.clientId, + refresh_token_id: validators.token.optional(), + client_name: Joi.string().required(), + created_time: Joi.number().min(0).required(), + last_access_time: Joi.number().min(0).required().allow(null), + scope: Joi.array().items(Joi.string()).required(), + }) + ), }, handler: async function (req) { const claims = await verifyAssertion(req.payload.assertion); diff --git a/packages/fxa-auth-server/lib/routes/oauth/client/get.js b/packages/fxa-auth-server/lib/routes/oauth/client/get.js index 3f63b800a55..f002e8eae83 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/client/get.js +++ b/packages/fxa-auth-server/lib/routes/oauth/client/get.js @@ -27,7 +27,7 @@ module.exports = ({ log, oauthDB }) => ({ trusted: Joi.boolean().required(), image_uri: Joi.any(), redirect_uri: Joi.string().required().allow(''), - }).label('Oauth.clientId_response'), + }), }, handler: async function requestInfoEndpoint(req) { const params = req.params; diff --git a/packages/fxa-auth-server/lib/routes/oauth/destroy.js b/packages/fxa-auth-server/lib/routes/oauth/destroy.js index 90e9281f19d..c15447a7aa7 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/destroy.js +++ b/packages/fxa-auth-server/lib/routes/oauth/destroy.js @@ -89,8 +89,7 @@ module.exports = ({ log, oauthDB }) => { refresh_token_id: validators.token, }) .rename('token', 'access_token') - .xor('access_token', 'refresh_token', 'refresh_token_id') - .label('Destroy_payload'), + .xor('access_token', 'refresh_token', 'refresh_token_id'), }, handler: destroyHandler, }, @@ -118,7 +117,7 @@ module.exports = ({ log, oauthDB }) => { .max(64) .optional() .description(DESCRIPTION.tokenTypeHint), - }).label('oauth.destroy_payload'), + }), }, response: {}, }, diff --git a/packages/fxa-auth-server/lib/routes/oauth/id_token_verify.js b/packages/fxa-auth-server/lib/routes/oauth/id_token_verify.js index 3d435f48494..f96284363b4 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/id_token_verify.js +++ b/packages/fxa-auth-server/lib/routes/oauth/id_token_verify.js @@ -17,7 +17,7 @@ module.exports = () => ({ client_id: Joi.string().required(), id_token: Joi.string().required(), expiry_grace_period: Joi.number().default(0), - }).label('Oauth.idTokenVerify_payload'), + }), }, response: { schema: Joi.object() @@ -33,8 +33,7 @@ module.exports = () => ({ iat: Joi.number().optional(), iss: Joi.string().optional(), sub: Joi.string().optional(), - }) - .label('Oauth.idTokenVerify_response'), + }), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/oauth/introspect.js b/packages/fxa-auth-server/lib/routes/oauth/introspect.js index 22a3edf2c0c..7c0e982c4af 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/introspect.js +++ b/packages/fxa-auth-server/lib/routes/oauth/introspect.js @@ -13,7 +13,7 @@ const MISC_DOCS = require('../../../docs/swagger/misc-api').default; const PAYLOAD_SCHEMA = Joi.object({ token: Joi.string().required(), token_type_hint: Joi.string().equal(['access_token', 'refresh_token']), -}).label('Introspect_payload'); +}); // The "token introspection" endpoint, per https://tools.ietf.org/html/rfc7662 @@ -27,21 +27,19 @@ module.exports = ({ oauthDB }) => ({ payload: PAYLOAD_SCHEMA.options({ stripUnknown: true }), }, response: { - schema: Joi.object() - .keys({ - // https://tools.ietf.org/html/rfc7662#section-2.2 - active: Joi.boolean().required(), - scope: validators.scope.optional(), - client_id: validators.clientId.optional(), - token_type: Joi.string().equal(['access_token', 'refresh_token']), - exp: Joi.number().optional(), - iat: Joi.number().optional(), - sub: Joi.string().optional(), - iss: Joi.string().optional(), - jti: Joi.string().optional(), - 'fxa-lastUsedAt': Joi.number().optional(), - }) - .label('Introspect_response'), + schema: Joi.object().keys({ + // https://tools.ietf.org/html/rfc7662#section-2.2 + active: Joi.boolean().required(), + scope: validators.scope.optional(), + client_id: validators.clientId.optional(), + token_type: Joi.string().equal(['access_token', 'refresh_token']), + exp: Joi.number().optional(), + iat: Joi.number().optional(), + sub: Joi.string().optional(), + iss: Joi.string().optional(), + jti: Joi.string().optional(), + 'fxa-lastUsedAt': Joi.number().optional(), + }), }, handler: async function introspectEndpoint(req) { const tokenTypeHint = req.payload.token_type_hint; diff --git a/packages/fxa-auth-server/lib/routes/oauth/key_data.js b/packages/fxa-auth-server/lib/routes/oauth/key_data.js index 0ab09556e60..32e24655b87 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/key_data.js +++ b/packages/fxa-auth-server/lib/routes/oauth/key_data.js @@ -105,7 +105,7 @@ module.exports = ({ log, oauthDB }) => { client_id: validators.clientId, assertion: validators.assertion.required(), scope: validators.scope.required(), - }).label('KeyData_payload'), + }), }, response: { schema: Joi.object().pattern(/^/, [ @@ -133,7 +133,7 @@ module.exports = ({ log, oauthDB }) => { client_id: validators.clientId.required(), scope: validators.scope.required(), assertion: Joi.forbidden(), - }).label('Oauth.scopedKeyData_payload'), + }), }, response: { schema: Joi.object().pattern( @@ -142,7 +142,7 @@ module.exports = ({ log, oauthDB }) => { identifier: validators.scope.required(), keyRotationSecret: validators.hexString.length(64).required(), keyRotationTimestamp: Joi.number().required(), - }).label('Oauth.scopedKeyData_response') + }) ), }, }, diff --git a/packages/fxa-auth-server/lib/routes/oauth/token.js b/packages/fxa-auth-server/lib/routes/oauth/token.js index 3e0e9e3617e..274578e3a14 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/token.js +++ b/packages/fxa-auth-server/lib/routes/oauth/token.js @@ -364,24 +364,20 @@ module.exports = ({ log, oauthDB, db, mailer, devices }) => { // with FxA OAuth. Sometimes, they will send other parameters that // we don't use, such as `response_type`, or something else. Instead // of giving an error here, we can just ignore them. - payload: PAYLOAD_SCHEMA.options({ stripUnknown: true }).label( - 'Token_payload' - ), + payload: PAYLOAD_SCHEMA.options({ stripUnknown: true }), }, response: { - schema: Joi.object() - .keys({ - access_token: validators.accessToken.required(), - refresh_token: validators.token, - id_token: validators.assertion, - session_token_id: validators.sessionTokenId.optional(), - scope: validators.scope.required(), - token_type: Joi.string().valid('bearer').required(), - expires_in: Joi.number().max(MAX_TTL_S).required(), - auth_at: Joi.number(), - keys_jwe: validators.jwe.optional(), - }) - .label('Token_response'), + schema: Joi.object().keys({ + access_token: validators.accessToken.required(), + refresh_token: validators.token, + id_token: validators.assertion, + session_token_id: validators.sessionTokenId.optional(), + scope: validators.scope.required(), + token_type: Joi.string().valid('bearer').required(), + expires_in: Joi.number().max(MAX_TTL_S).required(), + auth_at: Joi.number(), + keys_jwe: validators.jwe.optional(), + }), }, handler: tokenHandler, }, @@ -427,9 +423,7 @@ module.exports = ({ log, oauthDB, db, mailer, devices }) => { resource: validators.resourceUrl .optional() .description(DESCRIPTION.resource), - }) - .xor('client_secret', 'code_verifier') - .label('Oauth.token_authorizationCode'), + }).xor('client_secret', 'code_verifier'), // refresh token Joi.object({ grant_type: Joi.string().valid('refresh_token').required(), @@ -442,7 +436,7 @@ module.exports = ({ log, oauthDB, db, mailer, devices }) => { ttl: Joi.number().positive().optional(), ppid_seed: validators.ppidSeed.optional(), resource: validators.resourceUrl.optional(), - }).label('Oauth.token_refreshToken'), + }), // credentials Joi.object({ grant_type: Joi.string() @@ -458,7 +452,7 @@ module.exports = ({ log, oauthDB, db, mailer, devices }) => { ttl: Joi.number().positive().optional(), resource: validators.resourceUrl.optional(), assertion: Joi.forbidden(), - }).label('Oauth.token_fxaCredentials') + }) ), }, response: { @@ -485,7 +479,7 @@ module.exports = ({ log, oauthDB, db, mailer, devices }) => { .description(DESCRIPTION.expiresIn), auth_at: Joi.number().required().description(DESCRIPTION.authAt), keys_jwe: validators.jwe.optional(), - }).label('Oauth.token_response'), + }), // refresh token Joi.object({ access_token: validators.accessToken.required(), diff --git a/packages/fxa-auth-server/lib/routes/oauth/verify.js b/packages/fxa-auth-server/lib/routes/oauth/verify.js index 7a1c95fe5db..af279db8a3f 100644 --- a/packages/fxa-auth-server/lib/routes/oauth/verify.js +++ b/packages/fxa-auth-server/lib/routes/oauth/verify.js @@ -17,7 +17,7 @@ module.exports = ({ log }) => ({ validate: { payload: Joi.object({ token: validators.accessToken.required(), - }).label('Verify_payload'), + }), }, response: { schema: Joi.object({ @@ -26,7 +26,7 @@ module.exports = ({ log }) => ({ scope: Joi.array(), generation: Joi.number().min(0), profile_changed_at: Joi.number().min(0), - }).label('Verify_response'), + }), }, handler: async function verify(req) { const info = await token.verify(req.payload.token); diff --git a/packages/fxa-auth-server/lib/routes/password.js b/packages/fxa-auth-server/lib/routes/password.js index baad14e1c8a..4d584d89dae 100644 --- a/packages/fxa-auth-server/lib/routes/password.js +++ b/packages/fxa-auth-server/lib/routes/password.js @@ -46,15 +46,10 @@ module.exports = function ( options: { ...PASSWORD_DOCS.PASSWORD_CHANGE_START_POST, validate: { - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.email), - oldAuthPW: validators.authPW.description(DESCRIPTION.authPW), - }) - .label('Password.changeStart_payload'), + payload: isA.object({ + email: validators.email().required().description(DESCRIPTION.email), + oldAuthPW: validators.authPW.description(DESCRIPTION.authPW), + }), }, }, handler: async function (request) { @@ -142,19 +137,17 @@ module.exports = function ( query: isA.object({ keys: isA.boolean().optional().description(DESCRIPTION.queryKeys), }), - payload: isA - .object({ - authPW: validators.authPW.description(DESCRIPTION.authPW), - wrapKb: validators.wrapKb.description(DESCRIPTION.wrapKb), - sessionToken: isA - .string() - .min(64) - .max(64) - .regex(HEX_STRING) - .optional() - .description(DESCRIPTION.sessionToken), - }) - .label('Password.changeFinish_payload'), + payload: isA.object({ + authPW: validators.authPW.description(DESCRIPTION.authPW), + wrapKb: validators.wrapKb.description(DESCRIPTION.wrapKb), + sessionToken: isA + .string() + .min(64) + .max(64) + .regex(HEX_STRING) + .optional() + .description(DESCRIPTION.sessionToken), + }), }, }, handler: async function (request) { @@ -436,35 +429,31 @@ module.exports = function ( service: validators.service.description(DESCRIPTION.serviceRP), keys: isA.boolean().optional(), }), - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.emailRecovery), - service: validators.service.description(DESCRIPTION.serviceRP), - redirectTo: validators - .redirectTo(redirectDomain) - .optional() - .description(DESCRIPTION.redirectTo), - resume: isA - .string() - .max(2048) - .optional() - .description(DESCRIPTION.resume), - metricsContext: METRICS_CONTEXT_SCHEMA, - }) - .label('Password.forgotSend_payload'), + payload: isA.object({ + email: validators + .email() + .required() + .description(DESCRIPTION.emailRecovery), + service: validators.service.description(DESCRIPTION.serviceRP), + redirectTo: validators + .redirectTo(redirectDomain) + .optional() + .description(DESCRIPTION.redirectTo), + resume: isA + .string() + .max(2048) + .optional() + .description(DESCRIPTION.resume), + metricsContext: METRICS_CONTEXT_SCHEMA, + }), }, response: { - schema: isA - .object({ - passwordForgotToken: isA.string(), - ttl: isA.number(), - codeLength: isA.number(), - tries: isA.number(), - }) - .label('Password.forgotSend_response'), + schema: isA.object({ + passwordForgotToken: isA.string(), + ttl: isA.number(), + codeLength: isA.number(), + tries: isA.number(), + }), }, }, handler: async function (request) { @@ -567,34 +556,30 @@ module.exports = function ( query: isA.object({ service: validators.service.description(DESCRIPTION.serviceRP), }), - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.emailRecovery), - service: validators.service.description(DESCRIPTION.serviceRP), - redirectTo: validators - .redirectTo(redirectDomain) - .optional() - .description(DESCRIPTION.redirectTo), - resume: isA - .string() - .max(2048) - .optional() - .description(DESCRIPTION.resume), - }) - .label('Password.forgotResend_payload'), + payload: isA.object({ + email: validators + .email() + .required() + .description(DESCRIPTION.emailRecovery), + service: validators.service.description(DESCRIPTION.serviceRP), + redirectTo: validators + .redirectTo(redirectDomain) + .optional() + .description(DESCRIPTION.redirectTo), + resume: isA + .string() + .max(2048) + .optional() + .description(DESCRIPTION.resume), + }), }, response: { - schema: isA - .object({ - passwordForgotToken: isA.string(), - ttl: isA.number(), - codeLength: isA.number(), - tries: isA.number(), - }) - .label('Password.forgotResend_response'), + schema: isA.object({ + passwordForgotToken: isA.string(), + ttl: isA.number(), + codeLength: isA.number(), + tries: isA.number(), + }), }, }, handler: async function (request) { @@ -673,25 +658,21 @@ module.exports = function ( payload: 'required', }, validate: { - payload: isA - .object({ - code: isA - .string() - .min(32) - .max(32) - .regex(HEX_STRING) - .required() - .description(DESCRIPTION.codeRecovery), - accountResetWithRecoveryKey: isA.boolean().optional(), - }) - .label('Password.forgotVerify_payload'), + payload: isA.object({ + code: isA + .string() + .min(32) + .max(32) + .regex(HEX_STRING) + .required() + .description(DESCRIPTION.codeRecovery), + accountResetWithRecoveryKey: isA.boolean().optional(), + }), }, response: { - schema: isA - .object({ - accountResetToken: isA.string(), - }) - .label('Password.forgotVerify_response'), + schema: isA.object({ + accountResetToken: isA.string(), + }), }, }, handler: async function (request) { @@ -831,12 +812,10 @@ module.exports = function ( strategy: 'passwordForgotToken', }, response: { - schema: isA - .object({ - tries: isA.number(), - ttl: isA.number(), - }) - .label('Password.forgotStatus_response'), + schema: isA.object({ + tries: isA.number(), + ttl: isA.number(), + }), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/recovery-codes.js b/packages/fxa-auth-server/lib/routes/recovery-codes.js index e416110b313..3b48cee5c0b 100644 --- a/packages/fxa-auth-server/lib/routes/recovery-codes.js +++ b/packages/fxa-auth-server/lib/routes/recovery-codes.js @@ -17,10 +17,10 @@ module.exports = (log, db, config, customs, mailer) => { const RECOVERY_CODE_COUNT = (codeConfig && codeConfig.count) || 8; // Validate recovery codes - const recoveryCodesSchema = validators - .recoveryCodes(RECOVERY_CODE_COUNT, RECOVERY_CODE_SANE_MAX_LENGTH) - .label('replaceRecoveryCodes_response'); - + const recoveryCodesSchema = validators.recoveryCodes( + RECOVERY_CODE_COUNT, + RECOVERY_CODE_SANE_MAX_LENGTH + ); return [ { method: 'GET', @@ -84,11 +84,9 @@ module.exports = (log, db, config, customs, mailer) => { payload: recoveryCodesSchema, }, response: { - schema: isA - .object({ - success: isA.boolean(), - }) - .label('success'), + schema: isA.object({ + success: isA.boolean(), + }), }, }, async handler(request) { @@ -138,23 +136,19 @@ module.exports = (log, db, config, customs, mailer) => { payload: 'required', }, validate: { - payload: isA - .object({ - // Validation here is done with BASE_36 superset to be backwards compatible... - // Ideally all recovery codes are Crockford Base32. - code: validators.recoveryCode( - RECOVERY_CODE_SANE_MAX_LENGTH, - validators.BASE_36 - ), - }) - .label('session.verify.recoveryCode_payload'), + payload: isA.object({ + // Validation here is done with BASE_36 superset to be backwards compatible... + // Ideally all recovery codes are Crockford Base32. + code: validators.recoveryCode( + RECOVERY_CODE_SANE_MAX_LENGTH, + validators.BASE_36 + ), + }), }, response: { - schema: isA - .object({ - remaining: isA.number(), - }) - .label('session.verify.recoveryCode_response'), + schema: isA.object({ + remaining: isA.number(), + }), }, }, async handler(request) { diff --git a/packages/fxa-auth-server/lib/routes/recovery-key.js b/packages/fxa-auth-server/lib/routes/recovery-key.js index d61d0554bca..952bfd0182e 100644 --- a/packages/fxa-auth-server/lib/routes/recovery-key.js +++ b/packages/fxa-auth-server/lib/routes/recovery-key.js @@ -24,17 +24,15 @@ module.exports = (log, db, Password, verifierVersion, customs, mailer) => { payload: 'required', }, validate: { - payload: isA - .object({ - recoveryKeyId: validators.recoveryKeyId.description( - DESCRIPTION.recoveryKeyId - ), - recoveryData: validators.recoveryData.description( - DESCRIPTION.recoveryData - ), - enabled: isA.boolean().default(true), - }) - .label('createRecoveryKey_payload'), + payload: isA.object({ + recoveryKeyId: validators.recoveryKeyId.description( + DESCRIPTION.recoveryKeyId + ), + recoveryData: validators.recoveryData.description( + DESCRIPTION.recoveryData + ), + enabled: isA.boolean().default(true), + }), }, }, handler: async function (request) { @@ -175,11 +173,9 @@ module.exports = (log, db, Password, verifierVersion, customs, mailer) => { strategy: 'accountResetToken', }, validate: { - params: isA - .object({ - recoveryKeyId: validators.recoveryKeyId, - }) - .label('getRecoveryKey_params'), + params: isA.object({ + recoveryKeyId: validators.recoveryKeyId, + }), }, }, handler: async function (request) { @@ -205,18 +201,14 @@ module.exports = (log, db, Password, verifierVersion, customs, mailer) => { strategy: 'sessionToken', }, validate: { - payload: isA - .object({ - email: validators.email().optional(), - }) - .label('recoveryKeysExists_payload'), + payload: isA.object({ + email: validators.email().optional(), + }), }, response: { - schema: isA - .object({ - exists: isA.boolean().required(), - }) - .label('recoveryKeyExists_response'), + schema: isA.object({ + exists: isA.boolean().required(), + }), }, }, async handler(request) { diff --git a/packages/fxa-auth-server/lib/routes/session.js b/packages/fxa-auth-server/lib/routes/session.js index 8047a688703..78a3eb9a27a 100644 --- a/packages/fxa-auth-server/lib/routes/session.js +++ b/packages/fxa-auth-server/lib/routes/session.js @@ -57,8 +57,7 @@ module.exports = function ( .optional() .description(DESCRIPTION.customSessionToken), }) - .allow(null) - .label('Session.destroy_payload'), + .allow(null), }, }, handler: async function (request) { @@ -112,35 +111,31 @@ module.exports = function ( service: validators.service, verificationMethod: validators.verificationMethod.optional(), }), - payload: isA - .object({ - email: validators.email().required(), - authPW: validators.authPW, - service: validators.service, - redirectTo: validators - .redirectTo(config.smtp.redirectDomain) - .optional(), - resume: isA.string().optional(), - reason: isA.string().max(16).optional(), - unblockCode: signinUtils.validators.UNBLOCK_CODE, - metricsContext: METRICS_CONTEXT_SCHEMA, - originalLoginEmail: validators.email().optional(), - verificationMethod: validators.verificationMethod.optional(), - }) - .label('Session.reauth_payload'), + payload: isA.object({ + email: validators.email().required(), + authPW: validators.authPW, + service: validators.service, + redirectTo: validators + .redirectTo(config.smtp.redirectDomain) + .optional(), + resume: isA.string().optional(), + reason: isA.string().max(16).optional(), + unblockCode: signinUtils.validators.UNBLOCK_CODE, + metricsContext: METRICS_CONTEXT_SCHEMA, + originalLoginEmail: validators.email().optional(), + verificationMethod: validators.verificationMethod.optional(), + }), }, response: { - schema: isA - .object({ - uid: isA.string().regex(HEX_STRING).required(), - keyFetchToken: isA.string().regex(HEX_STRING).optional(), - verificationMethod: isA.string().optional(), - verificationReason: isA.string().optional(), - verified: isA.boolean().required(), - authAt: isA.number().integer(), - metricsEnabled: isA.boolean().required(), - }) - .label('Session.reauth_response'), + schema: isA.object({ + uid: isA.string().regex(HEX_STRING).required(), + keyFetchToken: isA.string().regex(HEX_STRING).optional(), + verificationMethod: isA.string().optional(), + verificationReason: isA.string().optional(), + verified: isA.boolean().required(), + authAt: isA.number().integer(), + metricsEnabled: isA.boolean().required(), + }), }, }, handler: async function (request) { @@ -257,12 +252,10 @@ module.exports = function ( strategy: 'sessionToken', }, response: { - schema: isA - .object({ - state: isA.string().required(), - uid: isA.string().regex(HEX_STRING).required(), - }) - .label('Session.status_response'), + schema: isA.object({ + state: isA.string().required(), + uid: isA.string().regex(HEX_STRING).required(), + }), }, }, handler: async function (request) { @@ -284,11 +277,9 @@ module.exports = function ( payload: 'required', }, validate: { - payload: isA - .object({ - reason: isA.string().max(16).optional(), - }) - .label('Session.duplicate_payload'), + payload: isA.object({ + reason: isA.string().max(16).optional(), + }), }, }, handler: async function (request) { @@ -352,16 +343,14 @@ module.exports = function ( payload: 'required', }, validate: { - payload: isA - .object({ - code: validators.DIGITS, - service: validators.service, - scopes: validators.scopes, - // The `marketingOptIn` is safe to remove after train-167+ - marketingOptIn: isA.boolean().optional(), - newsletters: validators.newsletters, - }) - .label('Session.verifyCode_payload'), + payload: isA.object({ + code: validators.DIGITS, + service: validators.service, + scopes: validators.scopes, + // The `marketingOptIn` is safe to remove after train-167+ + marketingOptIn: isA.boolean().optional(), + newsletters: validators.newsletters, + }), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/sign.js b/packages/fxa-auth-server/lib/routes/sign.js index 8ddbe15e410..bfa964d43fe 100644 --- a/packages/fxa-auth-server/lib/routes/sign.js +++ b/packages/fxa-auth-server/lib/routes/sign.js @@ -27,30 +27,28 @@ module.exports = (log, signer, db, domain, devices) => { query: isA.object({ service: validators.service.optional(), }), - payload: isA - .object({ - publicKey: isA - .object({ - algorithm: isA.string().valid('RS', 'DS').required(), - n: isA.string(), - e: isA.string(), - y: isA.string(), - p: isA.string(), - q: isA.string(), - g: isA.string(), - version: isA.string(), - }) - .required() - .description(DESCRIPTION.publicKey), - duration: isA - .number() - .integer() - .min(0) - .max(24 * HOUR) - .required() - .description(DESCRIPTION.duration), - }) - .label('Sign.cert_payload'), + payload: isA.object({ + publicKey: isA + .object({ + algorithm: isA.string().valid('RS', 'DS').required(), + n: isA.string(), + e: isA.string(), + y: isA.string(), + p: isA.string(), + q: isA.string(), + g: isA.string(), + version: isA.string(), + }) + .required() + .description(DESCRIPTION.publicKey), + duration: isA + .number() + .integer() + .min(0) + .max(24 * HOUR) + .required() + .description(DESCRIPTION.duration), + }), }, }, handler: async function certificateSign(request) { diff --git a/packages/fxa-auth-server/lib/routes/subscriptions/stripe.ts b/packages/fxa-auth-server/lib/routes/subscriptions/stripe.ts index 258e18bb226..18df1aa9e90 100644 --- a/packages/fxa-auth-server/lib/routes/subscriptions/stripe.ts +++ b/packages/fxa-auth-server/lib/routes/subscriptions/stripe.ts @@ -790,18 +790,12 @@ export const stripeRoutes = ( strategy: 'subscriptionsSecret', }, response: { - schema: isA - .array() - .items( - isA - .object() - .keys({ - clientId: isA.string(), - capabilities: isA.array().items(isA.string()), - }) - .label('subscriptionClient') - ) - .label('subscriptionsClient_response') as any, + schema: isA.array().items( + isA.object().keys({ + clientId: isA.string(), + capabilities: isA.array().items(isA.string()), + }) + ) as any, }, }, handler: (request: AuthRequest) => stripeHandler.getClients(request), @@ -814,7 +808,6 @@ export const stripeRoutes = ( response: { schema: isA .array() - .label('OauthSubscriptionsPlans') .items(validators.subscriptionsPlanValidator) as any, }, }, @@ -832,7 +825,6 @@ export const stripeRoutes = ( response: { schema: isA .array() - .label('OauthSubscriptionsActive') .items(validators.activeSubscriptionValidator) as any, }, }, @@ -918,9 +910,7 @@ export const stripeRoutes = ( ...SUBSCRIPTIONS_DOCS.OAUTH_SUBSCRIPTIONS_INVOICE_PREVIEW_POST, auth: false, response: { - schema: invoiceDTO.firstInvoicePreviewSchema.label( - 'OauthSubscriptionsInvoicePreview_response' - ) as any, + schema: invoiceDTO.firstInvoicePreviewSchema as any, }, validate: { payload: { @@ -941,9 +931,7 @@ export const stripeRoutes = ( strategy: 'oauthToken', }, response: { - schema: invoiceDTO.subsequentInvoicePreviewsSchema.label( - 'OauthSubscriptionsInvoicePreviewSubsequent_response' - ) as any, + schema: invoiceDTO.subsequentInvoicePreviewsSchema as any, }, }, handler: (request: AuthRequest) => @@ -956,9 +944,7 @@ export const stripeRoutes = ( ...SUBSCRIPTIONS_DOCS.OAUTH_SUBSCRIPTIONS_COUPON_POST, auth: false, response: { - schema: couponDTO.couponDetailsSchema.label( - 'OauthSubscriptionsCoupon_response' - ) as any, + schema: couponDTO.couponDetailsSchema as any, }, validate: { payload: { @@ -1038,11 +1024,9 @@ export const stripeRoutes = ( options: { ...SUBSCRIPTIONS_DOCS.OAUTH_SUBSCRIPTIONS_PRODUCTNAME_GET, response: { - schema: isA - .object({ - product_name: isA.string().required(), - }) - .label('Product Name') as any, + schema: isA.object({ + product_name: isA.string().required(), + }) as any, }, validate: { query: { diff --git a/packages/fxa-auth-server/lib/routes/subscriptions/support.ts b/packages/fxa-auth-server/lib/routes/subscriptions/support.ts index 6806791d39f..971c9139310 100644 --- a/packages/fxa-auth-server/lib/routes/subscriptions/support.ts +++ b/packages/fxa-auth-server/lib/routes/subscriptions/support.ts @@ -63,31 +63,25 @@ export const supportRoutes = ( maxBytes: config.support.ticketPayloadLimit, }, validate: { - payload: isA - .object() - .keys({ - email: email().optional(), - productName: isA.string().required(), - productPlatform: isA.string().optional(), - productVersion: isA.string().optional(), - topic: isA.string().required(), - app: isA.string().allow('').optional(), - subject: isA.string().allow('').optional(), - message: isA.string().required(), - product: isA.string().allow('').optional(), - category: isA.string().allow('').optional(), - }) - .label('SupportTicket_payload') as any, + payload: isA.object().keys({ + email: email().optional(), + productName: isA.string().required(), + productPlatform: isA.string().optional(), + productVersion: isA.string().optional(), + topic: isA.string().required(), + app: isA.string().allow('').optional(), + subject: isA.string().allow('').optional(), + message: isA.string().required(), + product: isA.string().allow('').optional(), + category: isA.string().allow('').optional(), + }) as any, }, response: { - schema: isA - .object() - .keys({ - success: isA.bool().required(), - ticket: isA.number().optional(), - error: isA.string().optional(), - }) - .label('SupportTicket_response') as any, + schema: isA.object().keys({ + success: isA.bool().required(), + ticket: isA.number().optional(), + error: isA.string().optional(), + }) as any, }, }, handler: async function ( diff --git a/packages/fxa-auth-server/lib/routes/totp.js b/packages/fxa-auth-server/lib/routes/totp.js index b565e0512dc..c8d3995396b 100644 --- a/packages/fxa-auth-server/lib/routes/totp.js +++ b/packages/fxa-auth-server/lib/routes/totp.js @@ -39,20 +39,16 @@ module.exports = (log, db, mailer, customs, config) => { payload: 'required', }, validate: { - payload: isA - .object({ - metricsContext: METRICS_CONTEXT_SCHEMA, - }) - .label('totp.create_payload'), + payload: isA.object({ + metricsContext: METRICS_CONTEXT_SCHEMA, + }), }, response: { - schema: isA - .object({ - qrCodeUrl: isA.string().required(), - secret: isA.string().required(), - recoveryCodes: isA.array().items(isA.string()).required(), - }) - .label('totp.create_response'), + schema: isA.object({ + qrCodeUrl: isA.string().required(), + secret: isA.string().required(), + recoveryCodes: isA.array().items(isA.string()).required(), + }), }, }, handler: async function (request) { @@ -202,12 +198,10 @@ module.exports = (log, db, mailer, customs, config) => { strategy: 'sessionToken', }, response: { - schema: isA - .object({ - exists: isA.boolean(), - verified: isA.boolean(), - }) - .label('totp.exists_response'), + schema: isA.object({ + exists: isA.boolean(), + verified: isA.boolean(), + }), }, }, handler: async function (request) { @@ -243,24 +237,20 @@ module.exports = (log, db, mailer, customs, config) => { payload: 'required', }, validate: { - payload: isA - .object({ - code: isA - .string() - .max(32) - .regex(validators.DIGITS) - .required() - .description(DESCRIPTION.codeTotp), - service: validators.service, - }) - .label('session.verify.totp_payload'), + payload: isA.object({ + code: isA + .string() + .max(32) + .regex(validators.DIGITS) + .required() + .description(DESCRIPTION.codeTotp), + service: validators.service, + }), }, response: { - schema: isA - .object({ - success: isA.boolean().required(), - }) - .label('session.verify.totp_response'), + schema: isA.object({ + success: isA.boolean().required(), + }), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/unblock-codes.js b/packages/fxa-auth-server/lib/routes/unblock-codes.js index 8864ffafd17..ac83a72824a 100644 --- a/packages/fxa-auth-server/lib/routes/unblock-codes.js +++ b/packages/fxa-auth-server/lib/routes/unblock-codes.js @@ -24,15 +24,10 @@ module.exports = (log, db, mailer, config, customs) => { options: { ...UNBLOCK_CODES_DOCS.ACCOUNT_LOGIN_SEND_UNBLOCK_CODE_POST, validate: { - payload: isA - .object({ - email: validators - .email() - .required() - .description(DESCRIPTION.email), - metricsContext: METRICS_CONTEXT_SCHEMA, - }) - .label('Account.SendUnblockCode_payload'), + payload: isA.object({ + email: validators.email().required().description(DESCRIPTION.email), + metricsContext: METRICS_CONTEXT_SCHEMA, + }), }, }, handler: async function (request) { @@ -87,22 +82,20 @@ module.exports = (log, db, mailer, config, customs) => { options: { ...UNBLOCK_CODES_DOCS.ACCOUNT_LOGIN_REJECT_UNBLOCK_CODE_POST, validate: { - payload: isA - .object({ - uid: isA - .string() - .max(32) - .regex(HEX_STRING) - .required() - .description(DESCRIPTION.uid), - unblockCode: isA - .string() - .regex(BASE_36) - .length(unblockCodeLen) - .required() - .description(DESCRIPTION.unblockCode), - }) - .label('Account.RejectUnblockCode_payload'), + payload: isA.object({ + uid: isA + .string() + .max(32) + .regex(HEX_STRING) + .required() + .description(DESCRIPTION.uid), + unblockCode: isA + .string() + .regex(BASE_36) + .length(unblockCodeLen) + .required() + .description(DESCRIPTION.unblockCode), + }), }, }, handler: async function (request) { diff --git a/packages/fxa-auth-server/lib/routes/validators.js b/packages/fxa-auth-server/lib/routes/validators.js index dd7a8c75821..2258b9dbf7a 100644 --- a/packages/fxa-auth-server/lib/routes/validators.js +++ b/packages/fxa-auth-server/lib/routes/validators.js @@ -322,15 +322,13 @@ module.exports.subscriptionPaymentCountryCode = isA .allow(null); // This is fxa-auth-db-mysql's perspective on an active subscription -module.exports.activeSubscriptionValidator = isA - .object({ - uid: isA.string().required(), - subscriptionId: module.exports.subscriptionsSubscriptionId.required(), - productId: module.exports.subscriptionsProductId.required(), - createdAt: isA.number().required(), - cancelledAt: isA.alternatives(isA.number(), isA.any().allow(null)), - }) - .label('Active subscription'); +module.exports.activeSubscriptionValidator = isA.object({ + uid: isA.string().required(), + subscriptionId: module.exports.subscriptionsSubscriptionId.required(), + productId: module.exports.subscriptionsProductId.required(), + createdAt: isA.number().required(), + cancelledAt: isA.alternatives(isA.number(), isA.any().allow(null)), +}); module.exports.subscriptionsSetupIntent = isA .object({ @@ -376,65 +374,57 @@ module.exports.subscriptionsInvoicePIExpandedValidator = isA }) .unknown(true); -module.exports.subscriptionsSubscriptionValidator = isA - .object({ - _subscription_type: MozillaSubscriptionTypes.WEB, - created: isA.number().required(), - current_period_end: isA.number().required(), - current_period_start: isA.number().required(), - cancel_at_period_end: isA.boolean().required(), - end_at: isA.alternatives(isA.number(), isA.any().allow(null)), - failure_code: isA.string().optional(), - failure_message: isA.string().optional(), - latest_invoice: isA.string().required(), - plan_id: module.exports.subscriptionsPlanId.required(), - product_id: module.exports.subscriptionsProductId.required(), - product_name: isA.string().required(), - status: isA.string().required(), - subscription_id: module.exports.subscriptionsSubscriptionId.required(), - promotion_code: isA.string().optional().allow(null), - promotion_duration: isA.string().optional().allow(null), - promotion_end: isA.number().optional().allow(null), - }) - .label('Subscription'); +module.exports.subscriptionsSubscriptionValidator = isA.object({ + _subscription_type: MozillaSubscriptionTypes.WEB, + created: isA.number().required(), + current_period_end: isA.number().required(), + current_period_start: isA.number().required(), + cancel_at_period_end: isA.boolean().required(), + end_at: isA.alternatives(isA.number(), isA.any().allow(null)), + failure_code: isA.string().optional(), + failure_message: isA.string().optional(), + latest_invoice: isA.string().required(), + plan_id: module.exports.subscriptionsPlanId.required(), + product_id: module.exports.subscriptionsProductId.required(), + product_name: isA.string().required(), + status: isA.string().required(), + subscription_id: module.exports.subscriptionsSubscriptionId.required(), + promotion_code: isA.string().optional().allow(null), + promotion_duration: isA.string().optional().allow(null), + promotion_end: isA.number().optional().allow(null), +}); // This is support-panel's perspective on a subscription -module.exports.subscriptionsWebSubscriptionSupportValidator = isA - .object({ - created: isA.number().required(), - current_period_end: isA.number().required(), - current_period_start: isA.number().required(), - plan_changed: isA.alternatives(isA.number(), isA.any().allow(null)), - previous_product: isA.alternatives(isA.string(), isA.any().allow(null)), - product_name: isA.string().required(), - status: isA.string().required(), - subscription_id: module.exports.subscriptionsSubscriptionId.required(), - }) - .label('Web Subscription Support'); +module.exports.subscriptionsWebSubscriptionSupportValidator = isA.object({ + created: isA.number().required(), + current_period_end: isA.number().required(), + current_period_start: isA.number().required(), + plan_changed: isA.alternatives(isA.number(), isA.any().allow(null)), + previous_product: isA.alternatives(isA.string(), isA.any().allow(null)), + product_name: isA.string().required(), + status: isA.string().required(), + subscription_id: module.exports.subscriptionsSubscriptionId.required(), +}); -module.exports.subscriptionsPlaySubscriptionSupportValidator = isA - .object({ - _subscription_type: MozillaSubscriptionTypes.IAP_GOOGLE, - auto_renewing: isA.bool().required(), - cancel_reason: isA.number().optional(), - expiry_time_millis: isA.number().required(), - package_name: isA.string().optional(), - sku: isA.string().optional(), - product_id: isA.string().optional(), - product_name: isA.string().required(), - }) - .label('Play Subscription Support'); +module.exports.subscriptionsPlaySubscriptionSupportValidator = isA.object({ + _subscription_type: MozillaSubscriptionTypes.IAP_GOOGLE, + auto_renewing: isA.bool().required(), + cancel_reason: isA.number().optional(), + expiry_time_millis: isA.number().required(), + package_name: isA.string().optional(), + sku: isA.string().optional(), + product_id: isA.string().optional(), + product_name: isA.string().required(), +}); -module.exports.subscriptionsSubscriptionSupportValidator = isA - .object({ - [MozillaSubscriptionTypes.WEB]: isA - .array() - .items(module.exports.subscriptionsWebSubscriptionSupportValidator), - [MozillaSubscriptionTypes.IAP_GOOGLE]: isA - .array() - .items(module.exports.subscriptionsPlaySubscriptionSupportValidator), - }) - .label('OauthSupportPanelSubscriptions_responses'); +module.exports.subscriptionsSubscriptionSupportValidator = isA.object({ + [MozillaSubscriptionTypes.WEB]: isA + .array() + .items(module.exports.subscriptionsWebSubscriptionSupportValidator), + [MozillaSubscriptionTypes.IAP_GOOGLE]: isA + .array() + .items(module.exports.subscriptionsPlaySubscriptionSupportValidator), +}); module.exports.subscriptionsSubscriptionListValidator = isA.object({ subscriptions: isA @@ -523,49 +513,45 @@ module.exports.subscriptionProductMetadataValidator = { }, }; -module.exports.subscriptionsPlanValidator = isA - .object({ - plan_id: module.exports.subscriptionsPlanId.required(), - plan_metadata: module.exports.subscriptionPlanMetadataValidator.optional(), - product_id: module.exports.subscriptionsProductId.required(), - product_name: isA.string().required(), - plan_name: isA.string().allow('').optional(), - product_metadata: - module.exports.subscriptionProductMetadataBaseValidator.optional(), - interval: isA.string().required(), - interval_count: isA.number().required(), - amount: isA.number().required(), - currency: isA.string().required(), - configuration: minimalConfigSchema - .keys(productConfigJoiKeys) - .keys(planConfigJoiKeys) - .optional() - .allow(null), - }) - .label('Subscriptions Plan'); +module.exports.subscriptionsPlanValidator = isA.object({ + plan_id: module.exports.subscriptionsPlanId.required(), + plan_metadata: module.exports.subscriptionPlanMetadataValidator.optional(), + product_id: module.exports.subscriptionsProductId.required(), + product_name: isA.string().required(), + plan_name: isA.string().allow('').optional(), + product_metadata: + module.exports.subscriptionProductMetadataBaseValidator.optional(), + interval: isA.string().required(), + interval_count: isA.number().required(), + amount: isA.number().required(), + currency: isA.string().required(), + configuration: minimalConfigSchema + .keys(productConfigJoiKeys) + .keys(planConfigJoiKeys) + .optional() + .allow(null), +}); -module.exports.subscriptionsCustomerValidator = isA - .object({ - customerId: isA.string().optional(), - billing_name: isA - .alternatives(isA.string(), isA.any().allow(null)) - .optional(), - exp_month: isA.number().optional(), - exp_year: isA.number().optional(), - last4: isA.string().optional(), - payment_provider: isA.string().optional(), - payment_type: isA.string().optional(), - paypal_payment_error: isA.string().optional(), - brand: isA.string().optional(), - billing_agreement_id: isA - .alternatives(isA.string(), isA.any().allow(null)) - .optional(), - subscriptions: isA - .array() - .items(module.exports.subscriptionsSubscriptionValidator) - .optional(), - }) - .label('Subscriptions Customer'); +module.exports.subscriptionsCustomerValidator = isA.object({ + customerId: isA.string().optional(), + billing_name: isA + .alternatives(isA.string(), isA.any().allow(null)) + .optional(), + exp_month: isA.number().optional(), + exp_year: isA.number().optional(), + last4: isA.string().optional(), + payment_provider: isA.string().optional(), + payment_type: isA.string().optional(), + paypal_payment_error: isA.string().optional(), + brand: isA.string().optional(), + billing_agreement_id: isA + .alternatives(isA.string(), isA.any().allow(null)) + .optional(), + subscriptions: isA + .array() + .items(module.exports.subscriptionsSubscriptionValidator) + .optional(), +}); module.exports.subscriptionsStripeIntentValidator = isA .object({ @@ -583,8 +569,7 @@ module.exports.subscriptionsStripeIntentValidator = isA }), status: isA.string().required(), }) - .unknown(true) - .label('Subscriptions Stripe Intent'); + .unknown(true); module.exports.subscriptionsStripeSourceValidator = isA .object({ @@ -650,7 +635,6 @@ module.exports.subscriptionsStripeSubscriptionValidator = isA .optional(), status: isA.string().required(), }) - .label('Stripe_subscription') .unknown(true); module.exports.subscriptionsGooglePlaySubscriptionValidator = isA.object({ @@ -709,8 +693,7 @@ module.exports.subscriptionsMozillaSubscriptionsValidator = isA ) .required(), }) - .unknown(true) - .label('mozSubscriptionsValidator_response'); + .unknown(true); module.exports.ppidSeed = isA.number().integer().min(0).max(1024);