Add support for OpenID connect!!
This commit is contained in:
98
app/unit/OpenIDConnectUnit.js
Normal file
98
app/unit/OpenIDConnectUnit.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const Unit = require('libflitter/Unit')
|
||||
const { Provider, interactionPolicy: { Prompt, base: policy } } = require('oidc-provider')
|
||||
const uuid = require('uuid').v4
|
||||
const CoreIDAdapter = require('../classes/oidc/CoreIDAdapter')
|
||||
const RequestLocalizationHelper = require('flitter-i18n/src/RequestLocalizationHelper')
|
||||
const ResponseSystemMiddleware = require('libflitter/routing/ResponseSystemMiddleware')
|
||||
|
||||
class OpenIDConnectUnit extends Unit {
|
||||
static get name() {
|
||||
return 'openid_connect'
|
||||
}
|
||||
|
||||
static get services() {
|
||||
return [...super.services, 'output', 'configs', 'models']
|
||||
}
|
||||
|
||||
async go(app) {
|
||||
this.Vue = this.app.di().get('Vue')
|
||||
const issuer = this.configs.get('app.url')
|
||||
const configuration = this.configs.get('oidc.provider')
|
||||
const interactions = policy()
|
||||
const User = this.models.get('auth:User')
|
||||
|
||||
CoreIDAdapter.connect(app)
|
||||
|
||||
this.provider = new Provider(issuer, {
|
||||
adapter: CoreIDAdapter,
|
||||
clients: [],
|
||||
interactions: {
|
||||
interactions,
|
||||
url: (ctx, interaction) => `/openid/interaction/${ctx.oidc.uid}`,
|
||||
},
|
||||
cookies: {
|
||||
long: { signed: true, maxAge: 24 * 60 * 60 * 1000 }, // 1 day, ms
|
||||
short: { signed: true },
|
||||
keys: [this.configs.get('server.session.secret') || uuid()]
|
||||
},
|
||||
claims: {
|
||||
email: ['email'],
|
||||
profile: [
|
||||
'first_name', 'last_name', 'picture', 'tagline', 'username',
|
||||
],
|
||||
},
|
||||
features: {
|
||||
devInteractions: { enabled: false },
|
||||
deviceFlow: { enabled: true },
|
||||
introspection: { enabled: true },
|
||||
revocation: { enabled: true },
|
||||
},
|
||||
ttl: {
|
||||
AccessToken: 60 * 60, // 1 hour in seconds
|
||||
AuthorizationCode: 10 * 60, // 10 minutes in seconds
|
||||
IdToken: 60 * 60, // 1 hour in seconds
|
||||
DeviceCode: 10 * 60, // 10 minutes in seconds
|
||||
RefreshToken: 24 * 60 * 60, // 1 day in seconds
|
||||
},
|
||||
findAccount: (...args) => User.findAccount(...args),
|
||||
...configuration,
|
||||
})
|
||||
|
||||
app.express.use('/oidc', this.wrap(this.provider.callback))
|
||||
}
|
||||
|
||||
wrap(callback) {
|
||||
return async (req, res, next) => {
|
||||
const client_id = req?.query?.client_id
|
||||
|
||||
// Provide some basic Flitter niceties in the request
|
||||
req.i18n = new RequestLocalizationHelper(req, res)
|
||||
new ResponseSystemMiddleware(this.app, res, req)
|
||||
|
||||
// If we got a client ID, make sure the current user has access to it
|
||||
if ( req?.session?.auth?.user_id && client_id ) {
|
||||
const User = this.models.get('auth:User')
|
||||
const Application = this.models.get('Application')
|
||||
const Policy = this.models.get('iam:Policy')
|
||||
|
||||
const user = await User.findById(req.session.auth.user_id)
|
||||
const application = await Application.findOne({ openid_client_ids: client_id })
|
||||
if ( !application ) {
|
||||
return this.Vue.auth_message(res, {
|
||||
message: req.T('saml.no_access').replace('APP_NAME', 'this application'),
|
||||
next_destination: '/dash',
|
||||
})
|
||||
} else if ( !(await Policy.check_user_access(user, application.id)) ) {
|
||||
return this.Vue.auth_message(res, {
|
||||
message: req.T('saml.no_access').replace('APP_NAME', application.name),
|
||||
next_destination: '/dash',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return callback(req, res, next)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = OpenIDConnectUnit
|
||||
Reference in New Issue
Block a user