/**
* This file is part of Sesatheque.
* Copyright 2014-2015, Association Sésamath
*
* Sesatheque is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3
* as published by the Free Software Foundation.
*
* Sesatheque is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Sesatheque (LICENCE.txt).
* @see http://www.gnu.org/licenses/agpl.txt
*
*
* Ce fichier fait partie de l'application Sésathèque, créée par l'association Sésamath.
*
* Sésathèque est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant
* les termes de la GNU Affero General Public License version 3 telle que publiée par la
* Free Software Foundation.
* Sésathèque est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ;
* sans même la garantie tacite de QUALITÉ MARCHANDE ou d'ADÉQUATION à UN BUT PARTICULIER.
* Consultez la GNU Affero General Public License pour plus de détails.
* Vous devez avoir reçu une copie de la GNU General Public License en même temps que Sésathèque
* (cf LICENCE.txt et http://vvlibri.org/fr/Analyse/gnu-affero-general-public-license-v3-analyse
* pour une explication en français)
*/
'use strict'
// un module avec des méthodes communes pour le service et le controleur du client
const { defaultPrefix } = require('./common')
const helper = require('./helper')
/** @type {sesalabSsoClient} */
let client
/**
* Retourne un authServer si on trouve sa baseUrl en config
* @param {string} baseUrl
* @returns {AuthServerDef}
*/
function getAuthServer (baseUrl) {
const server = client.authServers.find((server) => server.baseUrl === baseUrl)
/* global log */
if (!server && typeof log !== 'undefined' && log.debug) log.debug('pas trouvé ' + baseUrl + 'parmi', client.authServers)
return server
}
/**
* Initialise client
* @private
*/
function init (componentConfig, baseUrl) {
client = helper.getBaseConfig(componentConfig, baseUrl)
// spécifique client
if (!componentConfig.authServers || !componentConfig.authServers.length) throw new Error('Impossible d’initialiser $sesalabSsoClient sans préciser authServers en configuration')
client.authServers = componentConfig.authServers.map(function (authServer) {
/**
* @private
* @type {AuthServer}
*/
const cleanServer = {}
;['baseUrl', 'errorPage', 'loginPage', 'logoutPage'].forEach(function (prop) {
if (typeof authServer[prop] !== 'string' || !authServer[prop]) {
throw new Error('config incorrecte, ' + prop + ' manquant sur un authServer')
}
cleanServer[prop] = authServer[prop]
})
const prefix = authServer.prefix || defaultPrefix
cleanServer.validate = prefix + '/validate'
return cleanServer
})
// pour les callback, on initialise avec des fcts qui renvoient une erreur,
// elle devront donc être écrasée avant de les utiliser
if (componentConfig.logoutCallback) {
client.logoutCallback = componentConfig.logoutCallback
} else {
client.logoutCallback = function (context, next) {
next(new Error('Erreur de configuration, pas de méthode de déconnexion'))
}
}
if (componentConfig.loginCallback) {
client.loginCallback = componentConfig.loginCallback
} else {
client.loginCallback = function (context, user, next) {
next(new Error('Erreur de configuration, pas de méthode de connexion'))
}
}
// console.log('$sesalabSsoClient a construit le client', client)
}
/**
* Wrapper de la loginCallback courante
* @param context
* @param user
* @param next
*/
function loginCallback (context, user, next) {
client.loginCallback(context, user, next)
}
/**
* Wrapper de la loginCallback courante
* @param context
* @param next
*/
function logoutCallback (context, next) {
client.logoutCallback(context, next)
}
/**
* Affecte des nouvelles propriétés de client
* @param {object} props
*/
function setClient (props) {
Object.assign(client, props)
}
module.exports = {
getAuthServer,
getBaseUrl: () => client.baseUrl,
init,
loginCallback,
logoutCallback,
setClient
}
/**
* @callback simpleCallback
* @param {Error} [error]
*/
/**
* @callback loginCallback
* @param {Context} context
* @param {User} user
* @param {simpleCallback} next
*/
/**
* @callback logoutCallback
* @param {Context} context
* @param {simpleCallback} next
*/
/**
* La définition du client une fois normée par init
* @typedef {Object} sesalabSsoClient
* @property {string} baseUrl
* @property {number} [timeout=10] Timeout des appels du validate (en s)
* @property {string} [prefix=sesalabSso] Préfixe des routes de ce module
* @property {AuthServer[]} authServers La liste des serveurs d'authentification
* @property {function} loginCallback Logue le user localement, appelée avec (context, user, next), doit rappeler next(error)
* @property {function} logoutCallback Déconnecte le user courant localement, appelée avec (context, next), doit rappeler next(error)
*/