@de./sdk-rn 1.0.26 → 1.0.27

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.
@@ -1,14 +1,39 @@
1
1
  import type { AuthCredentials, AuthOptions } from '../types/auth';
2
2
  export default class Auth {
3
3
  private version;
4
+ private options;
4
5
  protected creds: AuthCredentials;
5
- private expiryTime?;
6
+ private refreshTimer?;
6
7
  private autorefresh?;
8
+ private onNewToken?;
7
9
  private baseURL;
10
+ private isRotating;
8
11
  accessToken?: string;
9
12
  constructor(creds: AuthCredentials, options?: AuthOptions);
10
13
  private request;
14
+ private debug;
15
+ private error;
16
+ /**
17
+ * Schedule next token rotation
18
+ */
19
+ private scheduleRotation;
20
+ /**
21
+ * Clear rotation timer
22
+ */
23
+ private clearRotation;
11
24
  getToken(): Promise<string>;
12
25
  rotateToken(): Promise<string>;
26
+ /**
27
+ * Stop auto-refresh and clean up resources
28
+ */
29
+ stopAutoRefresh(): void;
30
+ /**
31
+ * Start auto-refresh
32
+ */
33
+ startAutoRefresh(): void;
34
+ /**
35
+ * Clean up all resources
36
+ */
37
+ destroy(): void;
13
38
  }
14
39
  //# sourceMappingURL=Auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Auth.d.ts","sourceRoot":"","sources":["../../src/backend/Auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAsB,MAAM,eAAe,CAAA;AAWrF,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,OAAO,CAAC,OAAO,CAAQ;IACvB,SAAS,CAAC,KAAK,EAAE,eAAe,CAAA;IAChC,OAAO,CAAC,UAAU,CAAC,CAAK;IACxB,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAQ;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;gBAEd,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,WAAW;YAmB5C,OAAO;IA+Bf,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAqB3B,WAAW;CA4BlB"}
