@dronedeploy/rocos-js-sdk 4.4.11 → 4.4.12

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.
@@ -6,6 +6,7 @@ export declare class AuthService extends BaseServiceAbstract implements IBaseSer
6
6
  private token?;
7
7
  private tokenRefreshTimeoutId?;
8
8
  private tokenSubject$;
9
+ private pendingTokenRequest?;
9
10
  constructor(config: IRocosSDKConfig);
10
11
  /** Observable for token updates
11
12
  *
@@ -54,6 +55,8 @@ export declare class AuthService extends BaseServiceAbstract implements IBaseSer
54
55
  * This will return the current token if it is not expired, otherwise it will get a new token based on your config.
55
56
  */
56
57
  getToken(): Promise<Token>;
58
+ private getOrRequestToken;
59
+ private fetchNewToken;
57
60
  /**
58
61
  * Refresh the authentication token
59
62
  *
@@ -50,25 +50,27 @@ class AuthService extends BaseServiceAbstract_1.BaseServiceAbstract {
50
50
  if (expiresIn !== undefined) {
51
51
  this.logger.warn('setToken(value, expiresIn) is deprecated. Use setToken(value) instead');
52
52
  }
53
- if (typeof value === 'string') {
54
- this.token = new models_1.Token(value);
55
- }
56
- else {
57
- this.token = value;
53
+ const token = typeof value === 'string' ? new models_1.Token(value) : value;
54
+ if (token.value !== this.token?.value) {
55
+ this.pendingTokenRequest = undefined;
58
56
  }
57
+ this.token = token;
59
58
  this.config.token = this.token.value;
60
59
  // output a message for token change
61
60
  if (this.isTokenValid(this.token)) {
62
61
  this.tokenSubject$.next(this.token);
63
62
  }
64
63
  else {
65
- void this.getToken();
64
+ void this.getToken().catch((error) => {
65
+ this.logger.error('Failed to initialize auth token', error);
66
+ });
66
67
  }
67
68
  }
68
69
  /**
69
70
  * Clear token
70
71
  */
71
72
  clearToken() {
73
+ this.pendingTokenRequest = undefined;
72
74
  this.token = undefined;
73
75
  this.config.token = undefined;
74
76
  }
