EvalueTonSavoir/server/auth/modules/passport-providers/oidc.js

97 lines
3.9 KiB
JavaScript
Raw Normal View History

2024-09-28 14:03:15 -04:00
var OpenIDConnectStrategy = require('passport-openidconnect')
2024-10-01 11:37:07 -04:00
var authUserAssoc = require('../../../models/authUserAssociation')
var users = require('../../../models/users')
var { hasNestedValue } = require('../../../utils')
2024-09-28 14:03:15 -04:00
class PassportOpenIDConnect {
2024-10-01 11:37:07 -04:00
constructor(passportjs,auth_name){
this.passportjs = passportjs
2024-10-01 11:37:07 -04:00
this.auth_name = auth_name
}
2024-09-28 20:16:29 -04:00
async getConfigFromConfigURL(name,provider){
try{
const config = await fetch(provider.OIDC_CONFIG_URL)
return await config.json()
} catch (error) {
console.error(`Les informations de connexions de la connexion OIDC ${name} n'ont pu être chargées.`)
}
}
async register(app, passport,endpoint, name, provider) {
const config = await this.getConfigFromConfigURL(name,provider)
2024-09-29 18:39:24 -04:00
const cb_url =`${process.env['BACKEND_URL']}${endpoint}/${name}/callback`
2024-10-01 11:37:07 -04:00
const self = this
2024-09-28 20:16:29 -04:00
2024-09-28 14:03:15 -04:00
passport.use(name, new OpenIDConnectStrategy({
2024-09-28 20:16:29 -04:00
issuer: config.issuer,
authorizationURL: config.authorization_endpoint,
tokenURL: config.token_endpoint,
userInfoURL: config.userinfo_endpoint,
clientID: provider.OIDC_CLIENT_ID,
clientSecret: provider.OIDC_CLIENT_SECRET,
2024-09-29 18:39:24 -04:00
callbackURL: cb_url,
2024-09-28 20:16:29 -04:00
passReqToCallback: true,
scope: 'openid profile email ' + `${provider.OIDC_ADD_SCOPE}`,
2024-09-28 14:03:15 -04:00
},
2024-09-28 20:16:29 -04:00
// patch pour la librairie permet d'obtenir les groupes, PR en cours mais "morte" : https://github.com/jaredhanson/passport-openidconnect/pull/101
async function(req, issuer, profile, times, tok, done) {
2024-09-28 14:03:15 -04:00
try {
2024-10-01 11:37:07 -04:00
const received_user = {
auth_id: profile.id,
2024-09-28 20:16:29 -04:00
email: profile.emails[0].value,
name: profile.name.givenName,
2024-10-01 11:37:07 -04:00
roles: []
2024-09-28 14:03:15 -04:00
};
2024-10-01 11:37:07 -04:00
if(hasNestedValue(profile,provider.OIDC_ROLE_TEACHER_VALUE)) received_user.roles.push('teacher')
if(hasNestedValue(profile,provider.OIDC_ROLE_STUDENT_VALUE)) received_user.roles.push('student')
const user_association = await authUserAssoc.find_user_association(self.auth_name._id,received_user.auth_id)
let user_account = null
if(user_association){
user_account = await users.getById(user_association.user_id)
}
else {
let user_id = await users.getId(received_user.email)
user_account = user_id ? await users.getById(user_id) : await users.register(received_user.email,"")
await authUserAssoc.link(self.auth_name,received_user.auth_id,user_account._id)
}
user_account.name = received_user.name
user_account.roles = received_user.roles
await users.editUser(user_account)
self.passportjs.authenticate(user_account)
return done(null, user_account);
2024-09-28 14:03:15 -04:00
} catch (error) {
}
}));
2024-09-28 20:16:29 -04:00
app.get(`${endpoint}/${name}`, (req, res, next) => {
2024-09-28 14:03:15 -04:00
passport.authenticate(name, {
2024-09-28 20:16:29 -04:00
scope: 'openid profile email offline_access'+ ` ${provider.OAUTH_ADD_SCOPE}`,
2024-09-28 14:03:15 -04:00
prompt: 'consent'
2024-09-28 20:16:29 -04:00
})(req, res, next);
2024-09-28 14:03:15 -04:00
});
2024-09-28 20:16:29 -04:00
app.get(`${endpoint}/${name}/callback`,
(req, res, next) => {
passport.authenticate(name, { failureRedirect: '/login' })(req, res, next);
2024-09-28 14:03:15 -04:00
},
(req, res) => {
if (req.user) {
2024-09-28 20:16:29 -04:00
res.json(req.user)
console.info(`L'utilisateur '${req.user.name}' vient de se connecter`)
} else {
res.status(401).json({ error: "L'authentification a échoué" });
2024-09-28 14:03:15 -04:00
}
}
);
}
}
module.exports = PassportOpenIDConnect;