Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDK-1715] Configuration and API updates #109

Merged
merged 11 commits into from
Jul 9, 2020
31 changes: 0 additions & 31 deletions lib/ResponseMode.js

This file was deleted.

39 changes: 18 additions & 21 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,30 @@ const paramsSchema = Joi.object({
auth0Logout: Joi.boolean().optional().default(false),
authorizationParams: Joi.object({
response_type: Joi.string().optional().valid('id_token', 'code id_token', 'code').default('id_token'),
scope: Joi.string().optional().default('openid profile email'),
response_mode: Joi.alternatives([
Joi.string().optional(),
Joi.allow(null).optional()
]).default((parent) => parent.response_type.includes('token') ? 'form_post' : undefined),
scope: Joi.string().optional().pattern(/\bopenid\b/, 'contains openid').default('openid profile email'),
response_mode: Joi.string().optional().when('response_type', {
is: 'code',
then: Joi.valid('query', 'form_post'),
otherwise: Joi.valid('form_post').default('form_post')
}),
}).optional().unknown(true).default(),
baseURL: Joi.string().uri().required(),
clientID: Joi.string().required(),
clientSecret: Joi.string().when(
Joi.ref('authorizationParams.response_type', { adjust: (value) => value && value.split(' ').includes('code') }),
Joi.ref('authorizationParams.response_type', { adjust: (value) => value && value.includes('code') }),
{
is: true,
then: Joi.string().required().messages({
'any.required': '"clientSecret" is required for response_type code'
}),
otherwise: Joi.when(
Joi.ref('idTokenSigningAlg', { adjust: (value) => value && value.substring(0, 2) === 'HS' }),
{
is: true,
then: Joi.string().required().messages({
'any.required': '"clientSecret" is required for ID tokens with HS algorithms'
})
}
)
'any.required': '"clientSecret" is required for a response_type that includes code'
})
}
).when(
Joi.ref('idTokenSigningAlg', { adjust: (value) => value && value.startsWith('HS') }),
{
is: true,
then: Joi.string().required().messages({
'any.required': '"clientSecret" is required for ID tokens with HS algorithms'
adamjmcgrath marked this conversation as resolved.
Show resolved Hide resolved
})
}
),
clockTolerance: Joi.number().optional().default(60),
Expand All @@ -84,10 +84,7 @@ const paramsSchema = Joi.object({
identityClaimFilter: Joi.array().optional().default(['aud', 'iss', 'iat', 'exp', 'nbf', 'nonce', 'azp', 'auth_time', 's_hash', 'at_hash', 'c_hash']),
idpLogout: Joi.boolean().optional().default((parent) => parent.auth0Logout || false),
idTokenSigningAlg: Joi.string().not('none').optional().default('RS256'),
issuerBaseURL: Joi.alternatives([
Joi.string().uri(),
Joi.string().hostname()
]).required(),
issuerBaseURL: Joi.string().uri().required(),
legacySameSiteCookie: Joi.boolean().optional().default(true),
authRequired: Joi.boolean().optional().default(true),
routes: Joi.object({
Expand Down
7 changes: 5 additions & 2 deletions lib/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const url = require('url');
const urlJoin = require('url-join');
const { TokenSet } = require('openid-client');
const clone = require('clone');
const { strict: assert } = require('assert');


const debug = require('./debug');
const { get: getClient } = require('./client');
Expand Down Expand Up @@ -162,14 +164,15 @@ class ResponseContext {
} : undefined)
};

// TODO: validate response_type / response_mode?
assert(/\bopenid\b/.test(authParams.scope), 'scope should contain "openid"');

// TODO: hook here

if (authParams.max_age) {
transient.store('max_age', req, res, { ...transientOpts, value: authParams.max_age });
}

// TODO: check openid is in the scope here

const authorizationUrl = client.authorizationUrl(authParams);
res.redirect(authorizationUrl);
} catch (err) {
Expand Down
17 changes: 17 additions & 0 deletions test/auth.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,23 @@ describe('auth', () => {
assert.equal(decodedState.returnTo, 'https://example.org/custom-redirect');
});

it('should not allow removing openid from scope', async function () {
const router = auth({ ...defaultConfig, routes: { login: false } });
router.get('/login', (req, res) => {
res.oidc.login({
authorizationParams: {
scope: 'email'
}
});
});
server = await createServer(router);

const cookieJar = request.jar();
const res = await request.get('/login', { cookieJar, baseUrl, json: true, followRedirect: false });
assert.equal(res.statusCode, 500);
assert.equal(res.body.err.message, 'scope should contain "openid"');
});

it('should use a custom state builder', async () => {
server = await createServer(auth({
...defaultConfig,
Expand Down
Loading