@@ -125,15 +127,38 @@ class AuthService extends BaseServiceAbstract_1.BaseServiceAbstract {
125
127
  * This will return the current token if it is not expired, otherwise it will get a new token based on your config.
126
128
  */
127
129
  async getToken() {
128
- if (this.token && this.isTokenValid(this.token)) {
129
- if (this.token.isExpiredIn(15, 'minutes')) {
130
- this.logger.info('Token expires within 15 minutes. Refreshing.');
131
- const newToken = await this.refreshToken();
132
- this.setToken(newToken);
133
- return newToken;
134
- }
130
+ if (this.token && this.isTokenValid(this.token) && !this.token.isExpiredIn(15, 'minutes')) {
135
131
  return this.token;
136
132
  }
133
+ return this.getOrRequestToken(() => this.fetchNewToken());
134
+ }
135
+ getOrRequestToken(fetchToken) {
136
+ if (this.pendingTokenRequest) {
137
+ return this.pendingTokenRequest;
138
+ }
139
+ const request = fetchToken()
140
+ .then((token) => {
141
+ if (this.pendingTokenRequest === request) {
142
+ this.setToken(token);
143
+ }
144
+ else if (this.token) {
145
+ return this.getToken();
146
+ }
147
+ return token;
148
+ })
149
+ .finally(() => {
150
+ if (this.pendingTokenRequest === request) {
151
+ this.pendingTokenRequest = undefined;
152
+ }
153
+ });
154
+ this.pendingTokenRequest = request;
155
+ return request;
156
+ }
157
+ async fetchNewToken() {
158
+ if (this.token && this.isTokenValid(this.token)) {
159
+ this.logger.info('Token expires within 15 minutes. Refreshing.');
160
+ return this.refreshToken();
161
+ }
137
162
  let token;
138
163
  try {
139
164
  if ('appId' in this.config && 'appKey' in this.config) {
@@ -159,7 +184,6 @@ class AuthService extends BaseServiceAbstract_1.BaseServiceAbstract {
159
184
  this.logger.error(message);
160
185
  throw new models_1.RocosError(message, models_1.errorCodes.AUTH_ERROR);
161
186
  }
162
- this.setToken(token);
163
187
  return token;
164
188
  }
165
189
  /**
@@ -192,9 +216,8 @@ class AuthService extends BaseServiceAbstract_1.BaseServiceAbstract {
192
216
  */
193
217
  async refreshTokenIfExpired(minutes) {
194
218
  if (this.token?.isExpiredIn(minutes, 'minutes')) {
195
- this.logger.info('Token expires in 15 minutes. Refreshing.');
196
- const newToken = await this.refreshToken();
197
- this.setToken(newToken);
219
+ this.logger.info(`Token expires in ${minutes} minutes. Refreshing.`);
220
+ await this.getOrRequestToken(() => this.refreshToken());
198
221
  return true;
199
222
  }
200
223
  return false;
@@ -6,6 +6,7 @@ export declare class AuthService extends BaseServiceAbstract implements IBaseSer
6
6
  private token?;
7
7
  private tokenRefreshTimeoutId?;
8
8
  private tokenSubject$;
9
+ private pendingTokenRequest?;
9
10
  constructor(config: IRocosSDKConfig);
10
11
  /** Observable for token updates
11
12
  *
@@ -54,6 +55,8 @@ export declare class AuthService extends BaseServiceAbstract implements IBaseSer
54
55
  * This will return the current token if it is not expired, otherwise it will get a new token based on your config.
55
56
  */
56
57
  getToken(): Promise<Token>;
58
+ private getOrRequestToken;
59
+ private fetchNewToken;
57
60
  /**
58
61
  * Refresh the authentication token
59
62
  *
@@ -47,25 +47,27 @@ export class AuthService extends BaseServiceAbstract {
47
47
  if (expiresIn !== undefined) {
48
48
  this.logger.warn('setToken(value, expiresIn) is deprecated. Use setToken(value) instead');
49
49
  }
50
- if (typeof value === 'string') {
51
- this.token = new Token(value);
52
- }
53
- else {
54
- this.token = value;
50
+ const token = typeof value === 'string' ? new Token(value) : value;
51
+ if (token.value !== this.token?.value) {
52
+ this.pendingTokenRequest = undefined;
55
53
  }
54
+ this.token = token;
56
55
  this.config.token = this.token.value;
57
56
  // output a message for token change
58
57
  if (this.isTokenValid(this.token)) {
59
58
  this.tokenSubject$.next(this.token);
60
59
  }
61
60
  else {
62
- void this.getToken();
61
+ void this.getToken().catch((error) => {
62
+ this.logger.error('Failed to initialize auth token', error);
63
+ });
63
64
  }
64
65
  }
65
66
  /**
66
67
  * Clear token
67
68
  */
68
69
  clearToken() {
70
+ this.pendingTokenRequest = undefined;
69
71
  this.token = undefined;
70
72
  this.config.token = undefined;
71
73
  }
@@ -122,15 +124,38 @@ export class AuthService extends BaseServiceAbstract {
122
124
  * This will return the current token if it is not expired, otherwise it will get a new token based on your config.
123
125
  */
124
126
  async getToken() {
125
- if (this.token && this.isTokenValid(this.token)) {
126
- if (this.token.isExpiredIn(15, 'minutes')) {
127
- this.logger.info('Token expires within 15 minutes. Refreshing.');
128
- const newToken = await this.refreshToken();
129
- this.setToken(newToken);
130
- return newToken;
131
- }
127
+ if (this.token && this.isTokenValid(this.token) && !this.token.isExpiredIn(15, 'minutes')) {
132
128
  return this.token;
133
129
  }
130
+ return this.getOrRequestToken(() => this.fetchNewToken());
131
+ }
132
+ getOrRequestToken(fetchToken) {
133
+ if (this.pendingTokenRequest) {
134
+ return this.pendingTokenRequest;
135
+ }
136
+ const request = fetchToken()
137
+ .then((token) => {
138
+ if (this.pendingTokenRequest === request) {
139
+ this.setToken(token);
140
+ }
141
+ else if (this.token) {
142
+ return this.getToken();
143
+ }
144
+ return token;
145
+ })
146
+ .finally(() => {
147
+ if (this.pendingTokenRequest === request) {
148
+ this.pendingTokenRequest = undefined;
149
+ }
150
+ });
151
+ this.pendingTokenRequest = request;
152
+ return request;
153
+ }
154
+ async fetchNewToken() {
155
+ if (this.token && this.isTokenValid(this.token)) {
156
+ this.logger.info('Token expires within 15 minutes. Refreshing.');
157
+ return this.refreshToken();
158
+ }
134
159
  let token;
135
160
  try {
136
161
  if ('appId' in this.config && 'appKey' in this.config) {
@@ -156,7 +181,6 @@ export class AuthService extends BaseServiceAbstract {
156
181
  this.logger.error(message);
157
182
  throw new RocosError(message, errorCodes.AUTH_ERROR);
158
183
  }
159
- this.setToken(token);
160
184
  return token;
161
185
  }
162
186
  /**
@@ -189,9 +213,8 @@ export class AuthService extends BaseServiceAbstract {
189
213
  */
190
214
  async refreshTokenIfExpired(minutes) {
191
215
  if (this.token?.isExpiredIn(minutes, 'minutes')) {
192
- this.logger.info('Token expires in 15 minutes. Refreshing.');
193
- const newToken = await this.refreshToken();
194
- this.setToken(newToken);
216
+ this.logger.info(`Token expires in ${minutes} minutes. Refreshing.`);
217
+ await this.getOrRequestToken(() => this.refreshToken());
195
218
  return true;
196
219
  }
197
220
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dronedeploy/rocos-js-sdk",
3
- "version": "4.4.11",
3
+ "version": "4.4.12",
4
4
  "description": "Javascript SDK for rocos",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",