refactor: improve code structure

This commit is contained in:
Marcell Fülöp 2023-02-24 16:30:45 +00:00
parent 8350271e6f
commit bc0b466a8e

View File

@ -29,36 +29,13 @@ router
* Retrieve all users * Retrieve all users
*/ */
.get(jwtdecode(), async (req, res, next) => { .get(jwtdecode(), async (req, res, next) => {
console.log("oidc init >>>", res.locals.access, oidc); console.log("oidc: init flow");
settingModel settingModel
.query() .query()
.where({id: 'oidc-config'}) .where({id: 'oidc-config'})
.first() .first()
.then( async row => { .then( row => getInitParams(req, row))
console.log('oidc init > config > ', row); .then( params => redirectToAuthorizationURL(res, params));
let issuer = await oidc.Issuer.discover(row.meta.issuerURL);
let client = new issuer.Client({
client_id: row.meta.clientID,
client_secret: row.meta.clientSecret,
redirect_uris: [row.meta.redirectURL],
response_types: ['code'],
})
let state = crypto.randomUUID();
let nonce = crypto.randomUUID();
let url = client.authorizationUrl({
scope: 'openid email profile',
resource: 'http://rye.local:2081/api/oidc/callback',
state,
nonce,
})
console.log('oidc init > url > ', state, nonce, url);
res.cookie("npm_oidc", state + '--' + nonce);
res.redirect(url);
});
}); });
@ -80,23 +57,60 @@ router
* Retrieve a specific user * Retrieve a specific user
*/ */
.get(jwtdecode(), async (req, res, next) => { .get(jwtdecode(), async (req, res, next) => {
console.log("oidc callback >>>"); console.log("oidc: callback");
settingModel settingModel
.query() .query()
.where({id: 'oidc-config'}) .where({id: 'oidc-config'})
.first() .first()
.then( async row => { .then( settings => validateCallback(req, settings))
console.log('oidc callback > config > ', row); .then( token => redirectWithJwtToken(res, token))
.catch( err => redirectWithError(res, err));
});
/**
* Executed discovery and returns the configured `openid-client` client
*
* @param {Setting} row
* */
let getClient = async row => {
let issuer = await oidc.Issuer.discover(row.meta.issuerURL); let issuer = await oidc.Issuer.discover(row.meta.issuerURL);
let client = new issuer.Client({
return new issuer.Client({
client_id: row.meta.clientID, client_id: row.meta.clientID,
client_secret: row.meta.clientSecret, client_secret: row.meta.clientSecret,
redirect_uris: [row.meta.redirectURL], redirect_uris: [row.meta.redirectURL],
response_types: ['code'], response_types: ['code'],
}); });
}
/**
* Generates state, nonce and authorization url.
*
* @param {Request} req
* @param {Setting} row
* @return { {String}, {String}, {String} } state, nonce and url
* */
let getInitParams = async (req, row) => {
let client = await getClient(row);
let state = crypto.randomUUID();
let nonce = crypto.randomUUID();
let url = client.authorizationUrl({
scope: 'openid email profile',
resource: `${req.protocol}://${req.get('host')}${req.originalUrl}`,
state,
nonce,
})
return { state, nonce, url };
}
/**
* Parses state and nonce from cookie during the callback phase.
*
* @param {Request} req
* @return { {String}, {String} } state and nonce
* */
let parseStateFromCookie = req => {
let state, nonce; let state, nonce;
let cookies = req.headers.cookie.split(';'); let cookies = req.headers.cookie.split(';');
for (cookie of cookies) { for (cookie of cookies) {
@ -109,24 +123,43 @@ router
} }
} }
return { state, nonce };
}
/**
* Executes validation of callback parameters.
*
* @param {Request} req
* @param {Setting} settings
* @return {Promise} a promise resolving to a jwt token
* */
let validateCallback = async (req, settings) => {
let client = await getClient(settings);
let { state, nonce } = parseStateFromCookie(req);
const params = client.callbackParams(req); const params = client.callbackParams(req);
const tokenSet = await client.callback(row.meta.redirectURL, params, { /*code_verifier: verifier,*/ state, nonce }); const tokenSet = await client.callback(settings.meta.redirectURL, params, { state, nonce });
let claims = tokenSet.claims(); let claims = tokenSet.claims();
console.log('validated ID Token claims %j', claims); console.log('oidc: authentication successful for email', claims.email);
return internalToken.getTokenFromOAuthClaim({ identity: claims.email }) return internalToken.getTokenFromOAuthClaim({ identity: claims.email })
}
}) let redirectToAuthorizationURL = (res, params) => {
.then( response => { console.log('oidc: init flow > url > ', params.url);
console.log('oidc callback > signed token > >', response); res.cookie("npm_oidc", params.state + '--' + params.nonce);
res.cookie('npm_oidc', response.token + '---' + response.expires); res.redirect(params.url);
}
let redirectWithJwtToken = (res, token) => {
res.cookie('npm_oidc', token.token + '---' + token.expires);
res.redirect('/login'); res.redirect('/login');
}) }
.catch( err => {
console.log('oidc callback ERR > ', err); let redirectWithError = (res, error) => {
res.cookie('npm_oidc_error', err.message); console.log('oidc: callback error: ', error);
res.cookie('npm_oidc_error', error.message);
res.redirect('/login'); res.redirect('/login');
}); }
});
module.exports = router; module.exports = router;