@qikdev/sdk 0.1.170 → 0.1.181
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +1 -1
- package/package.json +4 -13
- package/src/api/qik.access.js +715 -750
- package/src/api/qik.api.js +3 -3
- package/src/api/qik.auth.js +797 -740
- package/src/api/qik.content.js +7 -12
- package/src/api/qik.core.js +1 -0
- package/src/api/qik.files.js +4 -40
- package/src/api/qik.socket.js +293 -305
- package/src/api/qik.utils.js +1190 -1039
- package/src/version.js +1 -1
- package/.husky/pre-commit +0 -5
- package/dist/sdk.js +0 -2
- package/dist/sdk.js.LICENSE.txt +0 -8
- package/eslint.config.js +0 -6
- package/yarn-error.log +0 -3598
package/src/api/qik.auth.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import axios from
|
|
2
|
-
import { EventDispatcher } from
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { EventDispatcher } from './qik.utils.js';
|
|
3
3
|
|
|
4
4
|
///////////////////////////////////////////////////
|
|
5
5
|
|
|
@@ -12,870 +12,927 @@ import { EventDispatcher } from "./qik.utils.js";
|
|
|
12
12
|
* @param {QikAPI} qik A reference to the parent instance of the QikCore module. This module is usually created by a QikCore instance that passes itself in as the first argument.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
var QikAuth = function
|
|
16
|
-
if (!qik.api) {
|
|
17
|
-
throw new Error(`Please ensure that QikAPI exists before QikAuth`);
|
|
18
|
-
}
|
|
15
|
+
var QikAuth = function(qik) {
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
if (!qik.api) {
|
|
18
|
+
throw new Error(`Please ensure that QikAPI exists before QikAuth`);
|
|
19
|
+
}
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
//Keep track of any refresh requests
|
|
22
|
+
var inflightRefreshRequest;
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
var store = sessionStorage;
|
|
27
|
-
const tokenBufferSeconds = 10;
|
|
24
|
+
///////////////////////////////////////////////////
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
var sessionStorage = {};
|
|
27
|
+
var store = sessionStorage;
|
|
28
|
+
const tokenBufferSeconds = 10;
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
debug: false,
|
|
33
|
-
};
|
|
30
|
+
///////////////////////////////////////////////////
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
32
|
+
const service = {
|
|
33
|
+
debug: false,
|
|
34
|
+
}
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
Object.defineProperty(service, 'store', {
|
|
37
|
+
value: store,
|
|
38
|
+
writable: false,
|
|
39
|
+
});
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
//Create a new dispatcher
|
|
42
|
+
const dispatcher = new EventDispatcher();
|
|
43
|
+
dispatcher.bootstrap(service);
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
//Get the current user
|
|
48
|
-
var user = store.user;
|
|
45
|
+
///////////////////////////////////////////////////
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
function dispatch(parameters) {
|
|
48
|
+
|
|
49
|
+
//Get the current user
|
|
50
|
+
var user = store.user;
|
|
51
|
+
|
|
52
|
+
//Dispatch the change to the listeners
|
|
53
|
+
if (service.onChange) {
|
|
54
|
+
service.onChange(user);
|
|
55
|
+
}
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
///////////////////////////////////////////////////
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @alias auth.set
|
|
63
|
-
* @description Manually set current user session
|
|
64
|
-
* @param {Object} user The user session object to set as the current user session
|
|
65
|
-
* @param {Object} parameters Additional parameters to dispatch
|
|
66
|
-
* @param {Boolean} stopDispatch Whether to supress dispatching a 'change' event.
|
|
67
|
-
* @example
|
|
68
|
-
*
|
|
69
|
-
* const userSession = {_id:'61eca4746971e75c1fc670cf', firstName:'Daffy', lastName:'Duck' ...};
|
|
70
|
-
* sdk.auth.set(userSession);
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
service.set = function (user, parameters, stopDispatch) {
|
|
74
|
-
if (JSON.stringify(store.user) != JSON.stringify(user)) {
|
|
75
|
-
store.user = user;
|
|
76
|
-
if (!stopDispatch) {
|
|
77
|
-
return dispatch(parameters);
|
|
78
|
-
}
|
|
57
|
+
//Dispatch the change event
|
|
58
|
+
dispatcher.dispatch('change', user, parameters);
|
|
79
59
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
* will be updated to reflect a session in the new organisation, you can use this option to disable that behavior and instead return the
|
|
106
|
-
* user session without dispatching any events
|
|
107
|
-
* @example
|
|
108
|
-
*
|
|
109
|
-
* sdk.auth.changeOrganisation('61eca4746971e75c1fc670cf');
|
|
110
|
-
* // Current user session will be automatically updated
|
|
111
|
-
*
|
|
112
|
-
* const newSession = await sdk.auth.changeOrganisation('61eca4746971e75c1fc670cf', {disableAutoAuthentication:true});
|
|
113
|
-
* // Current user session will not be updated
|
|
114
|
-
* sdk.auth.set(newSession);
|
|
115
|
-
*/
|
|
116
|
-
service.changeOrganisation = function (organisationID, options) {
|
|
117
|
-
//Ensure we just have the ID
|
|
118
|
-
organisationID = qik.utils.id(organisationID);
|
|
119
|
-
|
|
120
|
-
//////////////////////////
|
|
121
|
-
|
|
122
|
-
if (!options) {
|
|
123
|
-
options = {};
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
///////////////////////////////////////////////////
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @alias auth.set
|
|
66
|
+
* @description Manually set current user session
|
|
67
|
+
* @param {Object} user The user session object to set as the current user session
|
|
68
|
+
* @param {Object} parameters Additional parameters to dispatch
|
|
69
|
+
* @param {Boolean} stopDispatch Whether to supress dispatching a 'change' event.
|
|
70
|
+
* @example
|
|
71
|
+
*
|
|
72
|
+
* const userSession = {_id:'61eca4746971e75c1fc670cf', firstName:'Daffy', lastName:'Duck' ...};
|
|
73
|
+
* sdk.auth.set(userSession);
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
service.set = function(user, parameters, stopDispatch) {
|
|
77
|
+
|
|
78
|
+
if (JSON.stringify(store.user) != JSON.stringify(user)) {
|
|
79
|
+
store.user = user;
|
|
80
|
+
if (!stopDispatch) {
|
|
81
|
+
return dispatch(parameters)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
124
85
|
}
|
|
125
86
|
|
|
126
|
-
//////////////////////////
|
|
127
87
|
|
|
128
|
-
|
|
129
|
-
|
|
88
|
+
///////////////////////////////////////////////////
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @alias auth.logout
|
|
92
|
+
* @description Clear the current user session from memory and erase all caches
|
|
93
|
+
* @example
|
|
94
|
+
* sdk.auth.logout();
|
|
95
|
+
*/
|
|
130
96
|
|
|
131
|
-
|
|
132
|
-
|
|
97
|
+
service.logout = function() {
|
|
98
|
+
delete store.user;
|
|
99
|
+
qik.cache.reset();
|
|
100
|
+
return dispatch()
|
|
133
101
|
}
|
|
134
102
|
|
|
135
|
-
|
|
103
|
+
///////////////////////////////////////////////////
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @alias auth.changeOrganisation
|
|
107
|
+
* @description Manually set current user session
|
|
108
|
+
* @param {(String|Object)} organisation The id of the organisation to switch into
|
|
109
|
+
* @param {Object} options Additional options
|
|
110
|
+
* @param {Boolean} options.disableAutoAuthentication By default when switching organisation, the current user session
|
|
111
|
+
* will be updated to reflect a session in the new organisation, you can use this option to disable that behavior and instead return the
|
|
112
|
+
* user session without dispatching any events
|
|
113
|
+
* @example
|
|
114
|
+
*
|
|
115
|
+
* sdk.auth.changeOrganisation('61eca4746971e75c1fc670cf');
|
|
116
|
+
* // Current user session will be automatically updated
|
|
117
|
+
*
|
|
118
|
+
* const newSession = await sdk.auth.changeOrganisation('61eca4746971e75c1fc670cf', {disableAutoAuthentication:true});
|
|
119
|
+
* // Current user session will not be updated
|
|
120
|
+
* sdk.auth.set(newSession);
|
|
121
|
+
*/
|
|
122
|
+
service.changeOrganisation = function(organisationID, options) {
|
|
123
|
+
|
|
124
|
+
//Ensure we just have the ID
|
|
125
|
+
organisationID = qik.utils.id(organisationID);
|
|
126
|
+
|
|
127
|
+
//////////////////////////
|
|
128
|
+
|
|
129
|
+
if (!options) {
|
|
130
|
+
options = {};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
//////////////////////////
|
|
134
|
+
|
|
135
|
+
//Change the users current tokens straight away
|
|
136
|
+
var autoAuthenticate = true;
|
|
137
|
+
|
|
138
|
+
if (options.disableAutoAuthentication) {
|
|
139
|
+
autoAuthenticate = false;
|
|
140
|
+
}
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
qik.
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
//////////////////////////
|
|
143
|
+
|
|
144
|
+
return new Promise(function(resolve, reject) {
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
qik.api.post(`/user/switch/${organisationID}`)
|
|
148
|
+
.then(function(response) {
|
|
149
|
+
|
|
150
|
+
if (autoAuthenticate) {
|
|
151
|
+
qik.cache.reset();
|
|
152
|
+
service.set(response.data);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
resolve(response.data);
|
|
156
|
+
})
|
|
157
|
+
.catch(reject)
|
|
145
158
|
|
|
146
|
-
resolve(response.data);
|
|
147
159
|
})
|
|
148
|
-
.catch(reject);
|
|
149
|
-
});
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
///////////////////////////////////////////////////
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* @alias auth.impersonate
|
|
156
|
-
* @description Impersonate another user within your organisation
|
|
157
|
-
* @param {(String|Object)} persona The id of the user persona you want to impersonate
|
|
158
|
-
* @param {Object} options Additional options
|
|
159
|
-
* @param {Boolean} options.disableAutoAuthentication By default when impersonating a user, the current user session
|
|
160
|
-
* will be updated automatically to reflect the new session, you can use this option to disable that behavior and instead return the
|
|
161
|
-
* new impersonation user session without dispatching any events
|
|
162
|
-
* @example
|
|
163
|
-
*
|
|
164
|
-
* sdk.auth.impersonate('61eca4746971e75c1fc670cf');
|
|
165
|
-
* // Current user session will be automatically updated
|
|
166
|
-
*
|
|
167
|
-
* const newSession = await sdk.auth.impersonate('61eca4746971e75c1fc670cf', {disableAutoAuthentication:true});
|
|
168
|
-
* // Current user session will not be updated
|
|
169
|
-
* sdk.auth.set(newSession);
|
|
170
|
-
*/
|
|
171
|
-
service.impersonate = function (personaID, options) {
|
|
172
|
-
//Ensure we just have the ID
|
|
173
|
-
personaID = qik.utils.id(personaID);
|
|
174
|
-
|
|
175
|
-
//////////////////////////
|
|
176
|
-
|
|
177
|
-
if (!options) {
|
|
178
|
-
options = {};
|
|
179
160
|
}
|
|
180
161
|
|
|
181
|
-
|
|
162
|
+
///////////////////////////////////////////////////
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @alias auth.impersonate
|
|
166
|
+
* @description Impersonate another user within your organisation
|
|
167
|
+
* @param {(String|Object)} persona The id of the user persona you want to impersonate
|
|
168
|
+
* @param {Object} options Additional options
|
|
169
|
+
* @param {Boolean} options.disableAutoAuthentication By default when impersonating a user, the current user session
|
|
170
|
+
* will be updated automatically to reflect the new session, you can use this option to disable that behavior and instead return the
|
|
171
|
+
* new impersonation user session without dispatching any events
|
|
172
|
+
* @example
|
|
173
|
+
*
|
|
174
|
+
* sdk.auth.impersonate('61eca4746971e75c1fc670cf');
|
|
175
|
+
* // Current user session will be automatically updated
|
|
176
|
+
*
|
|
177
|
+
* const newSession = await sdk.auth.impersonate('61eca4746971e75c1fc670cf', {disableAutoAuthentication:true});
|
|
178
|
+
* // Current user session will not be updated
|
|
179
|
+
* sdk.auth.set(newSession);
|
|
180
|
+
*/
|
|
181
|
+
service.impersonate = function(personaID, options) {
|
|
182
|
+
|
|
183
|
+
//Ensure we just have the ID
|
|
184
|
+
personaID = qik.utils.id(personaID);
|
|
185
|
+
|
|
186
|
+
//////////////////////////
|
|
187
|
+
|
|
188
|
+
if (!options) {
|
|
189
|
+
options = {};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//////////////////////////
|
|
193
|
+
|
|
194
|
+
//Change the users current tokens straight away
|
|
195
|
+
var autoAuthenticate = true;
|
|
196
|
+
|
|
197
|
+
if (options.disableAutoAuthentication) {
|
|
198
|
+
autoAuthenticate = false;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
//////////////////////////
|
|
202
|
+
|
|
203
|
+
var promise = qik.api.post(`/user/impersonate/${personaID}`)
|
|
182
204
|
|
|
183
|
-
|
|
184
|
-
|
|
205
|
+
promise.then(function(res) {
|
|
206
|
+
|
|
207
|
+
if (autoAuthenticate) {
|
|
208
|
+
qik.cache.reset();
|
|
209
|
+
service.set(res.data);
|
|
210
|
+
}
|
|
211
|
+
}, function(err) {});
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
return promise;
|
|
185
215
|
|
|
186
|
-
if (options.disableAutoAuthentication) {
|
|
187
|
-
autoAuthenticate = false;
|
|
188
216
|
}
|
|
189
217
|
|
|
190
|
-
|
|
218
|
+
///////////////////////////////////////////////////
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @alias auth.login
|
|
222
|
+
* @description Login and authenticate as a user
|
|
223
|
+
* @param {Object} credentials The credentials used to login
|
|
224
|
+
* @param {String} credentials.email The email address to login to
|
|
225
|
+
* @param {String} credentials.password The password to login with
|
|
226
|
+
* @param {String} credentials.mfa The MFA (Multi Factor Authentication) code
|
|
227
|
+
* @param {Object} options Additional options
|
|
228
|
+
* @param {Boolean} options.disableAutoAuthentication By default when logging in the current user session
|
|
229
|
+
* will be updated automatically to reflect the new session, you can use this option to disable that behavior and instead return the
|
|
230
|
+
* session that was logged in to without dispatching any events
|
|
231
|
+
* @example
|
|
232
|
+
*
|
|
233
|
+
* const credentials = {
|
|
234
|
+
* email:'me@email.com',
|
|
235
|
+
* password:'******',
|
|
236
|
+
* mfa:'1234',
|
|
237
|
+
* }
|
|
238
|
+
*
|
|
239
|
+
* sdk.auth.login(credentials);
|
|
240
|
+
* // Current user session will be automatically updated
|
|
241
|
+
*
|
|
242
|
+
* const newSession = await sdk.auth.login(credentials, {disableAutoAuthentication:true});
|
|
243
|
+
* // Current user session will not be updated
|
|
244
|
+
* sdk.auth.set(newSession);
|
|
245
|
+
*/
|
|
246
|
+
service.login = async function(credentials, options) {
|
|
247
|
+
|
|
248
|
+
if (!options) {
|
|
249
|
+
options = {};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//////////////////////////
|
|
191
253
|
|
|
192
|
-
|
|
254
|
+
//Change the users current tokens straight away
|
|
255
|
+
var autoAuthenticate = true;
|
|
193
256
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (autoAuthenticate) {
|
|
197
|
-
qik.cache.reset();
|
|
198
|
-
service.set(res.data);
|
|
257
|
+
if (options.disableAutoAuthentication) {
|
|
258
|
+
autoAuthenticate = false;
|
|
199
259
|
}
|
|
200
|
-
},
|
|
201
|
-
function (err) {},
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
return promise;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
///////////////////////////////////////////////////
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* @alias auth.login
|
|
211
|
-
* @description Login and authenticate as a user
|
|
212
|
-
* @param {Object} credentials The credentials used to login
|
|
213
|
-
* @param {String} credentials.email The email address to login to
|
|
214
|
-
* @param {String} credentials.password The password to login with
|
|
215
|
-
* @param {String} credentials.mfa The MFA (Multi Factor Authentication) code
|
|
216
|
-
* @param {Object} options Additional options
|
|
217
|
-
* @param {Boolean} options.disableAutoAuthentication By default when logging in the current user session
|
|
218
|
-
* will be updated automatically to reflect the new session, you can use this option to disable that behavior and instead return the
|
|
219
|
-
* session that was logged in to without dispatching any events
|
|
220
|
-
* @example
|
|
221
|
-
*
|
|
222
|
-
* const credentials = {
|
|
223
|
-
* email:'me@email.com',
|
|
224
|
-
* password:'******',
|
|
225
|
-
* mfa:'1234',
|
|
226
|
-
* }
|
|
227
|
-
*
|
|
228
|
-
* sdk.auth.login(credentials);
|
|
229
|
-
* // Current user session will be automatically updated
|
|
230
|
-
*
|
|
231
|
-
* const newSession = await sdk.auth.login(credentials, {disableAutoAuthentication:true});
|
|
232
|
-
* // Current user session will not be updated
|
|
233
|
-
* sdk.auth.set(newSession);
|
|
234
|
-
*/
|
|
235
|
-
service.login = async function (credentials, options) {
|
|
236
|
-
if (!options) {
|
|
237
|
-
options = {};
|
|
238
|
-
}
|
|
239
260
|
|
|
240
|
-
|
|
261
|
+
//////////////////////////////////////
|
|
241
262
|
|
|
242
|
-
|
|
243
|
-
var autoAuthenticate = true;
|
|
263
|
+
var promise = new Promise(loginCheck)
|
|
244
264
|
|
|
245
|
-
|
|
246
|
-
autoAuthenticate = false;
|
|
247
|
-
}
|
|
265
|
+
function loginCheck(resolve, reject) {
|
|
248
266
|
|
|
249
|
-
|
|
267
|
+
if (!credentials) {
|
|
268
|
+
return reject({
|
|
269
|
+
message: 'Missing credentials!',
|
|
270
|
+
})
|
|
271
|
+
}
|
|
250
272
|
|
|
251
|
-
|
|
273
|
+
if (!credentials.email || !credentials.email.length) {
|
|
274
|
+
return reject({
|
|
275
|
+
message: 'Username was not provided',
|
|
276
|
+
})
|
|
277
|
+
}
|
|
252
278
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
279
|
+
if (!credentials.password || !credentials.password.length) {
|
|
280
|
+
return reject({
|
|
281
|
+
message: 'Password was not provided',
|
|
282
|
+
})
|
|
283
|
+
}
|
|
259
284
|
|
|
260
|
-
|
|
261
|
-
return reject({
|
|
262
|
-
message: "Username was not provided",
|
|
263
|
-
});
|
|
264
|
-
}
|
|
285
|
+
/////////////////////////////////////////////
|
|
265
286
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
287
|
+
var postOptions = {
|
|
288
|
+
bypassInterceptor: true
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/////////////////////////////////////////////
|
|
271
292
|
|
|
272
|
-
|
|
293
|
+
var url = `${qik.apiURL}/user/login`;
|
|
273
294
|
|
|
274
|
-
|
|
275
|
-
bypassInterceptor: true,
|
|
276
|
-
};
|
|
295
|
+
/////////////////////////////////////////////
|
|
277
296
|
|
|
278
|
-
|
|
297
|
+
//If we have a specified url
|
|
298
|
+
if (options.url) {
|
|
299
|
+
url = options.url;
|
|
300
|
+
}
|
|
279
301
|
|
|
280
|
-
|
|
302
|
+
/////////////////////////////////////////////
|
|
281
303
|
|
|
282
|
-
|
|
304
|
+
qik.api.post(url, credentials, postOptions).then(function(res) {
|
|
283
305
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
url = options.url;
|
|
287
|
-
}
|
|
306
|
+
if (autoAuthenticate) {
|
|
307
|
+
service.set(res.data);
|
|
288
308
|
|
|
289
|
-
|
|
309
|
+
}
|
|
290
310
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
service.set(res.data);
|
|
311
|
+
resolve(res);
|
|
312
|
+
}, reject);
|
|
294
313
|
}
|
|
295
314
|
|
|
296
|
-
|
|
297
|
-
|
|
315
|
+
//////////////////////////////////////
|
|
316
|
+
|
|
317
|
+
return promise;
|
|
318
|
+
|
|
298
319
|
}
|
|
299
320
|
|
|
300
|
-
|
|
321
|
+
///////////////////////////////////////////////////
|
|
301
322
|
|
|
302
|
-
|
|
303
|
-
};
|
|
323
|
+
service.signup = async function(credentials, options) {
|
|
304
324
|
|
|
305
|
-
|
|
325
|
+
if (!options) {
|
|
326
|
+
options = {};
|
|
327
|
+
}
|
|
306
328
|
|
|
307
|
-
service.signup = async function (credentials, options) {
|
|
308
|
-
if (!options) {
|
|
309
|
-
options = {};
|
|
310
|
-
}
|
|
311
329
|
|
|
312
|
-
|
|
330
|
+
//////////////////////////
|
|
313
331
|
|
|
314
|
-
|
|
315
|
-
|
|
332
|
+
//Change the users current tokens straight away
|
|
333
|
+
var autoAuthenticate = true;
|
|
316
334
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
335
|
+
if (options.disableAutoAuthentication) {
|
|
336
|
+
autoAuthenticate = false;
|
|
337
|
+
}
|
|
320
338
|
|
|
321
|
-
|
|
339
|
+
//////////////////////////////////////
|
|
322
340
|
|
|
323
|
-
|
|
341
|
+
var promise = new Promise(signupCheck)
|
|
324
342
|
|
|
325
|
-
|
|
326
|
-
if (!credentials) {
|
|
327
|
-
return reject({
|
|
328
|
-
message: "No details provided",
|
|
329
|
-
});
|
|
330
|
-
}
|
|
343
|
+
function signupCheck(resolve, reject) {
|
|
331
344
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
345
|
+
if (!credentials) {
|
|
346
|
+
return reject({
|
|
347
|
+
message: 'No details provided',
|
|
348
|
+
})
|
|
349
|
+
}
|
|
337
350
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
351
|
+
if (!credentials.firstName || !credentials.firstName.length) {
|
|
352
|
+
return reject({
|
|
353
|
+
message: 'First Name was not provided',
|
|
354
|
+
})
|
|
355
|
+
}
|
|
343
356
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
357
|
+
if (!credentials.lastName || !credentials.lastName.length) {
|
|
358
|
+
return reject({
|
|
359
|
+
message: 'Last Name was not provided',
|
|
360
|
+
})
|
|
361
|
+
}
|
|
349
362
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
363
|
+
if (!credentials.email || !credentials.email.length) {
|
|
364
|
+
return reject({
|
|
365
|
+
message: 'Email/Username was not provided',
|
|
366
|
+
})
|
|
367
|
+
}
|
|
355
368
|
|
|
356
|
-
if (!credentials.confirmPassword || !credentials.confirmPassword.length) {
|
|
357
|
-
return reject({
|
|
358
|
-
message: "Confirm Password was not provided",
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
369
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
370
|
+
if (!credentials.password || !credentials.password.length) {
|
|
371
|
+
return reject({
|
|
372
|
+
message: 'Password was not provided',
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (!credentials.confirmPassword || !credentials.confirmPassword.length) {
|
|
377
|
+
return reject({
|
|
378
|
+
message: 'Confirm Password was not provided',
|
|
379
|
+
})
|
|
380
|
+
}
|
|
367
381
|
|
|
368
|
-
|
|
382
|
+
if (credentials.confirmPassword != credentials.password) {
|
|
383
|
+
return reject({
|
|
384
|
+
message: 'Your passwords do not match',
|
|
385
|
+
})
|
|
386
|
+
}
|
|
369
387
|
|
|
370
|
-
|
|
371
|
-
bypassInterceptor: true,
|
|
372
|
-
};
|
|
388
|
+
/////////////////////////////////////////////
|
|
373
389
|
|
|
374
|
-
|
|
390
|
+
var postOptions = {
|
|
391
|
+
bypassInterceptor: true
|
|
392
|
+
}
|
|
375
393
|
|
|
376
|
-
|
|
394
|
+
/////////////////////////////////////////////
|
|
377
395
|
|
|
378
|
-
|
|
396
|
+
var url = `${qik.apiURL}/user/signup`;
|
|
379
397
|
|
|
380
|
-
|
|
381
|
-
if (options.application) {
|
|
382
|
-
//The url is relative to the domain
|
|
383
|
-
url = `${qik.domain || ""}/qik/application/signup`;
|
|
384
|
-
}
|
|
398
|
+
/////////////////////////////////////////////
|
|
385
399
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
url = options.url;
|
|
389
|
-
}
|
|
400
|
+
//If we are authenticating as an application
|
|
401
|
+
if (options.application) {
|
|
390
402
|
|
|
391
|
-
|
|
403
|
+
//The url is relative to the domain
|
|
404
|
+
url = `${qik.domain || ''}/qik/application/signup`;
|
|
405
|
+
}
|
|
392
406
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
407
|
+
//If we have a specified url
|
|
408
|
+
if (options.url) {
|
|
409
|
+
url = options.url;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/////////////////////////////////////////////
|
|
413
|
+
|
|
414
|
+
qik.api.post(url, credentials, postOptions).then(function(res) {
|
|
415
|
+
|
|
416
|
+
if (autoAuthenticate) {
|
|
417
|
+
service.set(res.data);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
resolve(res);
|
|
421
|
+
}, reject);
|
|
396
422
|
}
|
|
397
423
|
|
|
398
|
-
|
|
399
|
-
}, reject);
|
|
400
|
-
}
|
|
424
|
+
//////////////////////////////////////
|
|
401
425
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
return promise;
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
///////////////////////////////////////////////////
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* @alias auth.retrieveUserFromResetToken
|
|
411
|
-
* @description Retrieve user session through use of a valid reset token,
|
|
412
|
-
* Reset tokens are short lived tokens that can be generated when a user has forgotten their password or their
|
|
413
|
-
* password has been reset by an administrator
|
|
414
|
-
* @param {String} resetToken The token to use to authenticate
|
|
415
|
-
* @param {Object} options Additional options for the request
|
|
416
|
-
* @example
|
|
417
|
-
*
|
|
418
|
-
* const resetToken = 'XXX-324623-$$...';
|
|
419
|
-
*
|
|
420
|
-
* // Retrieve the user session by providing a reset token
|
|
421
|
-
* const user = await sdk.auth.retrieveUserFromResetToken(resetToken);
|
|
422
|
-
*/
|
|
423
|
-
service.retrieveUserFromResetToken = async function (resetToken, options) {
|
|
424
|
-
if (!options) {
|
|
425
|
-
options = {};
|
|
426
|
-
}
|
|
426
|
+
return promise;
|
|
427
427
|
|
|
428
|
-
var postOptions = {
|
|
429
|
-
bypassInterceptor: true,
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
return new Promise(function (resolve, reject) {
|
|
433
|
-
qik.api
|
|
434
|
-
.get(
|
|
435
|
-
options.url || `${qik.apiURL}/user/reset/${resetToken}`,
|
|
436
|
-
postOptions,
|
|
437
|
-
)
|
|
438
|
-
.then(function (res) {
|
|
439
|
-
return resolve(res.data);
|
|
440
|
-
}, reject);
|
|
441
|
-
});
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
///////////////////////////////////////////////////
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* @alias auth.updateUserWithToken
|
|
448
|
-
* @description Update a user's credentials through use of a reset token
|
|
449
|
-
* @param {String} resetToken The token to use to authenticate
|
|
450
|
-
* @param {Object} body Updates to be made to the user
|
|
451
|
-
* @param {Object} options Additional options for the request
|
|
452
|
-
* @param {Boolean} options.disableAutoAuthentication By default the current user session
|
|
453
|
-
* will be updated automatically to reflect the new updated session, you can use this option to disable that behavior
|
|
454
|
-
* and instead return the result without dispatching any events
|
|
455
|
-
* @example
|
|
456
|
-
*
|
|
457
|
-
* const resetToken = 'XXX-324623-$$...';
|
|
458
|
-
*
|
|
459
|
-
* // Retrieve the user session by providing a reset token
|
|
460
|
-
* const user = await sdk.auth.retrieveUserFromResetToken(resetToken);
|
|
461
|
-
*/
|
|
462
|
-
service.updateUserWithToken = async function (resetToken, body, options) {
|
|
463
|
-
if (!options) {
|
|
464
|
-
options = {};
|
|
465
428
|
}
|
|
466
429
|
|
|
467
|
-
//////////////////////////
|
|
468
430
|
|
|
469
|
-
|
|
470
|
-
|
|
431
|
+
///////////////////////////////////////////////////
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* @alias auth.retrieveUserFromResetToken
|
|
435
|
+
* @description Retrieve user session through use of a valid reset token,
|
|
436
|
+
* Reset tokens are short lived tokens that can be generated when a user has forgotten their password or their
|
|
437
|
+
* password has been reset by an administrator
|
|
438
|
+
* @param {String} resetToken The token to use to authenticate
|
|
439
|
+
* @param {Object} options Additional options for the request
|
|
440
|
+
* @example
|
|
441
|
+
*
|
|
442
|
+
* const resetToken = 'XXX-324623-$$...';
|
|
443
|
+
*
|
|
444
|
+
* // Retrieve the user session by providing a reset token
|
|
445
|
+
* const user = await sdk.auth.retrieveUserFromResetToken(resetToken);
|
|
446
|
+
*/
|
|
447
|
+
service.retrieveUserFromResetToken = async function(resetToken, options) {
|
|
448
|
+
|
|
449
|
+
if (!options) {
|
|
450
|
+
options = {};
|
|
451
|
+
}
|
|
471
452
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
453
|
+
var postOptions = {
|
|
454
|
+
bypassInterceptor: true
|
|
455
|
+
}
|
|
475
456
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
qik.api
|
|
484
|
-
.post(
|
|
485
|
-
options.url || `${qik.apiURL}/user/reset/${resetToken}`,
|
|
486
|
-
body,
|
|
487
|
-
postOptions,
|
|
488
|
-
)
|
|
489
|
-
.then(function (res) {
|
|
490
|
-
//If we should automatically authenticate
|
|
491
|
-
//once the request is successful
|
|
492
|
-
//Then clear caches and update the session
|
|
493
|
-
if (autoAuthenticate) {
|
|
494
|
-
qik.cache.reset();
|
|
495
|
-
service.set(res.data);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
return resolve(res.data);
|
|
499
|
-
}, reject);
|
|
500
|
-
});
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* @alias auth.sendResetPasswordRequest
|
|
505
|
-
* @description This function allows a reset token to be generated and emailed to the requesting user
|
|
506
|
-
* allowing them to modify their user details
|
|
507
|
-
* @param {Object} body Details for the reset request
|
|
508
|
-
* @param {String} body.email The email of the user to generate a token for
|
|
509
|
-
* @example
|
|
510
|
-
*
|
|
511
|
-
* const resetToken = 'XXX-324623-$$...';
|
|
512
|
-
*
|
|
513
|
-
* // Retrieve the user session by providing a reset token
|
|
514
|
-
* const user = await sdk.auth.retrieveUserFromResetToken(resetToken);
|
|
515
|
-
*/
|
|
516
|
-
service.sendResetPasswordRequest = function (details, options) {
|
|
517
|
-
if (!options) {
|
|
518
|
-
options = {};
|
|
519
|
-
}
|
|
457
|
+
return new Promise(function(resolve, reject) {
|
|
458
|
+
qik.api.get(options.url || `${qik.apiURL}/user/reset/${resetToken}`, postOptions).then(function(res) {
|
|
459
|
+
return resolve(res.data);
|
|
460
|
+
}, reject);
|
|
461
|
+
});
|
|
520
462
|
|
|
521
|
-
if (!details) {
|
|
522
|
-
return Promise.reject({
|
|
523
|
-
message: "No details were provided for password reset request",
|
|
524
|
-
});
|
|
525
463
|
}
|
|
526
464
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
465
|
+
///////////////////////////////////////////////////
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* @alias auth.updateUserWithToken
|
|
469
|
+
* @description Update a user's credentials through use of a reset token
|
|
470
|
+
* @param {String} resetToken The token to use to authenticate
|
|
471
|
+
* @param {Object} body Updates to be made to the user
|
|
472
|
+
* @param {Object} options Additional options for the request
|
|
473
|
+
* @param {Boolean} options.disableAutoAuthentication By default the current user session
|
|
474
|
+
* will be updated automatically to reflect the new updated session, you can use this option to disable that behavior
|
|
475
|
+
* and instead return the result without dispatching any events
|
|
476
|
+
* @example
|
|
477
|
+
*
|
|
478
|
+
* const resetToken = 'XXX-324623-$$...';
|
|
479
|
+
*
|
|
480
|
+
* // Retrieve the user session by providing a reset token
|
|
481
|
+
* const user = await sdk.auth.retrieveUserFromResetToken(resetToken);
|
|
482
|
+
*/
|
|
483
|
+
service.updateUserWithToken = async function(resetToken, body, options) {
|
|
484
|
+
|
|
485
|
+
if (!options) {
|
|
486
|
+
options = {};
|
|
487
|
+
}
|
|
532
488
|
|
|
533
|
-
|
|
534
|
-
var postOptions = {
|
|
535
|
-
bypassInterceptor: true,
|
|
536
|
-
};
|
|
489
|
+
//////////////////////////
|
|
537
490
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
.then(resolve, reject);
|
|
541
|
-
});
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
///////////////////////////////////////////////////
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* @alias auth.ensureValidToken
|
|
548
|
-
* @description This function forces a check to ensure that the current access token has not expired.
|
|
549
|
-
* If the token has expired, the user session will be refreshed with a new token.
|
|
550
|
-
* @param {Boolean} forceRefresh Whether to force the current token to be refreshed, even if it has not yet expired.
|
|
551
|
-
* @example
|
|
552
|
-
*
|
|
553
|
-
* // Check to ensure that the current access token is valid
|
|
554
|
-
* sdk.auth.ensureValidToken();
|
|
555
|
-
*
|
|
556
|
-
* // Force the token to be refreshed, even if the current token in use has not yet expired.
|
|
557
|
-
* sdk.auth.ensureValidToken(true);
|
|
558
|
-
*/
|
|
559
|
-
service.ensureValidToken = async function (forceRefresh) {
|
|
560
|
-
var currentUser = service.getCurrentUser();
|
|
561
|
-
if (!currentUser) {
|
|
562
|
-
return Promise.reject("No user");
|
|
563
|
-
}
|
|
491
|
+
//Change the users current tokens straight away
|
|
492
|
+
var autoAuthenticate = true;
|
|
564
493
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
}
|
|
494
|
+
if (options.disableAutoAuthentication) {
|
|
495
|
+
autoAuthenticate = false;
|
|
496
|
+
}
|
|
569
497
|
|
|
570
|
-
|
|
498
|
+
//////////////////////////////////////
|
|
571
499
|
|
|
572
|
-
|
|
573
|
-
var now = new Date();
|
|
500
|
+
return new Promise(function(resolve, reject) {
|
|
574
501
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
502
|
+
var postOptions = {
|
|
503
|
+
bypassInterceptor: true
|
|
504
|
+
}
|
|
578
505
|
|
|
579
|
-
|
|
506
|
+
qik.api.post(options.url || `${qik.apiURL}/user/reset/${resetToken}`, body, postOptions)
|
|
507
|
+
.then(function(res) {
|
|
508
|
+
|
|
509
|
+
//If we should automatically authenticate
|
|
510
|
+
//once the request is successful
|
|
511
|
+
//Then clear caches and update the session
|
|
512
|
+
if (autoAuthenticate) {
|
|
513
|
+
qik.cache.reset();
|
|
514
|
+
service.set(res.data);
|
|
515
|
+
}
|
|
580
516
|
|
|
581
|
-
|
|
517
|
+
return resolve(res.data);
|
|
518
|
+
}, reject);
|
|
519
|
+
});
|
|
582
520
|
|
|
583
|
-
if (forceRefresh) {
|
|
584
|
-
console.log("force refresh valid token", token.refreshToken);
|
|
585
|
-
return await service.refreshAccessToken(token.refreshToken);
|
|
586
521
|
}
|
|
587
522
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
523
|
+
/**
|
|
524
|
+
* @alias auth.sendResetPasswordRequest
|
|
525
|
+
* @description This function allows a reset token to be generated and emailed to the requesting user
|
|
526
|
+
* allowing them to modify their user details
|
|
527
|
+
* @param {Object} body Details for the reset request
|
|
528
|
+
* @param {String} body.email The email of the user to generate a token for
|
|
529
|
+
* @example
|
|
530
|
+
*
|
|
531
|
+
* const resetToken = 'XXX-324623-$$...';
|
|
532
|
+
*
|
|
533
|
+
* // Retrieve the user session by providing a reset token
|
|
534
|
+
* const user = await sdk.auth.retrieveUserFromResetToken(resetToken);
|
|
535
|
+
*/
|
|
536
|
+
service.sendResetPasswordRequest = function(details, options) {
|
|
537
|
+
|
|
538
|
+
if (!options) {
|
|
539
|
+
options = {};
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (!details) {
|
|
543
|
+
return Promise.reject({
|
|
544
|
+
message: 'No details were provided for password reset request',
|
|
545
|
+
})
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (!details.email || !details.email.length) {
|
|
549
|
+
return Promise.reject({
|
|
550
|
+
message: 'Email is required but was not provided',
|
|
551
|
+
})
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
return new Promise(function(resolve, reject) {
|
|
555
|
+
|
|
556
|
+
var postOptions = {
|
|
557
|
+
bypassInterceptor: true
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
qik.api.post(options.url || `${qik.apiURL}/user/forgot`, details, postOptions).then(resolve, reject);
|
|
561
|
+
})
|
|
593
562
|
}
|
|
594
|
-
};
|
|
595
563
|
|
|
596
|
-
///////////////////////////////////////////////////
|
|
597
564
|
|
|
598
|
-
|
|
565
|
+
///////////////////////////////////////////////////
|
|
599
566
|
|
|
600
|
-
|
|
601
|
-
|
|
567
|
+
/**
|
|
568
|
+
* @alias auth.ensureValidToken
|
|
569
|
+
* @description This function forces a check to ensure that the current access token has not expired.
|
|
570
|
+
* If the token has expired, the user session will be refreshed with a new token.
|
|
571
|
+
* @param {Boolean} forceRefresh Whether to force the current token to be refreshed, even if it has not yet expired.
|
|
572
|
+
* @example
|
|
573
|
+
*
|
|
574
|
+
* // Check to ensure that the current access token is valid
|
|
575
|
+
* sdk.auth.ensureValidToken();
|
|
576
|
+
*
|
|
577
|
+
* // Force the token to be refreshed, even if the current token in use has not yet expired.
|
|
578
|
+
* sdk.auth.ensureValidToken(true);
|
|
579
|
+
*/
|
|
580
|
+
service.ensureValidToken = async function(forceRefresh) {
|
|
602
581
|
|
|
603
|
-
|
|
582
|
+
var currentUser = service.getCurrentUser();
|
|
583
|
+
if (!currentUser) {
|
|
604
584
|
|
|
605
|
-
|
|
585
|
+
return Promise.reject('No user');
|
|
586
|
+
}
|
|
606
587
|
|
|
607
|
-
|
|
588
|
+
var { token } = currentUser;
|
|
589
|
+
if (!token) {
|
|
608
590
|
|
|
609
|
-
|
|
591
|
+
return Promise.reject('No token');
|
|
592
|
+
}
|
|
610
593
|
|
|
611
|
-
|
|
612
|
-
if (refreshContext.inflightRefreshRequest) {
|
|
613
|
-
return refreshContext.inflightRefreshRequest;
|
|
614
|
-
}
|
|
594
|
+
/////////////////////////////////////////////////////
|
|
615
595
|
|
|
616
|
-
|
|
596
|
+
//Check our date
|
|
597
|
+
var now = new Date();
|
|
617
598
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
resolve,
|
|
622
|
-
reject,
|
|
623
|
-
) {
|
|
624
|
-
//Bypass the interceptor on all token refresh calls
|
|
625
|
-
//Because we don't need to add the access token etc onto it
|
|
626
|
-
|
|
627
|
-
qik.api
|
|
628
|
-
.post(
|
|
629
|
-
`/user/refresh`,
|
|
630
|
-
{
|
|
631
|
-
refreshToken: refreshToken,
|
|
632
|
-
},
|
|
633
|
-
{
|
|
634
|
-
bypassInterceptor: true,
|
|
635
|
-
withoutToken: true,
|
|
636
|
-
},
|
|
637
|
-
)
|
|
638
|
-
.then(function tokenRefreshComplete(res) {
|
|
639
|
-
//Update the user with any changes
|
|
640
|
-
//returned back from the refresh request
|
|
641
|
-
if (!res) {
|
|
642
|
-
refreshContext.inflightRefreshRequest = null;
|
|
643
|
-
return reject();
|
|
644
|
-
} else {
|
|
645
|
-
//Update with our new session
|
|
646
|
-
service.set(res.data);
|
|
647
|
-
|
|
648
|
-
dispatch();
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
//Resolve with the new token
|
|
652
|
-
resolve(res.data.token);
|
|
653
|
-
|
|
654
|
-
//Remove the inflight request
|
|
655
|
-
setTimeout(function () {
|
|
656
|
-
refreshContext.inflightRefreshRequest = null;
|
|
657
|
-
});
|
|
658
|
-
})
|
|
659
|
-
.catch(function (err) {
|
|
660
|
-
//TODO Check if invalid_refresh_token
|
|
599
|
+
//Give us a bit of buffer so that the backend doesn't beat us to
|
|
600
|
+
//retiring the token
|
|
601
|
+
now.setSeconds(now.getSeconds() + tokenBufferSeconds);
|
|
661
602
|
|
|
662
|
-
|
|
663
|
-
refreshContext.inflightRefreshRequest = null;
|
|
664
|
-
});
|
|
665
|
-
reject(err);
|
|
666
|
-
});
|
|
667
|
-
});
|
|
603
|
+
/////////////////////////////////////////////////////
|
|
668
604
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
* @example
|
|
681
|
-
*
|
|
682
|
-
* // Makes request to the API and updates the current user session to match the response
|
|
683
|
-
* sdk.auth.sync();
|
|
684
|
-
*/
|
|
685
|
-
service.sync = function () {
|
|
686
|
-
return qik.api
|
|
687
|
-
.get("/user")
|
|
688
|
-
.then(function (res) {
|
|
689
|
-
if (res.data) {
|
|
690
|
-
if (store.user) {
|
|
691
|
-
Object.assign(store.user.session, res.data);
|
|
692
|
-
}
|
|
605
|
+
var expires = new Date(token.expires);
|
|
606
|
+
|
|
607
|
+
if (forceRefresh) {
|
|
608
|
+
console.log('force refresh valid token', token.refreshToken)
|
|
609
|
+
return await service.refreshAccessToken(token.refreshToken);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
//If the token is still fresh
|
|
613
|
+
if (now < expires) {
|
|
614
|
+
|
|
615
|
+
return token;
|
|
693
616
|
} else {
|
|
694
|
-
|
|
617
|
+
|
|
618
|
+
return await service.refreshAccessToken(token.refreshToken);
|
|
695
619
|
}
|
|
696
620
|
|
|
697
|
-
retryCount = 0;
|
|
698
621
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
///////////////////////////////////////////////////
|
|
625
|
+
|
|
626
|
+
const refreshContext = {};
|
|
627
|
+
|
|
628
|
+
service.refreshAccessToken = async function(refreshToken) {
|
|
629
|
+
|
|
630
|
+
// /////////////////////////////////////////////
|
|
631
|
+
|
|
632
|
+
// if (appContext) {
|
|
633
|
+
|
|
706
634
|
// } else {
|
|
707
635
|
|
|
708
|
-
// retryCount++;
|
|
709
|
-
// service.sync();
|
|
710
636
|
// }
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
637
|
+
|
|
638
|
+
// /////////////////////////////////////////////
|
|
639
|
+
|
|
640
|
+
//If there is already a request in progress
|
|
641
|
+
if (refreshContext.inflightRefreshRequest) {
|
|
642
|
+
|
|
643
|
+
return refreshContext.inflightRefreshRequest;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/////////////////////////////////////////////////////
|
|
647
|
+
|
|
648
|
+
//Create an refresh request
|
|
649
|
+
|
|
650
|
+
refreshContext.inflightRefreshRequest = new Promise(function(resolve, reject) {
|
|
651
|
+
|
|
652
|
+
//Bypass the interceptor on all token refresh calls
|
|
653
|
+
//Because we don't need to add the access token etc onto it
|
|
654
|
+
|
|
655
|
+
qik.api.post(`/user/refresh`, {
|
|
656
|
+
refreshToken: refreshToken
|
|
657
|
+
}, {
|
|
658
|
+
bypassInterceptor: true,
|
|
659
|
+
withoutToken: true,
|
|
660
|
+
})
|
|
661
|
+
.then(function tokenRefreshComplete(res) {
|
|
662
|
+
|
|
663
|
+
//Update the user with any changes
|
|
664
|
+
//returned back from the refresh request
|
|
665
|
+
if (!res) {
|
|
666
|
+
|
|
667
|
+
refreshContext.inflightRefreshRequest = null;
|
|
668
|
+
return reject();
|
|
669
|
+
|
|
670
|
+
} else {
|
|
671
|
+
//Update with our new session
|
|
672
|
+
service.set(res.data);
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
dispatch();
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
//Resolve with the new token
|
|
679
|
+
resolve(res.data.token);
|
|
680
|
+
|
|
681
|
+
//Remove the inflight request
|
|
682
|
+
setTimeout(function() {
|
|
683
|
+
refreshContext.inflightRefreshRequest = null;
|
|
684
|
+
})
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
})
|
|
688
|
+
.catch(function(err) {
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
//TODO Check if invalid_refresh_token
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
setTimeout(function() {
|
|
696
|
+
refreshContext.inflightRefreshRequest = null;
|
|
697
|
+
});
|
|
698
|
+
reject(err);
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
//Return the refresh request
|
|
706
|
+
return refreshContext.inflightRefreshRequest;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
///////////////////////////////////////////////////
|
|
710
|
+
|
|
711
|
+
var retryCount = 0;
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* @alias auth.sync
|
|
715
|
+
* @description A useful function to sync the current user session with the server.
|
|
716
|
+
* @example
|
|
717
|
+
*
|
|
718
|
+
* // Makes request to the API and updates the current user session to match the response
|
|
719
|
+
* sdk.auth.sync();
|
|
720
|
+
*/
|
|
721
|
+
service.sync = function() {
|
|
722
|
+
|
|
723
|
+
return qik.api.get('/user')
|
|
724
|
+
.then(function(res) {
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
if (res.data) {
|
|
728
|
+
if (store.user) {
|
|
729
|
+
Object.assign(store.user.session, res.data);
|
|
730
|
+
}
|
|
731
|
+
} else {
|
|
732
|
+
service.set(null);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
retryCount = 0;
|
|
737
|
+
|
|
738
|
+
dispatch();
|
|
739
|
+
})
|
|
740
|
+
.catch(function(err) {
|
|
741
|
+
|
|
742
|
+
// if (retryCount > 2) {
|
|
743
|
+
service.set(null);
|
|
744
|
+
retryCount = 0;
|
|
745
|
+
dispatch();
|
|
746
|
+
// } else {
|
|
747
|
+
|
|
748
|
+
// retryCount++;
|
|
749
|
+
// service.sync();
|
|
750
|
+
// }
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/////////////////////////////////////////////////////
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* @alias auth.getCurrentUser
|
|
760
|
+
* @description Retrieves the current user session
|
|
761
|
+
* @example
|
|
762
|
+
*
|
|
763
|
+
* const me = sdk.auth.getCurrentUser();
|
|
764
|
+
*/
|
|
765
|
+
service.getCurrentUser = function() {
|
|
766
|
+
return store.user;
|
|
748
767
|
}
|
|
749
768
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* @alias auth.getCurrentToken
|
|
772
|
+
* @description Retrieves the current access token. If the user is authenticated
|
|
773
|
+
* the response will be the current user's access token, otherwise will fall back to the
|
|
774
|
+
* applications token.
|
|
775
|
+
* @example
|
|
776
|
+
* const currentAccessToken = sdk.auth.getCurrentToken();
|
|
777
|
+
*/
|
|
778
|
+
service.getCurrentToken = function() {
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
var user = service.getCurrentUser();
|
|
782
|
+
|
|
783
|
+
//User is not logged in
|
|
784
|
+
if (!user) {
|
|
785
|
+
|
|
786
|
+
//But there is an application token
|
|
787
|
+
if (qik.applicationToken) {
|
|
788
|
+
//use that instead
|
|
789
|
+
return qik.applicationToken;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
//No token
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
var { token } = user;
|
|
797
|
+
if (!token) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
return token.accessToken;
|
|
802
|
+
|
|
753
803
|
}
|
|
754
804
|
|
|
755
|
-
|
|
756
|
-
|
|
805
|
+
/////////////////////////////////////////////////////
|
|
806
|
+
|
|
807
|
+
qik.api.interceptors.request.use(async function(config) {
|
|
808
|
+
|
|
809
|
+
//If we want to bypass the interceptor
|
|
810
|
+
//then just return the request
|
|
811
|
+
if (config.bypassInterceptor) {
|
|
812
|
+
return config;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
//////////////////////////////
|
|
816
|
+
|
|
817
|
+
//Get the original request
|
|
818
|
+
var originalRequest = config;
|
|
819
|
+
|
|
820
|
+
//////////////////////////////
|
|
821
|
+
|
|
822
|
+
var userDetails = await service.getCurrentUser();
|
|
823
|
+
var accessToken;
|
|
824
|
+
var refreshToken;
|
|
825
|
+
var expiryDate;
|
|
826
|
+
|
|
827
|
+
if (userDetails) {
|
|
828
|
+
var { token } = userDetails;
|
|
829
|
+
if (token) {
|
|
830
|
+
accessToken = token.accessToken;
|
|
831
|
+
refreshToken = token.refreshToken;
|
|
832
|
+
expiryDate = token.expires;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
//////////////////////////////
|
|
837
|
+
|
|
838
|
+
//If there is a user token
|
|
839
|
+
if (accessToken) {
|
|
840
|
+
//Set the token of the request as the user's access token
|
|
841
|
+
originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
} else {
|
|
845
|
+
//Return the original request without a token
|
|
846
|
+
|
|
847
|
+
return originalRequest;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/////////////////////////////////////////////////////
|
|
757
851
|
|
|
758
|
-
|
|
852
|
+
//If no refresh token
|
|
853
|
+
if (!refreshToken) {
|
|
759
854
|
|
|
760
|
-
qik.api.interceptors.request.use(
|
|
761
|
-
async function (config) {
|
|
762
|
-
//If we want to bypass the interceptor
|
|
763
|
-
//then just return the request
|
|
764
|
-
if (config.bypassInterceptor) {
|
|
765
|
-
return config;
|
|
766
|
-
}
|
|
767
855
|
|
|
768
|
-
|
|
856
|
+
//Continue with the original request
|
|
857
|
+
return originalRequest;
|
|
858
|
+
}
|
|
769
859
|
|
|
770
|
-
|
|
771
|
-
var originalRequest = config;
|
|
860
|
+
/////////////////////////////////////////////////////
|
|
772
861
|
|
|
773
|
-
|
|
862
|
+
//We have a refresh token so we need to check
|
|
863
|
+
//whether our access token is stale and needs to be refreshed
|
|
864
|
+
var now = new Date();
|
|
774
865
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
var expiryDate;
|
|
866
|
+
//Give us a bit of buffer so that the backend doesn't beat us to
|
|
867
|
+
//retiring the token
|
|
868
|
+
now.setSeconds(now.getSeconds() + tokenBufferSeconds);
|
|
779
869
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
870
|
+
/////////////////////////////////////////////////////
|
|
871
|
+
|
|
872
|
+
var expires = new Date(expiryDate);
|
|
873
|
+
|
|
874
|
+
//If the token is still fresh
|
|
875
|
+
if (now < expires) {
|
|
876
|
+
//Return the original request
|
|
877
|
+
return originalRequest;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/////////////////////////////////////////////////////
|
|
881
|
+
|
|
882
|
+
return new Promise(async function(resolve, reject) {
|
|
883
|
+
|
|
884
|
+
//Refresh the token
|
|
885
|
+
await service.refreshAccessToken(refreshToken)
|
|
886
|
+
.then(function(newToken) {
|
|
887
|
+
|
|
888
|
+
//Update the original request with our new token
|
|
889
|
+
originalRequest.headers['Authorization'] = `Bearer ${newToken}`;
|
|
890
|
+
//And continue onward
|
|
891
|
+
return resolve(originalRequest);
|
|
892
|
+
})
|
|
893
|
+
.catch(function(err) {
|
|
894
|
+
|
|
895
|
+
return reject(err);
|
|
896
|
+
});
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
},
|
|
901
|
+
function(error) {
|
|
902
|
+
return Promise.reject(error);
|
|
903
|
+
})
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
/////////////////////////////////////////////////////
|
|
908
|
+
|
|
909
|
+
qik.api.interceptors.response.use(function(response) {
|
|
910
|
+
return response;
|
|
911
|
+
}, function(err) {
|
|
912
|
+
|
|
913
|
+
//////////////////////////////
|
|
914
|
+
|
|
915
|
+
//Get the response status
|
|
916
|
+
var status = (err && err.response && err.response.status) || err.status;
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
switch (status) {
|
|
920
|
+
case 401:
|
|
921
|
+
service.logout();
|
|
922
|
+
break;
|
|
923
|
+
default:
|
|
924
|
+
//Some other error
|
|
925
|
+
break;
|
|
786
926
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
/////////////////////////////////////////////////////
|
|
802
|
-
|
|
803
|
-
//If no refresh token
|
|
804
|
-
if (!refreshToken) {
|
|
805
|
-
//Continue with the original request
|
|
806
|
-
return originalRequest;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
/////////////////////////////////////////////////////
|
|
810
|
-
|
|
811
|
-
//We have a refresh token so we need to check
|
|
812
|
-
//whether our access token is stale and needs to be refreshed
|
|
813
|
-
var now = new Date();
|
|
814
|
-
|
|
815
|
-
//Give us a bit of buffer so that the backend doesn't beat us to
|
|
816
|
-
//retiring the token
|
|
817
|
-
now.setSeconds(now.getSeconds() + tokenBufferSeconds);
|
|
818
|
-
|
|
819
|
-
/////////////////////////////////////////////////////
|
|
820
|
-
|
|
821
|
-
var expires = new Date(expiryDate);
|
|
822
|
-
|
|
823
|
-
//If the token is still fresh
|
|
824
|
-
if (now < expires) {
|
|
825
|
-
//Return the original request
|
|
826
|
-
return originalRequest;
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
/////////////////////////////////////////////////////
|
|
830
|
-
|
|
831
|
-
return new Promise(async function (resolve, reject) {
|
|
832
|
-
//Refresh the token
|
|
833
|
-
await service
|
|
834
|
-
.refreshAccessToken(refreshToken)
|
|
835
|
-
.then(function (newToken) {
|
|
836
|
-
//Update the original request with our new token
|
|
837
|
-
originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
|
|
838
|
-
//And continue onward
|
|
839
|
-
return resolve(originalRequest);
|
|
840
|
-
})
|
|
841
|
-
.catch(function (err) {
|
|
842
|
-
return reject(err);
|
|
843
|
-
});
|
|
844
|
-
});
|
|
845
|
-
},
|
|
846
|
-
function (error) {
|
|
847
|
-
return Promise.reject(error);
|
|
848
|
-
},
|
|
849
|
-
);
|
|
850
|
-
|
|
851
|
-
/////////////////////////////////////////////////////
|
|
852
|
-
|
|
853
|
-
qik.api.interceptors.response.use(
|
|
854
|
-
function (response) {
|
|
855
|
-
return response;
|
|
856
|
-
},
|
|
857
|
-
function (err) {
|
|
858
|
-
//////////////////////////////
|
|
859
|
-
|
|
860
|
-
//Get the response status
|
|
861
|
-
var status = (err && err.response && err.response.status) || err.status;
|
|
862
|
-
|
|
863
|
-
switch (status) {
|
|
864
|
-
case 401:
|
|
865
|
-
service.logout();
|
|
866
|
-
break;
|
|
867
|
-
default:
|
|
868
|
-
//Some other error
|
|
869
|
-
break;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
/////////////////////////////////////////////////////
|
|
873
|
-
|
|
874
|
-
return Promise.reject(err);
|
|
875
|
-
},
|
|
876
|
-
);
|
|
877
|
-
|
|
878
|
-
return service;
|
|
879
|
-
};
|
|
880
|
-
|
|
881
|
-
export default QikAuth;
|
|
927
|
+
|
|
928
|
+
/////////////////////////////////////////////////////
|
|
929
|
+
|
|
930
|
+
return Promise.reject(err);
|
|
931
|
+
})
|
|
932
|
+
|
|
933
|
+
return service;
|
|
934
|
+
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
export default QikAuth;
|