@qikdev/sdk 0.1.14 → 0.1.18

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.
@@ -54,6 +54,18 @@ var QikAPI = function(qik) {
54
54
  const defaultAdapter = axios.defaults.adapter
55
55
  // console.log('DEFAULT ADAPTER', defaultAdapter)
56
56
 
57
+ /////////////////////////////////////////////////////
58
+
59
+ function getRequestCacheKey(config) {
60
+
61
+ var key = _.compact([
62
+ config.method,
63
+ config.url,
64
+ JSON.stringify({ user: qik.auth.getCurrentUser(), params: config.params, data: config.data }),
65
+ ]).join('-')
66
+
67
+ return key;
68
+ }
57
69
 
58
70
  ///////////////////////////////////////
59
71
 
@@ -96,7 +108,7 @@ var QikAPI = function(qik) {
96
108
  if (useCache) {
97
109
 
98
110
  //Generate the cache key from the request
99
- var cacheKey = getCacheKeyFromConfig(config);
111
+ var cacheKey = getRequestCacheKey(config);
100
112
 
101
113
  //If we have the cachedResponse version
102
114
  cachedResponse = useCache.get(cacheKey);
@@ -146,6 +158,26 @@ var QikAPI = function(qik) {
146
158
 
147
159
  //////////////////////////////////////////////////////////////////////////////
148
160
 
161
+ service.generateEndpointURL = function(endpoint, params, options) {
162
+ options = options || {}
163
+
164
+ //Append the access token to the url
165
+ if(!options.withoutToken) {
166
+ params.access_token = qik.auth.getCurrentToken();
167
+ }
168
+
169
+ var stripLeadingTag = endpoint[0] == '/' ? endpoint.slice(1) : endpoint;
170
+ return `${qik.apiURL}${endpoint}?${qik.utils.mapParameters(params)}`
171
+ }
172
+
173
+ //////////////////////////////////////////////////////////////////////////////
174
+
175
+ service.wasCancelled = function(err) {
176
+ return axios.isCancel(err);
177
+ }
178
+
179
+ //////////////////////////////////////////////////////////////////////////////
180
+
149
181
  function createNewAxios(adapter) {
150
182
 
151
183
  var instance = axios.create({
@@ -165,6 +197,10 @@ var QikAPI = function(qik) {
165
197
  // Add relative date and timezone to every request
166
198
  instance.interceptors.request.use(function(config) {
167
199
 
200
+ if (config.withoutToken) {
201
+ return config;
202
+ }
203
+
168
204
  config.headers['qik-request-date'] = new Date().getTime();
169
205
  if (Intl) {
170
206
  config.headers['qik-request-timezone'] = Intl.DateTimeFormat().resolvedOptions().timeZone;
@@ -172,8 +208,18 @@ var QikAPI = function(qik) {
172
208
 
173
209
  config.headers['qik-api-version'] = version;
174
210
 
175
- return config;
176
211
 
212
+ var token = qik.auth.getCurrentToken();
213
+
214
+ if (token) {
215
+ config.headers['Authorization'] = `Bearer ${token}`;
216
+
217
+ if (config.params && config.params.access_token) {
218
+ delete config.params.access_token;
219
+ }
220
+ }
221
+
222
+ return config;
177
223
  });
178
224
 
179
225
  /////////////////////////////////////////////////////
@@ -184,7 +230,6 @@ var QikAPI = function(qik) {
184
230
  }, function(err) {
185
231
 
186
232
  if (axios.isCancel(err)) {
187
- console.log('Request cancelled');
188
233
  return Promise.reject(err);
189
234
  }
190
235
 
@@ -199,7 +244,7 @@ var QikAPI = function(qik) {
199
244
  case 502:
200
245
  case 504:
201
246
  //Retry until it works
202
- console.log(`qik.api > ${status} connection error retrying`)
247
+ // console.log(`qik.api > ${status} connection error retrying`)
203
248
  return instance.request(err.config);
204
249
  break;
205
250
  case 404:
@@ -207,7 +252,7 @@ var QikAPI = function(qik) {
207
252
  break;
208
253
  default:
209
254
  //Some other error, likely a problem connecting to the server
210
- console.log('qik.api > connection error', status, err);
255
+ // console.log('qik.api > connection error', status, err);
211
256
  break;
212
257
  }
213
258
 
@@ -302,67 +347,7 @@ var QikAPI = function(qik) {
302
347
  */
303
348
 
304
349
 
305
-
306
- ///////////////////////////////////////////////////
307
-
308
- /**
309
- * A helper function for generating an authenticated url for the current user
310
- * @param {string} endpoint The id of the asset, or the asset object you want to download
311
- * @alias api.generateEndpointURL
312
- * @param {object} params
313
- * @return {string} A full URL with relevant parameters included
314
- * @example
315
- * // returns 'https://api.qik.io/something?access_token=2352345...'
316
- * qik.api.generateEndpointURL('/something');
317
- */
318
-
319
- service.generateEndpointURL = function(path, params) {
320
-
321
- if (!path || !String(path).length) {
322
- return;
323
- }
324
-
325
- if (!params) {
326
- params = {};
327
- }
328
-
329
- var url = `${qik.apiURL}${path}`;
330
-
331
- ////////////////////////////////////////
332
-
333
- url = parameterDefaults(url, params);
334
-
335
- ////////////////////////////////////////
336
-
337
- //Map the parameters to a query string
338
- var queryParameters = qik.utils.mapParameters(params);
339
-
340
- if (queryParameters.length) {
341
- url += '?' + queryParameters;
342
- }
343
-
344
- return url;
345
-
346
- }
347
-
348
- ///////////////////////////////////////////////////////
349
-
350
- function parameterDefaults(url, params) {
351
-
352
- //If we haven't requested without token
353
- if (!params.withoutToken) {
354
- //Get the current token from QikAuth
355
- var CurrentQikToken = qik.auth.getCurrentToken();
356
-
357
- //Check to see if we have a token and none has been explicity set
358
- if (!params['access_token'] && CurrentQikToken) {
359
- //Use the current token by default
360
- params['access_token'] = CurrentQikToken;
361
- }
362
- }
363
-
364
- return url;
365
- }
350
+
366
351
 
367
352
 
368
353
  /////////////////////////////////////////////////////
@@ -1,5 +1,4 @@
1
1
  import axios from 'axios';
2
- import _ from 'lodash';
3
2
  import { EventDispatcher } from './qik.utils.js';
4
3
 
5
4
  ///////////////////////////////////////////////////
@@ -25,6 +24,7 @@ var QikAuth = function(qik) {
25
24
 
26
25
  var defaultStore = {};
27
26
  var store = defaultStore;
27
+ const tokenBufferSeconds = 10;
28
28
 
29
29
  ///////////////////////////////////////////////////
30
30
  ///////////////////////////////////////////////////
@@ -43,7 +43,6 @@ var QikAuth = function(qik) {
43
43
  var dispatcher = new EventDispatcher();
44
44
  dispatcher.bootstrap(service);
45
45
 
46
- // console.log('New Dispatcher!', dispatcher)
47
46
 
48
47
  ///////////////////////////////////////////////////
49
48
  ///////////////////////////////////////////////////
@@ -62,13 +61,6 @@ var QikAuth = function(qik) {
62
61
  dispatcher.dispatch('change', user, parameters);
63
62
  }
64
63
 
65
- ///////////////////////////////////////////////////
66
-
67
- function log(message) {
68
- if (service.debug) {
69
- console.log(message);
70
- }
71
- }
72
64
 
73
65
  ///////////////////////////////////////////////////
74
66
 
@@ -86,12 +78,11 @@ var QikAuth = function(qik) {
86
78
 
87
79
  store.user = user;
88
80
 
89
- log('qik.auth > user set');
81
+
90
82
  return dispatch(parameters)
91
83
  }
92
84
 
93
85
 
94
-
95
86
  ///////////////////////////////////////////////////
96
87
 
97
88
  /**
@@ -114,7 +105,7 @@ var QikAuth = function(qik) {
114
105
 
115
106
 
116
107
 
117
- log('qik.auth > user logout');
108
+
118
109
 
119
110
 
120
111
  if (qik.withCredentials) {
@@ -262,7 +253,7 @@ var QikAuth = function(qik) {
262
253
  * @param {Object} options.disableAutoAuthentication Disable automatic authentication, if true, will not set the current user session
263
254
  * @return {Promise} Returns a promise that either resolves with the logged in user session, or rejects with the responding error from the server
264
255
  */
265
- service.login = function(credentials, options) {
256
+ service.login = async function(credentials, options) {
266
257
 
267
258
  if (!options) {
268
259
  options = {};
@@ -324,7 +315,7 @@ var QikAuth = function(qik) {
324
315
 
325
316
  if (autoAuthenticate) {
326
317
  store.user = res.data;
327
- // console.log('Persist user', store.user)
318
+
328
319
  dispatch();
329
320
  // if (service.onChange) {
330
321
  // service.onChange(store.user);
@@ -359,7 +350,7 @@ var QikAuth = function(qik) {
359
350
  * @param {Object} options Extra options and configuration for the request
360
351
  * @return {Promise} Returns a promise that either resolves to the new authenticated session, or rejects with the responding error from the server
361
352
  */
362
- service.signup = function(credentials, options) {
353
+ service.signup = async function(credentials, options) {
363
354
 
364
355
  if (!options) {
365
356
  options = {};
@@ -479,7 +470,7 @@ var QikAuth = function(qik) {
479
470
  * If not specified or false, will assume it's a Qik global user that is resetting their password.
480
471
  * @return {Promise} Returns a promise that resolves with the reset session details
481
472
  */
482
- service.retrieveUserFromResetToken = function(resetToken, options) {
473
+ service.retrieveUserFromResetToken = async function(resetToken, options) {
483
474
 
484
475
  if (!options) {
485
476
  options = {};
@@ -526,7 +517,7 @@ var QikAuth = function(qik) {
526
517
  * @param {Object} options other options for the request
527
518
  * @return {Promise} Returns a promise that resolves with the reset session details
528
519
  */
529
- service.updateUserWithToken = function(resetToken, body, options) {
520
+ service.updateUserWithToken = async function(resetToken, body, options) {
530
521
 
531
522
  if (!options) {
532
523
  options = {};
@@ -653,6 +644,49 @@ var QikAuth = function(qik) {
653
644
  }
654
645
 
655
646
 
647
+ ///////////////////////////////////////////////////
648
+
649
+ service.ensureValidToken = async function() {
650
+
651
+
652
+
653
+ var currentUser = service.getCurrentUser();
654
+ if (!currentUser) {
655
+
656
+ return Promise.reject('No user');
657
+ }
658
+
659
+ var { token } = currentUser;
660
+ if (!token) {
661
+
662
+ return Promise.reject('No token');
663
+ }
664
+
665
+ /////////////////////////////////////////////////////
666
+
667
+ //Check our date
668
+ var now = new Date();
669
+
670
+ //Give us a bit of buffer so that the backend doesn't beat us to
671
+ //retiring the token
672
+ now.setSeconds(now.getSeconds() + tokenBufferSeconds);
673
+
674
+ /////////////////////////////////////////////////////
675
+
676
+ var expires = new Date(token.expires);
677
+
678
+ //If the token is still fresh
679
+ if (now < expires) {
680
+
681
+ return token;
682
+ } else {
683
+
684
+ return await service.refreshAccessToken(token.refreshToken);
685
+ }
686
+
687
+
688
+ }
689
+
656
690
  ///////////////////////////////////////////////////
657
691
 
658
692
  /**
@@ -666,57 +700,55 @@ var QikAuth = function(qik) {
666
700
 
667
701
  const refreshContext = {};
668
702
 
669
-
670
- service.refreshAccessToken = function(refreshToken) {
703
+ service.refreshAccessToken = async function(refreshToken) {
671
704
 
672
705
  // /////////////////////////////////////////////
673
706
 
674
707
  // if (appContext) {
675
- // console.log('refresh token in app context')
708
+
676
709
  // } else {
677
- // console.log('refresh token in normal context')
710
+
678
711
  // }
679
712
 
680
713
  // /////////////////////////////////////////////
681
714
 
682
715
  //If there is already a request in progress
683
716
  if (refreshContext.inflightRefreshRequest) {
684
- log(`qik.auth > use inflight request`);
717
+
685
718
  return refreshContext.inflightRefreshRequest;
686
719
  }
687
720
 
688
721
  /////////////////////////////////////////////////////
689
722
 
690
723
  //Create an refresh request
691
- log(`qik.auth > refresh token new request`);
724
+
692
725
  refreshContext.inflightRefreshRequest = new Promise(function(resolve, reject) {
693
726
 
694
727
 
695
- log(`qik.auth > refresh token ${refreshToken}`);
728
+
696
729
 
697
730
  //Bypass the interceptor on all token refresh calls
698
731
  //Because we don't need to add the access token etc onto it
732
+
699
733
  qik.api.post(`/user/refresh`, {
700
734
  refreshToken: refreshToken
701
735
  }, {
702
736
  bypassInterceptor: true,
737
+ withoutToken: true,
703
738
  })
704
739
  .then(function tokenRefreshComplete(res) {
705
740
 
706
741
  //Update the user with any changes
707
742
  //returned back from the refresh request
708
743
  if (!res) {
709
- log('qik.auth > no res');
744
+
710
745
  refreshContext.inflightRefreshRequest = null;
711
746
  return reject();
712
747
 
713
748
  } else {
714
- if (store.user) {
715
- Object.assign(store.user, res.data);
716
- } else {
717
- store.user = res.data;
718
- }
719
- log(`qik.auth > token refreshed > ${res.data}`);
749
+ //Update with our new session
750
+ store.user = res.data;
751
+
720
752
 
721
753
  dispatch();
722
754
  }
@@ -732,11 +764,11 @@ var QikAuth = function(qik) {
732
764
 
733
765
  })
734
766
  .catch(function(err) {
735
- console.log('TOKEN REFRESH FAILED', err);
767
+
736
768
 
737
769
  //TODO Check if invalid_refresh_token
738
770
 
739
- //console.log('Refresh request Failed')
771
+
740
772
  setTimeout(function() {
741
773
  refreshContext.inflightRefreshRequest = null;
742
774
  });
@@ -769,32 +801,31 @@ var QikAuth = function(qik) {
769
801
 
770
802
  service.sync = function() {
771
803
 
772
- // console.log('Sync with server', store.user)
773
804
  return qik.api.get('/user')
774
805
  .then(function(res) {
775
806
 
776
- // console.log('sync response', res);
777
807
 
778
808
  if (res.data) {
779
809
  if (store.user) {
780
- Object.assign(store.user, res.data);
810
+ Object.assign(store.user.session, res.data);
781
811
  }
782
812
  } else {
783
813
  store.user = null;
784
814
  }
785
- log('qik.auth > server session refreshed');
815
+
816
+
786
817
  retryCount = 0;
787
818
 
788
819
  dispatch();
789
820
  })
790
821
  .catch(function(err) {
822
+
791
823
  // if (retryCount > 2) {
792
- console.log('auth sync not logged in');
793
824
  store.user = null;
794
825
  retryCount = 0;
795
826
  dispatch();
796
827
  // } else {
797
- // console.log('Retry sync')
828
+
798
829
  // retryCount++;
799
830
  // service.sync();
800
831
  // }
@@ -815,104 +846,129 @@ var QikAuth = function(qik) {
815
846
  }
816
847
 
817
848
 
818
- service.getCurrentToken = function() {
819
- return service.getCurrentUser().accessToken;
849
+ service.getCurrentToken = function(ensureFresh) {
850
+
851
+ var details = service.getCurrentUser();
852
+
853
+ if (!details) {
854
+ return;
855
+ }
856
+
857
+ var { token } = details;
858
+ if (!token) {
859
+ return;
860
+ }
861
+
862
+ return token.accessToken;
863
+
820
864
  }
821
865
 
822
866
  /////////////////////////////////////////////////////
823
867
 
824
- qik.api.interceptors.request.use(function(config) {
868
+ qik.api.interceptors.request.use(async function(config) {
825
869
 
826
- //If we want to bypass the interceptor
827
- //then just return the request
828
- if (config.bypassInterceptor) {
829
- console.log('auth interceptor was bypassed');
830
- return config;
831
- }
870
+ //If we want to bypass the interceptor
871
+ //then just return the request
872
+ if (config.bypassInterceptor) {
873
+ return config;
874
+ }
832
875
 
833
- //////////////////////////////
834
- //////////////////////////////
835
- //////////////////////////////
836
- //////////////////////////////
876
+ //////////////////////////////
877
+ //////////////////////////////
878
+ //////////////////////////////
879
+ //////////////////////////////
837
880
 
838
- //Get the original request
839
- var originalRequest = config;
881
+ //Get the original request
882
+ var originalRequest = config;
840
883
 
841
- //If we aren't logged in or don't have a token
842
- var accessToken = _.get(store, 'user.accessToken');
843
- var refreshToken = _.get(store, 'user.refreshToken');
884
+ //////////////////////////////
844
885
 
845
- //////////////////////////////
886
+ var userDetails = await service.getCurrentUser();
887
+ var accessToken;
888
+ var refreshToken;
889
+ var expiryDate;
846
890
 
847
- //If there is a user token
848
- if (accessToken) {
849
- //Set the token of the request as the user's access token
850
- originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;
851
- log('qik.auth > using user token');
891
+ if (userDetails) {
892
+ var { token } = userDetails;
893
+ if (token) {
894
+ accessToken = token.accessToken;
895
+ refreshToken = token.refreshToken;
896
+ expiryDate = token.expires;
897
+ }
898
+ }
852
899
 
853
- } else {
854
- //Return the original request without a token
855
- log('qik.auth > no token');
856
- return originalRequest;
857
- }
900
+ //////////////////////////////
858
901
 
859
- /////////////////////////////////////////////////////
902
+ //If there is a user token
903
+ if (accessToken) {
904
+ //Set the token of the request as the user's access token
905
+ originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;
906
+
860
907
 
861
- //If no refresh token
862
- if (!refreshToken) {
863
- log('qik.auth > no refresh token');
908
+ } else {
909
+ //Return the original request without a token
910
+
911
+ return originalRequest;
912
+ }
864
913
 
865
- //Continue with the original request
866
- return originalRequest;
867
- }
914
+ /////////////////////////////////////////////////////
868
915
 
869
- /////////////////////////////////////////////////////
916
+ //If no refresh token
917
+ if (!refreshToken) {
918
+
870
919
 
871
- //We have a refresh token so we need to check
872
- //whether our access token is stale and needs to be refreshed
873
- var now = new Date();
920
+ //Continue with the original request
921
+ return originalRequest;
922
+ }
874
923
 
875
- //Give us a bit of buffer incase some of our images
876
- //are still loading
877
- now.setSeconds(now.getSeconds() + 10);
924
+ /////////////////////////////////////////////////////
878
925
 
879
- /////////////////////////////////////////////////////
926
+ //We have a refresh token so we need to check
927
+ //whether our access token is stale and needs to be refreshed
928
+ var now = new Date();
880
929
 
881
- var expiryDate = _.get(store, 'user.expires');
882
- var expires = new Date(expiryDate);
930
+ //Give us a bit of buffer so that the backend doesn't beat us to
931
+ //retiring the token
932
+ now.setSeconds(now.getSeconds() + tokenBufferSeconds);
883
933
 
884
- //If the token is still fresh
885
- if (now < expires) {
886
- //Return the original request
887
- return originalRequest;
888
- }
889
-
890
- /////////////////////////////////////////////////////
934
+ /////////////////////////////////////////////////////
891
935
 
892
- log('qik.auth > token expired');
936
+ var expires = new Date(expiryDate);
893
937
 
894
- return new Promise(function(resolve, reject) {
938
+ //If the token is still fresh
939
+ if (now < expires) {
940
+ //Return the original request
941
+ return originalRequest;
942
+ }
895
943
 
896
- //Refresh the token
897
- service.refreshAccessToken(refreshToken)
898
- .then(function(newToken) {
899
- log('qik.auth > token refreshed', isManagedUser);
900
- //Update the original request with our new token
901
- originalRequest.headers['Authorization'] = `Bearer ${newToken}`;
902
- //And continue onward
903
- return resolve(originalRequest);
904
- })
905
- .catch(function(err) {
906
- console.log('ERRRRRR', err);
907
- log('qik.auth > token refresh rejected', err);
908
- return reject(err);
909
- });
910
- });
944
+ /////////////////////////////////////////////////////
945
+
946
+
947
+
948
+ return new Promise(async function(resolve, reject) {
949
+
950
+ //Refresh the token
951
+ await service.refreshAccessToken(refreshToken)
952
+ .then(function(newToken) {
953
+
954
+ //Update the original request with our new token
955
+ originalRequest.headers['Authorization'] = `Bearer ${newToken}`;
956
+ //And continue onward
957
+ return resolve(originalRequest);
958
+ })
959
+ .catch(function(err) {
960
+
961
+ return reject(err);
962
+ });
963
+ });
964
+
965
+
966
+ },
967
+ function(error) {
968
+ return Promise.reject(error);
969
+ })
911
970
 
912
971
 
913
- }, function(error) {
914
- return Promise.reject(error);
915
- })
916
972
 
917
973
  /////////////////////////////////////////////////////
918
974
 
@@ -923,12 +979,11 @@ var QikAuth = function(qik) {
923
979
  //////////////////////////////
924
980
 
925
981
  //Get the response status
926
- var status = _.get(err, 'response.status') || err.status;
982
+ var status = (err && err.response && err.response.status) || err.status;
927
983
 
928
- log('qik.auth > error', status);
984
+
929
985
  switch (status) {
930
986
  case 401:
931
- console.log('logout from 401')
932
987
  service.logout();
933
988
  break;
934
989
  default: