UNPKG

4.72 kBJavaScriptView Raw
1const request = require('superagent')
2
3export default class Authentication {
4 constructor (opts = {}) {
5 let { authUrl, clientId, storage, loginUrl, logoutUrl, userFetchUrl, accessCheckUrl } = opts
6
7 this.authUrl = authUrl || 'https://moauth.fagbokforlaget.no'
8 this.currentUser = undefined
9 this.token = undefined
10 this.clientId = clientId
11 this.storage = storage || window.localStorage
12 this.loginUrl = loginUrl || this.authUrl + '/_auth/login'
13 this.logoutUrl = logoutUrl
14 this.userFetchUrl = userFetchUrl || this.authUrl + '/_auth/user?token='
15 this.accessCheckUrl = accessCheckUrl || this.authUrl + '/_auth/access'
16 }
17
18 _loginUrl (redirectUrl, scope = undefined) {
19 if (!this.loginUrl.includes('?')) {
20 this.loginUrl += '?'
21 }
22 return this.loginUrl + '&client_id=' + (this.clientId || 'generic') + '&redirect_url=' + encodeURIComponent(redirectUrl) + '&scope=' + (scope || 'dbok')
23 }
24
25 _parseQueryString (loc) {
26 const pl = /\+/g
27 const search = /([^&=]+)=?([^&]*)/g
28 const decode = function (s) { return decodeURIComponent(s.replace(pl, ' ')) }
29 let urlParams = {}
30 let query = loc.substring(1)
31
32 if (/\?/.test(query)) {
33 query = query.split('?')[1]
34 }
35
36 while (1) {
37 const match = search.exec(query)
38
39 if (!match) {
40 break
41 }
42 urlParams[decode(match[1])] = decode(match[2])
43 }
44
45 return urlParams
46 }
47
48 authorize (obj = {}) {
49 let { redirectUrl, scope } = obj
50
51 window.location = this._loginUrl(redirectUrl || window.location, scope)
52 }
53
54 getUser () {
55 let storeUser = this.storage.getItem('user')
56
57 if (this.currentUser) {
58 return this.currentUser
59 }
60 if (storeUser) {
61 return JSON.parse(storeUser)
62 }
63 return undefined
64 }
65
66 checkToken (loc = window.location.search) {
67 let params = this._parseQueryString(loc)
68 let self = this
69
70 self.token = params.token || params.access_token || this.storage.getItem('token') || undefined
71
72 return new Promise((resolve, reject) => {
73 if (self.isAuthenticated() && self.token && typeof self.token !== 'undefined') {
74 resolve(self.getUser())
75 }
76
77 if (self.token && typeof self.token !== 'undefined') {
78 if (window) {
79 window.history.replaceState({}, '', window.location.pathname + window.location.hash || '')
80 }
81 self.storage.setItem('token', self.token)
82 self.fetchUser(this.userFetchUrl + encodeURIComponent(self.token))
83 .then((user) => {
84 resolve(user)
85 })
86 .catch((err) => {
87 reject(err)
88 })
89 } else {
90 reject(new Error('access token not found'))
91 }
92 })
93 }
94
95 checkAccess (productIds = []) {
96 const token = this.token || this.storage.getItem('token') || undefined
97 const products = Array.isArray(productIds) ? productIds : [productIds]
98 const user = this.getUser()
99
100 return new Promise(async (resolve, reject) => {
101 if (token && typeof token !== 'undefined') {
102 const allowedProducts = await this.fetchAccess(this.accessCheckUrl, { token: token, productIds: products })
103 resolve({ success: true, user: user, products: allowedProducts })
104 } else {
105 throw new Error('access token not found')
106 }
107 })
108 }
109
110 fetchUser (url) {
111 let self = this
112
113 return new Promise((resolve, reject) => {
114 request
115 .get(url)
116 .then(response => {
117 if (response.statusCode === 200 && response.body) {
118 let resp = response.body
119 let user = resp.user || resp.objects[0]
120
121 self.storage.setItem('user', JSON.stringify(user))
122 resolve(user)
123 } else {
124 reject(new Error('authentication failed: Invalid response'))
125 }
126 })
127 .catch(err => {
128 reject(err)
129 })
130 })
131 }
132
133 fetchAccess (url, body) {
134 return new Promise((resolve, reject) => {
135 request
136 .post(url)
137 .send(body)
138 .set('Accept', 'application/json')
139 .then(response => {
140 if (response.statusCode === 200 && response.body) {
141 if (response.body.success) {
142 resolve(response.body.products)
143 } else {
144 reject(new Error('This user does not have access to this product'))
145 }
146 }
147 })
148 .catch(error => {
149 reject(error)
150 })
151 })
152 }
153
154 async logout (url) {
155 this.storage.removeItem('user')
156 this.storage.removeItem('token')
157
158 url = url || this.logoutUrl
159
160 if (url) window.location = url
161 }
162
163 isAuthenticated () {
164 let user = this.getUser()
165
166 if (user) {
167 return true
168 }
169 return false
170 }
171}