UNPKG

@mo-platform/auth

Version:

Mo authentication library

172 lines (144 loc) 4.73 kB
const request = require('superagent') export default class Authentication { constructor (opts = {}) { let { authUrl, clientId, storage, loginUrl, logoutUrl, userFetchUrl, accessCheckUrl } = opts this.authUrl = authUrl || 'https://moauth.fagbokforlaget.no' this.currentUser = undefined this.token = undefined this.clientId = clientId this.storage = storage || window.localStorage this.loginUrl = loginUrl || this.authUrl + '/_auth/login' this.logoutUrl = logoutUrl || this.authUrl + '/_auth/logout' this.userFetchUrl = userFetchUrl || this.authUrl + '/_auth/user?token=' this.accessCheckUrl = accessCheckUrl || this.authUrl + '/_auth/access/{{productId}}?token={{token}}' } _loginUrl (redirectUrl, scope = undefined) { if (!this.loginUrl.includes('?')) { this.loginUrl += '?' } return this.loginUrl + '&client_id=' + (this.clientId || 'generic') + '&redirect_url=' + encodeURIComponent(redirectUrl) + '&scope=' + (scope || 'dbok') } _parseQueryString (loc) { const pl = /\+/g const search = /([^&=]+)=?([^&]*)/g const decode = function (s) { return decodeURIComponent(s.replace(pl, ' ')) } let urlParams = {} let query = loc.substring(1) if (/\?/.test(query)) { query = query.split('?')[1] } while (1) { const match = search.exec(query) if (!match) { break } urlParams[decode(match[1])] = decode(match[2]) } return urlParams } authorize (obj = {}) { let { redirectUrl, scope } = obj window.location = this._loginUrl(redirectUrl || window.location, scope) } getUser () { let storeUser = this.storage.getItem('user') if (this.currentUser) { return this.currentUser } if (storeUser) { return JSON.parse(storeUser) } return undefined } checkToken (loc = window.location.search) { let params = this._parseQueryString(loc) let self = this self.token = params.token || params.access_token || this.storage.getItem('token') || undefined return new Promise((resolve, reject) => { if (self.isAuthenticated() && self.token && typeof self.token !== 'undefined') { resolve(self.getUser()) } if (self.token && typeof self.token !== 'undefined') { if (window) { window.history.replaceState({}, '', window.location.pathname + window.location.hash || '') } self.storage.setItem('token', self.token) self.fetchUser(this.userFetchUrl + encodeURIComponent(self.token)) .then((user) => { resolve(user) }) .catch((err) => { reject(err) }) } else { reject(new Error('access token not found')) } }) } checkAccess (productId) { const token = this.token || this.storage.getItem('token') || undefined return new Promise((resolve, reject) => { if (token && typeof token !== 'undefined') { const url = this.accessCheckUrl.replace(/{{productId}}/g, productId).replace(/{{token}}/g, token) this.fetchAccess(url) .then((data) => { resolve(data) }) .catch((err) => { reject(err) }) } else { reject(new Error('access token not found')) } }) } fetchUser (url) { let self = this return new Promise((resolve, reject) => { request('GET', url) .end(function (error, response) { if (!error && response.statusCode === 200 && response.body) { let resp = response.body let user = resp.user || resp.objects[0] self.storage.setItem('user', JSON.stringify(user)) resolve(user) } else { reject(new Error('authentication failed:' + error)) } }) }) } fetchAccess (url) { return new Promise((resolve, reject) => { request('GET', url) .end(function (error, response) { if (!error && response.statusCode === 200 && response.body) { if (response.body.success) { resolve(response.body.product) } else { reject(new Error('This user does not have access to this product')) } } else { reject(error) } }) }) } logout (url) { this.storage.removeItem('user') this.storage.removeItem('token') if (this.logoutUrl) { request('GET', this.logoutUrl).end((err, response) => { if (err) {} // Do nothing if (url) window.location = url }) } } isAuthenticated () { let user = this.getUser() if (user) { return true } return false } }