whio-api-sdk 1.0.165 → 1.0.167
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 +49 -6
- package/dist/src/sdk/urls.js +1 -1
- package/package.json +1 -1
- package/src/sdk/sdk.ts +57 -6
- 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
|
}
|
|
@@ -119,22 +132,52 @@ export class ApiSDK {
|
|
|
119
132
|
}
|
|
120
133
|
logout() {
|
|
121
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
122
|
-
|
|
123
|
-
yield this.request('/auth/logout', 'POST');
|
|
124
|
-
}
|
|
125
|
-
finally {
|
|
126
|
-
yield this.clearAuth();
|
|
127
|
-
}
|
|
135
|
+
yield this.clearAuth();
|
|
128
136
|
});
|
|
129
137
|
}
|
|
130
138
|
clearAuth() {
|
|
131
139
|
return __awaiter(this, void 0, void 0, function* () {
|
|
132
140
|
this.accessToken = null;
|
|
141
|
+
this.refreshToken = null;
|
|
133
142
|
this.user = null;
|
|
134
143
|
yield this.storage.removeItem('access_token');
|
|
144
|
+
yield this.storage.removeItem('refresh_token');
|
|
135
145
|
yield this.storage.removeItem('user');
|
|
136
146
|
});
|
|
137
147
|
}
|
|
148
|
+
isTokenExpired(token, bufferMinutes = 5) {
|
|
149
|
+
try {
|
|
150
|
+
const decoded = jwtDecode(token);
|
|
151
|
+
const currentTime = Date.now() / 1000;
|
|
152
|
+
const bufferTime = bufferMinutes * 60;
|
|
153
|
+
return decoded.exp <= (currentTime + bufferTime);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
// If we can't decode the token, consider it expired
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
refreshAccessToken() {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
if (!this.refreshToken) {
|
|
163
|
+
throw new Error('No refresh token available');
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const response = yield this.request('/auth/refresh', 'POST', { refresh_token: this.refreshToken }, {}, true // Skip token validation for this request
|
|
167
|
+
);
|
|
168
|
+
this.accessToken = response.access_token;
|
|
169
|
+
this.refreshToken = response.refresh_token;
|
|
170
|
+
this.user = response.user;
|
|
171
|
+
yield this.storage.setItem('access_token', response.access_token);
|
|
172
|
+
yield this.storage.setItem('refresh_token', response.refresh_token);
|
|
173
|
+
yield this.storage.setItem('user', JSON.stringify(response.user));
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
yield this.clearAuth();
|
|
177
|
+
throw new Error('Failed to refresh access token');
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
138
181
|
isAuthenticated() {
|
|
139
182
|
return !!this.accessToken;
|
|
140
183
|
}
|
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;
|
|
@@ -179,20 +192,58 @@ export class ApiSDK {
|
|
|
179
192
|
}
|
|
180
193
|
|
|
181
194
|
public async logout(): Promise<void> {
|
|
182
|
-
|
|
183
|
-
await this.request('/auth/logout', 'POST');
|
|
184
|
-
} finally {
|
|
185
|
-
await this.clearAuth();
|
|
186
|
-
}
|
|
195
|
+
await this.clearAuth();
|
|
187
196
|
}
|
|
188
197
|
|
|
189
198
|
private async clearAuth(): Promise<void> {
|
|
190
199
|
this.accessToken = null;
|
|
200
|
+
this.refreshToken = null;
|
|
191
201
|
this.user = null;
|
|
192
202
|
await this.storage!.removeItem('access_token');
|
|
203
|
+
await this.storage!.removeItem('refresh_token');
|
|
193
204
|
await this.storage!.removeItem('user');
|
|
194
205
|
}
|
|
195
206
|
|
|
207
|
+
private isTokenExpired(token: string, bufferMinutes: number = 5): boolean {
|
|
208
|
+
try {
|
|
209
|
+
const decoded: any = jwtDecode(token);
|
|
210
|
+
const currentTime = Date.now() / 1000;
|
|
211
|
+
const bufferTime = bufferMinutes * 60;
|
|
212
|
+
|
|
213
|
+
return decoded.exp <= (currentTime + bufferTime);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
// If we can't decode the token, consider it expired
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private async refreshAccessToken(): Promise<void> {
|
|
221
|
+
if (!this.refreshToken) {
|
|
222
|
+
throw new Error('No refresh token available');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
const response = await this.request<LoginResponse>(
|
|
227
|
+
'/auth/refresh',
|
|
228
|
+
'POST',
|
|
229
|
+
{ refresh_token: this.refreshToken },
|
|
230
|
+
{},
|
|
231
|
+
true // Skip token validation for this request
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
this.accessToken = response.access_token;
|
|
235
|
+
this.refreshToken = response.refresh_token;
|
|
236
|
+
this.user = response.user;
|
|
237
|
+
|
|
238
|
+
await this.storage!.setItem('access_token', response.access_token);
|
|
239
|
+
await this.storage!.setItem('refresh_token', response.refresh_token);
|
|
240
|
+
await this.storage!.setItem('user', JSON.stringify(response.user));
|
|
241
|
+
} catch (error) {
|
|
242
|
+
await this.clearAuth();
|
|
243
|
+
throw new Error('Failed to refresh access token');
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
196
247
|
public isAuthenticated(): boolean {
|
|
197
248
|
return !!this.accessToken;
|
|
198
249
|
}
|
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',
|