Skip to content
Snippets Groups Projects
Select Git revision
  • 6e6051e44f80a3e155da16c611280e44b158d611
  • master default protected
  • github/fork/hrani/master
  • github/fork/dilawar/master
  • chamcham
  • chhennapoda
  • wheel
  • 3.2.0-pre0
  • v3.1.3
  • 3.1.2
  • 3.1.1
  • chamcham-3.1.1
  • 3.1.0
  • ghevar_3.0.2_pre2
  • ghevar_3.0.2
15 results

setget.txt

Blame
  • authentication-service-v2.js 5.46 KiB
    import config from '../config.json';
    
    /* global Keycloak */
    
    let keycloakClient = undefined;
    
    const INIT_CHECK_INTERVAL_MS = 100;
    const INIT_CHECK_MAX_RETRIES = 10;
    
    let _instance = null;
    const SINGLETON_ENFORCER = Symbol();
    
    /**
     * Service taking care of OIDC/FS authentication for NRP accounts
     */
    class AuthenticationService {
      constructor(enforcer) {
        if (enforcer !== SINGLETON_ENFORCER) {
          throw new Error('Use ' + this.constructor.name + '.instance');
        }
    
        this.proxyURL = config.api.proxy.url;
        this.oidcEnabled = config.auth.enableOIDC;
        this.clientId = config.auth.clientId;
        this.authURL = config.auth.url;
        this.STORAGE_KEY = `tokens-${this.clientId}@https://iam.ebrains.eu/auth/realms/hbp`;
    
        this.init();
      }
    
      static get instance() {
        if (_instance == null) {
          _instance = new AuthenticationService(SINGLETON_ENFORCER);
        }
    
        return _instance;
      }
    
      init() {
        this.initialized = false;
        if (this.oidcEnabled) {
          this.authCollab().then(() => {
            this.initialized = true;
          });
        }
        else {
          this.checkForNewLocalTokenToStore();
          this.initialized = true;
        }
    
        this.promiseInitialized = new Promise((resolve, reject) => {
          let numChecks = 0;
          let checkInterval = setInterval(() => {
            numChecks++;
            if (numChecks > INIT_CHECK_MAX_RETRIES) {
              clearInterval(checkInterval);
              reject();
            }
            if (this.initialized) {
              clearInterval(checkInterval);
              resolve();
            }
          }, INIT_CHECK_INTERVAL_MS);
        });
      }
    
      authenticate(config) {
        if (this.oidcEnabled) {
          this.authCollab(config);
        }
        else {
          this.authLocal(config);
        }
      }
    
      getToken() {
        if (this.oidcEnabled) {
          if (keycloakClient && keycloakClient.authenticated) {
            keycloakClient
              .updateToken(30)
              .then(function() {})
              .catch(function() {
                console.error('Failed to refresh token');
              });
            return keycloakClient.token;
          }
          else {
            console.error('getToken() - Client is not authenticated');
          }
        }
        else {
          return this.getStoredLocalToken();
        }
      }
    
      logout() {
        if (this.oidcEnabled) {
          if (keycloakClient && keycloakClient.authenticated) {
            keycloakClient.logout();
            keycloakClient.clearStoredLocalToken();
          }
          else {
            console.error('Client is not authenticated');
          }
        }
        else {
          return this.clearStoredLocalToken();
        }
      }
    
      authLocal(config) {
        if (this.authenticating) {
          return;
        }
        this.authenticating = true;
    
        this.authURL = this.authURL || config.url;
        this.clientId = this.clientId || config.clientId;
    
        let absoluteUrl = /^https?:\/\//i;
        if (!absoluteUrl.test(this.authURL)) {
          this.authURL = `${this.proxyURL}${this.authURL}`;
        }
    
        this.clearStoredLocalToken();
        window.location.href = `${this.authURL}&client_id=${this
          .clientId}&redirect_uri=${encodeURIComponent(window.location.href)}`;
      }
    
      checkForNewLocalTokenToStore() {
        const path = window.location.pathname;
    
        const accessTokenMatch = /&access_token=([^&]*)/.exec(path);
        if (!accessTokenMatch || !accessTokenMatch[1]) {
          return;
        }
    
        let accessToken = accessTokenMatch[1];
        localStorage.setItem(
          this.STORAGE_KEY,
          //eslint-disable-next-line camelcase
          JSON.stringify([{ access_token: accessToken }])
        );
    
        // navigate to clean url
        let cleanedPath = path.substr(0, path.indexOf('&'));
        window.location = cleanedPath;
      }
    
      clearStoredLocalToken() {
        localStorage.removeItem(this.STORAGE_KEY);
      }
    
      getStoredLocalToken() {
        let storedItem = localStorage.getItem(this.STORAGE_KEY);
        if (!storedItem) {
          // this token will be rejected by the server and the client will get a proper auth error
          return 'no-token';
        }
    
        try {
          let tokens = JSON.parse(storedItem);
          return tokens.length ? tokens[tokens.length - 1].access_token : null;
        }
        catch (e) {
          // this token will be rejected by the server and the client will get a proper auth error
          return 'malformed-token';
        }
      }
    
      authCollab(config) {
        if (this.authenticating) {
          return;
        }
        this.authenticating = true;
    
        return new Promise(resolve => {
          this.authURL = this.authURL || config.url;
    
          this.initKeycloakClient().then(() => {
            if (!keycloakClient.authenticated) {
              // User is not authenticated, run login
              keycloakClient
                .login({ scope: 'openid profile email group' })
                .then(() => {
                  resolve(true);
                });
            }
            else {
              keycloakClient.loadUserInfo().then(userInfo => {
                this.userInfo = userInfo;
                resolve(true);
              });
            }
          });
        });
      }
    
      initKeycloakClient() {
        return new Promise(resolve => {
          keycloakClient = Keycloak({
            realm: 'hbp',
            clientId: this.clientId,
            //'public-client': true,
            'confidential-port': 0,
            url: this.authURL,
            redirectUri: window.location.href // 'http://localhost:9001/#/esv-private' //
          });
    
          keycloakClient
            .init({
              flow: 'hybrid' /*, responseMode: 'fragment'*/
            })
            .then(() => {
              resolve(keycloakClient);
            });
        });
      }
    }
    
    AuthenticationService.CONSTANTS = Object.freeze({
      MALFORMED_TOKEN: 'malformed-token',
      NO_TOKEN: 'no-token'
    });
    
    export default AuthenticationService;