1
+ {"version":3,"file":"Auth.d.ts","sourceRoot":"","sources":["../../src/backend/Auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAsB,MAAM,eAAe,CAAA;AAWrF,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,OAAO,CAAa;IAC5B,SAAS,CAAC,KAAK,EAAE,eAAe,CAAA;IAChC,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAyB;IAC5C,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAAiB;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;gBAEd,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,WAAW;YAqB5C,OAAO;IA+BrB,OAAO,CAAC,KAAK;IAGb,OAAO,CAAC,KAAK;IAIb;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOf,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAgB3B,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IA0DpC;;OAEG;IACH,eAAe;IAOf;;OAEG;IACH,gBAAgB;IAOhB;;OAEG;IACH,OAAO;CAOR"}
@@ -13,6 +13,7 @@ import { Platform } from 'react-native';
13
13
  const ACCESS_TOKEN_EXPIRY = 3.75; // in 3 minutes 45 seconds
14
14
  export default class Auth {
15
15
  constructor(creds, options) {
16
+ this.isRotating = false;
16
17
  if (!creds)
17
18
  throw new Error('Undefined Credentials. Check https://doc.dedot.io/sdk/auth');
18
19
  if (!creds.workspace)
@@ -24,6 +25,7 @@ export default class Auth {
24
25
  if (!creds.secret)
25
26
  throw new Error('Undefined Connector Secret. Check https://doc.dedot.io/sdk/auth');
26
27
  this.creds = creds;
28
+ this.options = options || {};
27
29
  this.version = (options === null || options === void 0 ? void 0 : options.version) || 1;
28
30
  this.baseURL = (options === null || options === void 0 ? void 0 : options.env) !== 'dev'
29
31
  ? 'https://api.dedot.io'
@@ -33,6 +35,7 @@ export default class Auth {
33
35
  default: 'http://api.dedot.io:24800'
34
36
  });
35
37
  this.autorefresh = (options === null || options === void 0 ? void 0 : options.autorefresh) || false;
38
+ this.onNewToken = options === null || options === void 0 ? void 0 : options.onNewToken;
36
39
  }
37
40
  async request(_a) {
38
41
  var { url } = _a, options = __rest(_a, ["url"]);
@@ -56,29 +59,56 @@ export default class Auth {
56
59
  options.body = JSON.stringify(options.body);
57
60
  }
58
61
  options = Object.assign(Object.assign({}, rawOptions), options);
59
- console.log('Auth request', `${this.baseURL}/v${this.version}/${url.replace(/^\//, '')}`, options);
62
+ this.debug('Auth request', `${this.baseURL}/v${this.version}/${url.replace(/^\//, '')}`, options);
60
63
  const response = await fetch(`${this.baseURL}/v${this.version}/${url.replace(/^\//, '')}`, options);
61
64
  return await response.json();
62
65
  }
66
+ debug(...args) {
67
+ var _a;
68
+ ((_a = this.options) === null || _a === void 0 ? void 0 : _a.env) === 'dev' && console.debug('[Auth]', ...args);
69
+ }
70
+ error(...args) {
71
+ console.error('[Auth]', ...args);
72
+ }
73
+ /**
74
+ * Schedule next token rotation
75
+ */
76
+ scheduleRotation() {
77
+ if (!this.autorefresh)
78
+ return;
79
+ this.clearRotation();
80
+ this.refreshTimer = setTimeout(() => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000);
81
+ }
82
+ /**
83
+ * Clear rotation timer
84
+ */
85
+ clearRotation() {
86
+ if (!this.refreshTimer)
87
+ return;
88
+ clearTimeout(this.refreshTimer);
89
+ this.refreshTimer = undefined;
90
+ }
63
91
  async getToken() {
64
- const { workspace, cid, secret } = this.creds, options = {
92
+ const options = {
65
93
  url: '/access/token',
66
94
  method: 'POST',
67
95
  body: this.creds
68
96
  }, { error, message, token } = await this.request(options);
69
97
  if (error)
70
98
  throw new Error(message);
71
- // Set auto-refresh token every 4 mins
72
- if (this.autorefresh) {
73
- clearTimeout(this.expiryTime);
74
- this.expiryTime = setTimeout(() => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000);
75
- }
76
99
  this.accessToken = token;
100
+ this.scheduleRotation(); // Schedule auto-refresh
77
101
  return token;
78
102
  }
79
103
  async rotateToken() {
104
+ // Prevent concurrent rotation attempts
105
+ if (this.isRotating) {
106
+ this.debug('Token rotation already in progress, skipping');
107
+ return this.accessToken;
108
+ }
80
109
  if (!this.accessToken)
81
110
  throw new Error('No access token found');
111
+ this.isRotating = true;
82
112
  try {
83
113
  const options = {
84
114
  url: '/access/token/rotate',
@@ -87,18 +117,69 @@ export default class Auth {
87
117
  }, { error, message, token } = await this.request(options);
88
118
  if (error)
89
119
  throw new Error(message);
90
- // Set auto-refresh token every 4 mins
91
- if (this.autorefresh) {
92
- clearTimeout(this.expiryTime);
93
- this.expiryTime = setTimeout(() => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000);
94
- }
95
120
  this.accessToken = token;
121
+ // Notify callback listener
122
+ if (typeof this.onNewToken === 'function')
123
+ try {
124
+ this.onNewToken(token);
125
+ }
126
+ catch (callbackError) {
127
+ this.error('[Auth] Error in onNewToken callback:', callbackError);
128
+ }
129
+ // Schedule next rotation
130
+ this.scheduleRotation();
131
+ this.debug('Token rotated successfully');
96
132
  return token;
97
133
  }
98
134
  catch (error) {
99
- console.error(`Refresh access token failed: ${error.message}`);
100
- return await this.getToken(); // Get new token instead
135
+ this.debug('Refresh access token failed:', error.message);
136
+ try {
137
+ // Fallback: Get new token instead
138
+ const newToken = await this.getToken();
139
+ this.debug('Fallback to new token successful');
140
+ // Notify callback listener about new token
141
+ if (this.onNewToken)
142
+ try {
143
+ this.onNewToken(newToken);
144
+ }
145
+ catch (callbackError) {
146
+ this.error('Error in onNewToken callback:', callbackError);
147
+ }
148
+ return newToken;
149
+ }
150
+ catch (fallbackError) {
151
+ this.error('Fallback to new token also failed:', fallbackError.message);
152
+ throw fallbackError;
153
+ }
154
+ }
155
+ finally {
156
+ this.isRotating = false;
101
157
  }
102
158
  }
159
+ /**
160
+ * Stop auto-refresh and clean up resources
161
+ */
162
+ stopAutoRefresh() {
163
+ this.debug('Stopping auto-refresh');
164
+ this.clearRotation();
165
+ this.autorefresh = false;
166
+ }
167
+ /**
168
+ * Start auto-refresh
169
+ */
170
+ startAutoRefresh() {
171
+ this.debug('Starting auto-refresh');
172
+ this.autorefresh = true;
173
+ this.scheduleRotation();
174
+ }
175
+ /**
176
+ * Clean up all resources
177
+ */
178
+ destroy() {
179
+ this.debug('Destroying Auth instance');
180
+ this.stopAutoRefresh();
181
+ this.accessToken = undefined;
182
+ this.onNewToken = undefined;
183
+ }
103
184
  }
104
185
  //# sourceMappingURL=Auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Auth.js","sourceRoot":"","sources":["../../src/backend/Auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Auth.js","sourceRoot":"","sources":["../../src/backend/Auth.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export type AuthOptions = {
2
2
  env?: 'dev' | 'prod'
3
3
  version?: number
4
4
  autorefresh?: boolean
5
+ onNewToken?: (token: string) => void
5
6
  }
6
7
 
7
8
  export type AuthCredentials = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@de./sdk-rn",
3
- "version": "1.0.26",
3
+ "version": "1.0.27",
4
4
  "description": "Complete SDK pack for MSI React Native (Map Service Interface) and DClient services",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -11,10 +11,13 @@ type AuthResponse = {
11
11
 
12
12
  export default class Auth {
13
13
  private version: number
14
+ private options: AuthOptions
14
15
  protected creds: AuthCredentials
15
- private expiryTime?: any
16
+ private refreshTimer?: number
16
17
  private autorefresh?: boolean
18
+ private onNewToken?: (token: string) => void
17
19
  private baseURL: string
20
+ private isRotating: boolean = false
18
21
  public accessToken?: string
19
22
 
20
23
  constructor( creds: AuthCredentials, options?: AuthOptions ){
@@ -25,6 +28,7 @@ export default class Auth {
25
28
  if( !creds.secret ) throw new Error('Undefined Connector Secret. Check https://doc.dedot.io/sdk/auth')
26
29
 
27
30
  this.creds = creds
31
+ this.options = options || {}
28
32
  this.version = options?.version || 1
29
33
  this.baseURL = options?.env !== 'dev'
30
34
  ? 'https://api.dedot.io'
@@ -34,9 +38,10 @@ export default class Auth {
34
38
  default: 'http://api.dedot.io:24800'
35
39
  })
36
40
  this.autorefresh = options?.autorefresh || false
41
+ this.onNewToken = options?.onNewToken
37
42
  }
38
43
 
39
- private async request<T>({ url, ...options }: AuthRequestOptions ): Promise<T>{
44
+ private async request<T>({ url, ...options }: AuthRequestOptions ): Promise<T> {
40
45
  const rawOptions: any = {
41
46
  method: 'GET',
42
47
  headers: {
@@ -61,15 +66,41 @@ export default class Auth {
61
66
 
62
67
  options = { ...rawOptions, ...options }
63
68
 
64
- console.log('Auth request', `${this.baseURL}/v${this.version}/${url.replace(/^\//, '')}`, options )
69
+ this.debug('Auth request', `${this.baseURL}/v${this.version}/${url.replace(/^\//, '')}`, options )
65
70
  const response = await fetch(`${this.baseURL}/v${this.version}/${url.replace(/^\//, '')}`, options )
66
71
 
67
72
  return await response.json() as T
68
73
  }
69
74
 
75
+ private debug( ...args: any[] ){
76
+ this.options?.env === 'dev' && console.debug('[Auth]', ...args )
77
+ }
78
+ private error( ...args: any[] ){
79
+ console.error('[Auth]', ...args )
80
+ }
81
+
82
+ /**
83
+ * Schedule next token rotation
84
+ */
85
+ private scheduleRotation(){
86
+ if( !this.autorefresh ) return
87
+
88
+ this.clearRotation()
89
+ this.refreshTimer = setTimeout( () => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000 )
90
+ }
91
+
92
+ /**
93
+ * Clear rotation timer
94
+ */
95
+ private clearRotation(){
96
+ if( !this.refreshTimer ) return
97
+
98
+ clearTimeout( this.refreshTimer )
99
+ this.refreshTimer = undefined
100
+ }
101
+
70
102
  async getToken(): Promise<string>{
71
103
  const
72
- { workspace, cid, secret } = this.creds,
73
104
  options: AuthRequestOptions = {
74
105
  url: '/access/token',
75
106
  method: 'POST',
@@ -78,20 +109,24 @@ export default class Auth {
78
109
  { error, message, token } = await this.request<AuthResponse>( options )
79
110
  if( error ) throw new Error( message )
80
111
 
81
- // Set auto-refresh token every 4 mins
82
- if( this.autorefresh ){
83
- clearTimeout( this.expiryTime )
84
- this.expiryTime = setTimeout( () => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000 )
85
- }
86
-
87
112
  this.accessToken = token
113
+ this.scheduleRotation() // Schedule auto-refresh
114
+
88
115
  return token
89
116
  }
90
117
 
91
- async rotateToken(){
118
+ async rotateToken(): Promise<string> {
119
+ // Prevent concurrent rotation attempts
120
+ if( this.isRotating ){
121
+ this.debug('Token rotation already in progress, skipping')
122
+ return this.accessToken!
123
+ }
124
+
92
125
  if( !this.accessToken )
93
126
  throw new Error('No access token found')
94
127
 
128
+ this.isRotating = true
129
+
95
130
  try {
96
131
  const
97
132
  options: AuthRequestOptions = {
@@ -102,18 +137,70 @@ export default class Auth {
102
137
  { error, message, token } = await this.request<AuthResponse>( options )
103
138
  if( error ) throw new Error( message )
104
139
 
105
- // Set auto-refresh token every 4 mins
106
- if( this.autorefresh ){
107
- clearTimeout( this.expiryTime )
108
- this.expiryTime = setTimeout( () => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000 )
109
- }
110
-
111
140
  this.accessToken = token
141
+
142
+ // Notify callback listener
143
+ if( typeof this.onNewToken === 'function' )
144
+ try { this.onNewToken( token ) }
145
+ catch( callbackError ){ this.error('[Auth] Error in onNewToken callback:', callbackError) }
146
+
147
+ // Schedule next rotation
148
+ this.scheduleRotation()
149
+
150
+ this.debug('Token rotated successfully')
112
151
  return token
113
152
  }
114
153
  catch( error: any ){
115
- console.error(`Refresh access token failed: ${error.message}`)
116
- return await this.getToken() // Get new token instead
154
+ this.debug('Refresh access token failed:', error.message)
155
+
156
+ try {
157
+ // Fallback: Get new token instead
158
+ const newToken = await this.getToken()
159
+ this.debug('Fallback to new token successful')
160
+
161
+ // Notify callback listener about new token
162
+ if( this.onNewToken )
163
+ try { this.onNewToken( newToken ) }
164
+ catch( callbackError ){ this.error('Error in onNewToken callback:', callbackError) }
165
+
166
+ return newToken
167
+ }
168
+ catch( fallbackError: any ){
169
+ this.error('Fallback to new token also failed:', fallbackError.message)
170
+ throw fallbackError
171
+ }
117
172
  }
173
+ finally { this.isRotating = false }
174
+ }
175
+
176
+ /**
177
+ * Stop auto-refresh and clean up resources
178
+ */
179
+ stopAutoRefresh(){
180
+ this.debug('Stopping auto-refresh')
181
+
182
+ this.clearRotation()
183
+ this.autorefresh = false
184
+ }
185
+
186
+ /**
187
+ * Start auto-refresh
188
+ */
189
+ startAutoRefresh(){
190
+ this.debug('Starting auto-refresh')
191
+
192
+ this.autorefresh = true
193
+ this.scheduleRotation()
194
+ }
195
+
196
+ /**
197
+ * Clean up all resources
198
+ */
199
+ destroy(){
200
+ this.debug('Destroying Auth instance')
201
+ this.stopAutoRefresh()
202
+
203
+ this.accessToken = undefined
204
+ this.onNewToken = undefined
118
205
  }
119
206
  }
@@ -2,6 +2,7 @@ export type AuthOptions = {
2
2
  env?: 'dev' | 'prod'
3
3
  version?: number
4
4
  autorefresh?: boolean
5
+ onNewToken?: (token: string) => void
5
6
  }
6
7
 
7
8
  export type AuthCredentials = {