whio-api-sdk 1.0.165 → 1.0.166
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/src/sdk/sdk.d.ts +2 -0
- package/dist/src/sdk/sdk.js +48 -0
- package/dist/src/sdk/urls.js +1 -1
- package/package.json +1 -1
- package/src/sdk/sdk.ts +56 -1
- package/src/sdk/urls.ts +1 -1
package/dist/src/sdk/sdk.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export declare class ApiSDK {
|
|
|
14
14
|
login(credentials: LoginCredentials): Promise<LoginResponse>;
|
|
15
15
|
logout(): Promise<void>;
|
|
16
16
|
private clearAuth;
|
|
17
|
+
private isTokenExpired;
|
|
18
|
+
private refreshAccessToken;
|
|
17
19
|
isAuthenticated(): boolean;
|
|
18
20
|
getCurrentUser(): User | null;
|
|
19
21
|
getAccessToken(): string | null;
|
package/dist/src/sdk/sdk.js
CHANGED
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
// sdk.ts
|
|
11
11
|
import { OrganizationRoleType, } from './types';
|
|
12
12
|
import urls from './urls';
|
|
13
|
+
import { jwtDecode } from 'jwt-decode';
|
|
13
14
|
export class ApiSDK {
|
|
14
15
|
constructor(config = {}) {
|
|
15
16
|
this.accessToken = null;
|
|
@@ -39,11 +40,22 @@ export class ApiSDK {
|
|
|
39
40
|
if (!this.accessToken) {
|
|
40
41
|
throw new Error('Access token not found');
|
|
41
42
|
}
|
|
43
|
+
// Check if token is expired or expiring soon
|
|
44
|
+
if (this.isTokenExpired(this.accessToken)) {
|
|
45
|
+
// Try to refresh the token
|
|
46
|
+
if (this.refreshToken) {
|
|
47
|
+
yield this.refreshAccessToken();
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
throw new Error('Access token expired and no refresh token available');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
42
53
|
});
|
|
43
54
|
}
|
|
44
55
|
initialize() {
|
|
45
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
46
57
|
this.accessToken = yield this.storage.getItem('access_token');
|
|
58
|
+
this.refreshToken = yield this.storage.getItem('refresh_token');
|
|
47
59
|
const userString = yield this.storage.getItem('user');
|
|
48
60
|
this.user = userString ? JSON.parse(userString) : null;
|
|
49
61
|
});
|
|
@@ -108,6 +120,7 @@ export class ApiSDK {
|
|
|
108
120
|
this.refreshToken = response.refresh_token;
|
|
109
121
|
this.user = response.user;
|
|
110
122
|
yield this.storage.setItem('access_token', response.access_token);
|
|
123
|
+
yield this.storage.setItem('refresh_token', response.refresh_token);
|
|
111
124
|
yield this.storage.setItem('user', JSON.stringify(response.user));
|
|
112
125
|
return response;
|
|
113
126
|
}
|
|
@@ -130,11 +143,46 @@ export class ApiSDK {
|
|
|
130
143
|
clearAuth() {
|
|
131
144
|
return __awaiter(this, void 0, void 0, function* () {
|
|
132
145
|
this.accessToken = null;
|
|
146
|
+
this.refreshToken = null;
|
|
133
147
|
this.user = null;
|
|
134
148
|
yield this.storage.removeItem('access_token');
|
|
149
|
+
yield this.storage.removeItem('refresh_token');
|
|
135
150
|
yield this.storage.removeItem('user');
|
|
136
151
|
});
|
|
137
152
|
}
|
|
153
|
+
isTokenExpired(token, bufferMinutes = 5) {
|
|
154
|
+
try {
|
|
155
|
+
const decoded = jwtDecode(token);
|
|
156
|
+
const currentTime = Date.now() / 1000;
|
|
157
|
+
const bufferTime = bufferMinutes * 60;
|
|
158
|
+
return decoded.exp <= (currentTime + bufferTime);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
// If we can't decode the token, consider it expired
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
refreshAccessToken() {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
167
|
+
if (!this.refreshToken) {
|
|
168
|
+
throw new Error('No refresh token available');
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const response = yield this.request('/auth/refresh', 'POST', { refresh_token: this.refreshToken }, {}, true // Skip token validation for this request
|
|
172
|
+
);
|
|
173
|
+
this.accessToken = response.access_token;
|
|
174
|
+
this.refreshToken = response.refresh_token;
|
|
175
|
+
this.user = response.user;
|
|
176
|
+
yield this.storage.setItem('access_token', response.access_token);
|
|
177
|
+
yield this.storage.setItem('refresh_token', response.refresh_token);
|
|
178
|
+
yield this.storage.setItem('user', JSON.stringify(response.user));
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
yield this.clearAuth();
|
|
182
|
+
throw new Error('Failed to refresh access token');
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
138
186
|
isAuthenticated() {
|
|
139
187
|
return !!this.accessToken;
|
|
140
188
|
}
|
package/dist/src/sdk/urls.js
CHANGED
|
@@ -3,7 +3,7 @@ const urls = {
|
|
|
3
3
|
login: '/auth/login',
|
|
4
4
|
profile: '/auth/profile',
|
|
5
5
|
register: '/auth/register',
|
|
6
|
-
refreshToken: '/auth/refresh
|
|
6
|
+
refreshToken: '/auth/refresh',
|
|
7
7
|
logout: '/auth/logout',
|
|
8
8
|
changePassword: '/auth/change-password',
|
|
9
9
|
adminChangePassword: '/auth/admin/change-password',
|
package/package.json
CHANGED
package/src/sdk/sdk.ts
CHANGED
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
UpdateSessionDto,
|
|
40
40
|
} from './types';
|
|
41
41
|
import urls from './urls';
|
|
42
|
-
import jwtDecode from 'jwt-decode';
|
|
42
|
+
import { jwtDecode } from 'jwt-decode';
|
|
43
43
|
|
|
44
44
|
export class ApiSDK {
|
|
45
45
|
private baseUrl: string;
|
|
@@ -70,13 +70,25 @@ export class ApiSDK {
|
|
|
70
70
|
|
|
71
71
|
private async getToken() {
|
|
72
72
|
this.accessToken = await this.storage!.getItem('access_token');
|
|
73
|
+
|
|
73
74
|
if (!this.accessToken) {
|
|
74
75
|
throw new Error('Access token not found');
|
|
75
76
|
}
|
|
77
|
+
|
|
78
|
+
// Check if token is expired or expiring soon
|
|
79
|
+
if (this.isTokenExpired(this.accessToken)) {
|
|
80
|
+
// Try to refresh the token
|
|
81
|
+
if (this.refreshToken) {
|
|
82
|
+
await this.refreshAccessToken();
|
|
83
|
+
} else {
|
|
84
|
+
throw new Error('Access token expired and no refresh token available');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
private async initialize() {
|
|
79
90
|
this.accessToken = await this.storage!.getItem('access_token');
|
|
91
|
+
this.refreshToken = await this.storage!.getItem('refresh_token');
|
|
80
92
|
const userString = await this.storage!.getItem('user');
|
|
81
93
|
this.user = userString ? JSON.parse(userString) : null;
|
|
82
94
|
}
|
|
@@ -169,6 +181,7 @@ export class ApiSDK {
|
|
|
169
181
|
this.user = response.user;
|
|
170
182
|
|
|
171
183
|
await this.storage!.setItem('access_token', response.access_token);
|
|
184
|
+
await this.storage!.setItem('refresh_token', response.refresh_token);
|
|
172
185
|
await this.storage!.setItem('user', JSON.stringify(response.user));
|
|
173
186
|
|
|
174
187
|
return response;
|
|
@@ -188,11 +201,53 @@ export class ApiSDK {
|
|
|
188
201
|
|
|
189
202
|
private async clearAuth(): Promise<void> {
|
|
190
203
|
this.accessToken = null;
|
|
204
|
+
this.refreshToken = null;
|
|
191
205
|
this.user = null;
|
|
192
206
|
await this.storage!.removeItem('access_token');
|
|
207
|
+
await this.storage!.removeItem('refresh_token');
|
|
193
208
|
await this.storage!.removeItem('user');
|
|
194
209
|
}
|
|
195
210
|
|
|
211
|
+
private isTokenExpired(token: string, bufferMinutes: number = 5): boolean {
|
|
212
|
+
try {
|
|
213
|
+
const decoded: any = jwtDecode(token);
|
|
214
|
+
const currentTime = Date.now() / 1000;
|
|
215
|
+
const bufferTime = bufferMinutes * 60;
|
|
216
|
+
|
|
217
|
+
return decoded.exp <= (currentTime + bufferTime);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
// If we can't decode the token, consider it expired
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private async refreshAccessToken(): Promise<void> {
|
|
225
|
+
if (!this.refreshToken) {
|
|
226
|
+
throw new Error('No refresh token available');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
const response = await this.request<LoginResponse>(
|
|
231
|
+
'/auth/refresh',
|
|
232
|
+
'POST',
|
|
233
|
+
{ refresh_token: this.refreshToken },
|
|
234
|
+
{},
|
|
235
|
+
true // Skip token validation for this request
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
this.accessToken = response.access_token;
|
|
239
|
+
this.refreshToken = response.refresh_token;
|
|
240
|
+
this.user = response.user;
|
|
241
|
+
|
|
242
|
+
await this.storage!.setItem('access_token', response.access_token);
|
|
243
|
+
await this.storage!.setItem('refresh_token', response.refresh_token);
|
|
244
|
+
await this.storage!.setItem('user', JSON.stringify(response.user));
|
|
245
|
+
} catch (error) {
|
|
246
|
+
await this.clearAuth();
|
|
247
|
+
throw new Error('Failed to refresh access token');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
196
251
|
public isAuthenticated(): boolean {
|
|
197
252
|
return !!this.accessToken;
|
|
198
253
|
}
|
package/src/sdk/urls.ts
CHANGED
|
@@ -3,7 +3,7 @@ const urls = {
|
|
|
3
3
|
login: '/auth/login',
|
|
4
4
|
profile: '/auth/profile',
|
|
5
5
|
register: '/auth/register',
|
|
6
|
-
refreshToken: '/auth/refresh
|
|
6
|
+
refreshToken: '/auth/refresh',
|
|
7
7
|
logout: '/auth/logout',
|
|
8
8
|
changePassword: '/auth/change-password',
|
|
9
9
|
adminChangePassword: '/auth/admin/change-password',
|