Source: component/serviceClient.js

/**
 * 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'

const { getAuthServer, init, setClient } = require('./helperClient')
const { errorCallback, setErrorCallback } = require('./helper')

module.exports = function (component) {
  component.service('$sesalabSsoClient', function ($cache, $settings) {
    /**
     * Retourne l'url de connexion sur le serveur
     * @returns {string}
     */
    function getLoginUrl (context) {
      return null
    }

    /**
     * Retourne l'url de déconnexion sur le serveur
     * @returns {string}
     */
    function getLogoutUrl (context) {
      if (context.session.authBaseUrl) {
        const authServer = getAuthServer(context.session.authBaseUrl)
        if (authServer.logoutPage) return authServer.baseUrl + authServer.logoutPage
      }
      console.error(new Error('Impossible de trouver le serveur d’authentification, donc l’url de logout'))
      return null
    }

    /**
     * Redirige vers le login du serveur d'authentification et reviendra vers urlApp
     * @param context
     * @param urlApp
     */
    function login (context, urlApp) {
      errorCallback(context, new Error('sesalab-sso n’implémente pas encore le login initié par une sesathèque'))
    }

    /**
     * Redirige vers le logout du serveur d'authentification
     * @param context
     */
    function logout (context) {
      const logoutUrl = getLogoutUrl(context)
      if (logoutUrl) context.redirect(logoutUrl)
      else errorCallback(context, new Error('Impossible de trouver le serveur d’authentification'))
    }

    /**
     * Affecte la callback de login (les applis peuvent avoir besoin de le préciser après le boot pour utiliser
     * des services pas encore dispo lors de la déclaration de la configuration)
     * @param loginCallback callback qui sera appelée avec (error, user) (pour connecter un user sur l'appli cliente)
     */
    function setLoginCallback (loginCallback) {
      if (typeof loginCallback !== 'function') throw new Error('setLoginCallback prend une fonction en argument')
      setClient({ loginCallback })
    }

    /**
     * Affecte la callback de logout (les applis peuvent avoir besoin de le préciser après le boot pour utiliser
     * des services pas encore dispo lors de la déclaration de la configuration)
     * @param logoutCallback callback qui sera appelée avec (context, user) (pour déconnecter un user sur l'appli cliente)
     */
    function setLogoutCallback (logoutCallback) {
      if (typeof logoutCallback !== 'function') throw new Error('setLoginCallback prend une fonction en argument')
      setClient({ logoutCallback })
    }

    const componentConfig = $settings.get('components.sesalabSso', {})
    const baseUrl = $settings.get('application.baseUrl')
    init(componentConfig, baseUrl)
    return {
      getLoginUrl,
      getLogoutUrl,
      login,
      logout,
      setErrorCallback,
      setLoginCallback,
      setLogoutCallback
    }
  })
}

/**
 * @typedef {Object} AuthServer
 * @property {string} baseUrl url absolue avec / de fin
 * @property {string} validate url relative du validate
 * @property {string} loginPage url relative du form d'authentification
 * @property {string} logoutPage url relative de la page qui fera toutes les déconnexions en ajax et affichera le résultat
 * @property {string} errorPage url relative de la page qui affichera une erreur
 * @property {string|RegExp|function} [ip] ip qui répond au validate
 *                                      peut être une ip (v4 ou v6)
 *                                      ou une RegExp
 *                                      ou une fct (qui doit renvoyer un booléen en reçevant une ip)
 */