Created
August 26, 2021 00:55
-
-
Save wilsonjackson/9136b0bee9d47080bcbee991378b2581 to your computer and use it in GitHub Desktop.
Implementation of setProviderSession for node-oidc-provider@7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a replacement for the method Provider.setProviderSession, which was removed in oidc-provider 7.x. | |
// | |
// Question in repo about its removal, unanswered at the time of this writing: | |
// https://github.com/panva/node-oidc-provider/discussions/934 | |
// | |
// Original 6.x Method source is here: | |
// https://github.com/panva/node-oidc-provider/blob/2c3a667de583846470921883918f4c4145bef6c6/lib/provider.js | |
// | |
// The version in this file has been adjusted in the following significant ways: | |
// - Removed the `meta` argument, which is no longer supported in 7.x | |
// - Now creates a Grant record, which is a new entity type in 7.x | |
// - Uses Session.loginAccount() instead of Object.assign() to assign session properties | |
// - Discovers the session TTL by reading OIDC Provider configuration, as it's a required argument to Session.save() | |
// | |
// oidc-provider internals are used here, so this could very easily break in an upgrade. | |
const instance = require('oidc-provider/lib/helpers/weak_cache'); | |
const epochTime = require('oidc-provider/lib/helpers/epoch_time'); | |
const ssHandler = require('oidc-provider/lib/helpers/samesite_handler'); | |
const nanoid = require('oidc-provider/lib/helpers/nanoid'); | |
const assert = require('assert'); | |
/** | |
* @name setProviderSession | |
* @api public | |
*/ | |
async function setProviderSession(provider, req, res, { | |
accountId, | |
loginTs = epochTime(), | |
remember = true, | |
clients = [], | |
} = {}) { | |
assert(typeof accountId === 'string', 'accountId must be a string'); | |
assert(Number.isSafeInteger(loginTs), 'loginTs must be an Integer'); | |
assert(Array.isArray(clients), 'clients must be an Array'); | |
const ctx = { | |
req, | |
res, | |
oidc: { | |
provider, | |
cookies: provider.app.createContext(req, res).cookies, | |
}, | |
secure: req.connection.encrypted || req.protocol === 'https', | |
}; | |
const session = await provider.Session.get(ctx); | |
session.loginAccount({ accountId, loginTs, transient: !remember }); | |
for (const clientId of clients) { | |
assert(typeof clientId === 'string', 'clients must contain an array of client_id strings'); | |
const grant = new provider.Grant({ accountId, clientId }); | |
grant.addOIDCScope('openid'); | |
const grantId = await grant.save(); | |
session.sidFor(clientId, nanoid()); | |
session.grantIdFor(clientId, grantId); | |
} | |
let ttl = instance(provider).configuration('ttl.Session'); | |
if (typeof ttl === 'function') { | |
ttl = ttl(ctx, session); | |
} | |
await session.save(ttl); | |
const { maxAge, ...opts } = instance(provider).configuration('cookies.long'); | |
ssHandler.set( | |
ctx.oidc.cookies, | |
provider.cookieName('session'), | |
session.id, | |
session.transient ? opts : { maxAge, ...opts }, | |
); | |
return session; | |
} | |
module.exports = { | |
setProviderSession, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment