supaapps-auth 2.0.0-rc.9 → 2.1.0
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/AuthManager.d.ts +15 -2
- package/dist/AuthManager.js +78 -9
- package/dist/types.d.ts +14 -0
- package/dist/types.js +12 -1
- package/package.json +1 -1
- package/src/AuthManager.ts +182 -57
- package/src/types.ts +16 -0
package/dist/AuthManager.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthManagerEvent, UserTokenPayload } from './types';
|
|
1
|
+
import { AuthManagerEvent, PlatformCheckResponse, UserTokenPayload } from './types';
|
|
2
2
|
export declare class AuthManager {
|
|
3
3
|
private static instance;
|
|
4
4
|
private authServer;
|
|
@@ -18,11 +18,24 @@ export declare class AuthManager {
|
|
|
18
18
|
getLoginWithGoogleUri(): string;
|
|
19
19
|
isLoggedIn(): Promise<boolean>;
|
|
20
20
|
getAccessToken(mustBeLoggedIn?: boolean): Promise<string>;
|
|
21
|
-
platformCheck(email: string
|
|
21
|
+
platformCheck(email: string): Promise<PlatformCheckResponse>;
|
|
22
22
|
verifyEmail(email: string, token: string): Promise<boolean>;
|
|
23
23
|
doPassReset(email: string, token: string, newPassword: string): Promise<boolean>;
|
|
24
24
|
changeEmail(email: string): Promise<boolean>;
|
|
25
25
|
initPasswordReset(email: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Updates user account fields. Only sends fields present in the update object.
|
|
28
|
+
* For password, expects: { old: string, new: string }
|
|
29
|
+
*/
|
|
30
|
+
updateAccount(update: {
|
|
31
|
+
firstName?: string;
|
|
32
|
+
lastName?: string;
|
|
33
|
+
email?: string;
|
|
34
|
+
password?: {
|
|
35
|
+
old: string;
|
|
36
|
+
new: string;
|
|
37
|
+
};
|
|
38
|
+
}): Promise<boolean>;
|
|
26
39
|
changePassword(oldPassword: string, newPassword: string, email: string): Promise<boolean>;
|
|
27
40
|
registerUsingEmail(firstName: string, lastName: string, email: string, password: string): Promise<void>;
|
|
28
41
|
private saveTokens;
|
package/dist/AuthManager.js
CHANGED
|
@@ -115,13 +115,24 @@ class AuthManager {
|
|
|
115
115
|
}
|
|
116
116
|
isLoggedIn() {
|
|
117
117
|
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
catch (error) {
|
|
118
|
+
const accessToken = localStorage.getItem('access_token');
|
|
119
|
+
const refreshToken = localStorage.getItem('refresh_token');
|
|
120
|
+
// If either token is missing, user is not logged in
|
|
121
|
+
if (!accessToken || !refreshToken) {
|
|
123
122
|
return false;
|
|
124
123
|
}
|
|
124
|
+
// If access token is expired, try to refresh
|
|
125
|
+
if (this.isTokenExpired(accessToken)) {
|
|
126
|
+
try {
|
|
127
|
+
yield this.refreshAccessToken();
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
catch (_a) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// If access token is valid
|
|
135
|
+
return true;
|
|
125
136
|
});
|
|
126
137
|
}
|
|
127
138
|
getAccessToken() {
|
|
@@ -139,7 +150,7 @@ class AuthManager {
|
|
|
139
150
|
}
|
|
140
151
|
});
|
|
141
152
|
}
|
|
142
|
-
platformCheck(email
|
|
153
|
+
platformCheck(email) {
|
|
143
154
|
return __awaiter(this, void 0, void 0, function* () {
|
|
144
155
|
const response = yield axios_1.default.post(`${this.authServer}auth/email/platform_check`, {
|
|
145
156
|
realm_name: this.realmName,
|
|
@@ -148,7 +159,9 @@ class AuthManager {
|
|
|
148
159
|
if (response.data.error || response.data.errors) {
|
|
149
160
|
throw new Error(response.data.error || response.data.message);
|
|
150
161
|
}
|
|
151
|
-
return
|
|
162
|
+
return response.status === 200
|
|
163
|
+
? response.data
|
|
164
|
+
: { platforms: [] };
|
|
152
165
|
});
|
|
153
166
|
}
|
|
154
167
|
verifyEmail(email, token) {
|
|
@@ -208,6 +221,57 @@ class AuthManager {
|
|
|
208
221
|
return response.status === 200 || response.status === 201;
|
|
209
222
|
});
|
|
210
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Updates user account fields. Only sends fields present in the update object.
|
|
226
|
+
* For password, expects: { old: string, new: string }
|
|
227
|
+
*/
|
|
228
|
+
updateAccount(update) {
|
|
229
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
+
const accessToken = localStorage.getItem('access_token');
|
|
231
|
+
if (!accessToken) {
|
|
232
|
+
throw new Error('Access token not found');
|
|
233
|
+
}
|
|
234
|
+
// Update name
|
|
235
|
+
if (update.firstName || update.lastName) {
|
|
236
|
+
const response = yield axios_1.default.post(`${this.authServer}auth/email/update_profile`, Object.assign(Object.assign({ realm_name: this.realmName }, (update.firstName && { first_name: update.firstName })), (update.lastName && { last_name: update.lastName })), {
|
|
237
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
238
|
+
});
|
|
239
|
+
if (response.data.error || response.data.errors) {
|
|
240
|
+
throw new Error(response.data.error || response.data.message);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Update email
|
|
244
|
+
if (update.email) {
|
|
245
|
+
const response = yield axios_1.default.post(`${this.authServer}auth/email/change_email`, {
|
|
246
|
+
realm_name: this.realmName,
|
|
247
|
+
email: update.email,
|
|
248
|
+
}, {
|
|
249
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
250
|
+
});
|
|
251
|
+
if (response.data.error || response.data.errors) {
|
|
252
|
+
throw new Error(response.data.error || response.data.message);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Update password
|
|
256
|
+
if (update.password && update.email) {
|
|
257
|
+
const response = yield axios_1.default.post(`${this.authServer}auth/email/change_pass`, {
|
|
258
|
+
realm_name: this.realmName,
|
|
259
|
+
email: update.email,
|
|
260
|
+
old_password: update.password.old,
|
|
261
|
+
new_password: update.password.new,
|
|
262
|
+
}, {
|
|
263
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
264
|
+
});
|
|
265
|
+
if (response.data.error || response.data.errors) {
|
|
266
|
+
throw new Error(response.data.error || response.data.message);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else if (update.password && !update.email) {
|
|
270
|
+
throw new Error('Email is required to change password');
|
|
271
|
+
}
|
|
272
|
+
return true;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
211
275
|
changePassword(oldPassword, newPassword, email) {
|
|
212
276
|
return __awaiter(this, void 0, void 0, function* () {
|
|
213
277
|
const accessToken = localStorage.getItem('access_token');
|
|
@@ -250,7 +314,9 @@ class AuthManager {
|
|
|
250
314
|
localStorage.setItem('access_token', response.data.access_token);
|
|
251
315
|
localStorage.setItem('refresh_token', response.data.refresh_token);
|
|
252
316
|
this.onStateChange({
|
|
253
|
-
type: byRefresh
|
|
317
|
+
type: byRefresh
|
|
318
|
+
? types_1.AuthEventType.USER_UPDATED
|
|
319
|
+
: types_1.AuthEventType.USER_LOGGED_IN,
|
|
254
320
|
user: this.tokenToPayload(response.data.access_token),
|
|
255
321
|
});
|
|
256
322
|
const user = this.tokenToPayload(response.data.access_token);
|
|
@@ -322,7 +388,9 @@ class AuthManager {
|
|
|
322
388
|
const userToken = {
|
|
323
389
|
id: decodedToken.id,
|
|
324
390
|
iss: decodedToken.iss,
|
|
325
|
-
sub: typeof decodedToken.sub === 'string'
|
|
391
|
+
sub: typeof decodedToken.sub === 'string'
|
|
392
|
+
? parseInt(decodedToken.sub)
|
|
393
|
+
: decodedToken.sub,
|
|
326
394
|
first_name: decodedToken.first_name,
|
|
327
395
|
last_name: decodedToken.last_name,
|
|
328
396
|
email: decodedToken.email,
|
|
@@ -331,6 +399,7 @@ class AuthManager {
|
|
|
331
399
|
exp: decodedToken.exp,
|
|
332
400
|
scopes: decodedToken.scopes,
|
|
333
401
|
realm: decodedToken.realm,
|
|
402
|
+
provider: decodedToken.provider,
|
|
334
403
|
};
|
|
335
404
|
const { data: publicKey } = yield axios_1.default.get(`${authServer}public/public_key`);
|
|
336
405
|
const { data: algo } = yield axios_1.default.get(`${authServer}public/algo`);
|
package/dist/types.d.ts
CHANGED
|
@@ -19,8 +19,22 @@ export interface UserTokenPayload {
|
|
|
19
19
|
exp: number;
|
|
20
20
|
scopes: string;
|
|
21
21
|
realm: string;
|
|
22
|
+
provider: Platforms;
|
|
22
23
|
}
|
|
23
24
|
export interface AuthManagerEvent {
|
|
24
25
|
type: AuthEventType;
|
|
25
26
|
user?: UserTokenPayload;
|
|
26
27
|
}
|
|
28
|
+
export interface PlatformCheckResponse {
|
|
29
|
+
platforms: Platforms[];
|
|
30
|
+
}
|
|
31
|
+
export declare enum Platforms {
|
|
32
|
+
PASSWORD = "password",
|
|
33
|
+
GOOGLE = "google",
|
|
34
|
+
FACEBOOK = "facebook",
|
|
35
|
+
TWITTER = "twitter",
|
|
36
|
+
GITHUB = "github",
|
|
37
|
+
APPLE = "apple",
|
|
38
|
+
LINKEDIN = "linkedin",
|
|
39
|
+
MICROSOFT = "microsoft"
|
|
40
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AuthEventType = void 0;
|
|
3
|
+
exports.Platforms = exports.AuthEventType = void 0;
|
|
4
4
|
var AuthEventType;
|
|
5
5
|
(function (AuthEventType) {
|
|
6
6
|
AuthEventType["INITALIZED_IN"] = "initialized-logged-in";
|
|
@@ -11,3 +11,14 @@ var AuthEventType;
|
|
|
11
11
|
AuthEventType["FAILED_MUST_LOGIN_CHECK"] = "failed-must-login";
|
|
12
12
|
AuthEventType["REFRESH_FAILED"] = "refresh-failed";
|
|
13
13
|
})(AuthEventType || (exports.AuthEventType = AuthEventType = {}));
|
|
14
|
+
var Platforms;
|
|
15
|
+
(function (Platforms) {
|
|
16
|
+
Platforms["PASSWORD"] = "password";
|
|
17
|
+
Platforms["GOOGLE"] = "google";
|
|
18
|
+
Platforms["FACEBOOK"] = "facebook";
|
|
19
|
+
Platforms["TWITTER"] = "twitter";
|
|
20
|
+
Platforms["GITHUB"] = "github";
|
|
21
|
+
Platforms["APPLE"] = "apple";
|
|
22
|
+
Platforms["LINKEDIN"] = "linkedin";
|
|
23
|
+
Platforms["MICROSOFT"] = "microsoft";
|
|
24
|
+
})(Platforms || (exports.Platforms = Platforms = {}));
|
package/package.json
CHANGED
package/src/AuthManager.ts
CHANGED
|
@@ -4,7 +4,12 @@ import {
|
|
|
4
4
|
decode as jwtDecode,
|
|
5
5
|
verify as jwtVerify,
|
|
6
6
|
} from 'jsonwebtoken'; // Ensure jsonwebtoken is correctly imported
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
AuthEventType,
|
|
9
|
+
AuthManagerEvent,
|
|
10
|
+
PlatformCheckResponse,
|
|
11
|
+
UserTokenPayload,
|
|
12
|
+
} from './types';
|
|
8
13
|
|
|
9
14
|
export class AuthManager {
|
|
10
15
|
private static instance: AuthManager | null = null;
|
|
@@ -44,16 +49,16 @@ export class AuthManager {
|
|
|
44
49
|
onStateChange,
|
|
45
50
|
);
|
|
46
51
|
AuthManager.instance
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
.checkAccessToken(true)
|
|
53
|
+
.then((token) => {
|
|
54
|
+
onStateChange({
|
|
55
|
+
type: AuthEventType.INITALIZED_IN,
|
|
56
|
+
user: AuthManager.instance.tokenToPayload(token),
|
|
57
|
+
});
|
|
58
|
+
})
|
|
59
|
+
.catch(() => {
|
|
60
|
+
onStateChange({ type: AuthEventType.INITALIZED_OUT });
|
|
52
61
|
});
|
|
53
|
-
})
|
|
54
|
-
.catch(() => {
|
|
55
|
-
onStateChange({ type: AuthEventType.INITALIZED_OUT });
|
|
56
|
-
});
|
|
57
62
|
}
|
|
58
63
|
return AuthManager.instance;
|
|
59
64
|
}
|
|
@@ -95,7 +100,9 @@ export class AuthManager {
|
|
|
95
100
|
return { verifier, challenge };
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
public async refreshAccessToken(
|
|
103
|
+
public async refreshAccessToken(
|
|
104
|
+
isInitialization: boolean = false,
|
|
105
|
+
): Promise<string> {
|
|
99
106
|
try {
|
|
100
107
|
const refreshToken = localStorage.getItem('refresh_token');
|
|
101
108
|
if (!refreshToken) {
|
|
@@ -122,7 +129,9 @@ export class AuthManager {
|
|
|
122
129
|
}
|
|
123
130
|
}
|
|
124
131
|
|
|
125
|
-
public async checkAccessToken(
|
|
132
|
+
public async checkAccessToken(
|
|
133
|
+
isInitilization: boolean = false,
|
|
134
|
+
): Promise<string> {
|
|
126
135
|
const accessToken = localStorage.getItem('access_token');
|
|
127
136
|
if (accessToken && this.isTokenExpired(accessToken)) {
|
|
128
137
|
return this.refreshAccessToken(isInitilization);
|
|
@@ -149,15 +158,31 @@ export class AuthManager {
|
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
public async isLoggedIn(): Promise<boolean> {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
161
|
+
const accessToken = localStorage.getItem('access_token');
|
|
162
|
+
const refreshToken = localStorage.getItem('refresh_token');
|
|
163
|
+
|
|
164
|
+
// If either token is missing, user is not logged in
|
|
165
|
+
if (!accessToken || !refreshToken) {
|
|
156
166
|
return false;
|
|
157
167
|
}
|
|
168
|
+
|
|
169
|
+
// If access token is expired, try to refresh
|
|
170
|
+
if (this.isTokenExpired(accessToken)) {
|
|
171
|
+
try {
|
|
172
|
+
await this.refreshAccessToken();
|
|
173
|
+
return true;
|
|
174
|
+
} catch {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// If access token is valid
|
|
180
|
+
return true;
|
|
158
181
|
}
|
|
159
182
|
|
|
160
|
-
public async getAccessToken(
|
|
183
|
+
public async getAccessToken(
|
|
184
|
+
mustBeLoggedIn: boolean = false,
|
|
185
|
+
): Promise<string> {
|
|
161
186
|
try {
|
|
162
187
|
return await this.checkAccessToken();
|
|
163
188
|
} catch (error) {
|
|
@@ -170,23 +195,29 @@ export class AuthManager {
|
|
|
170
195
|
}
|
|
171
196
|
}
|
|
172
197
|
|
|
173
|
-
|
|
174
|
-
|
|
198
|
+
public async platformCheck(
|
|
199
|
+
email: string,
|
|
200
|
+
): Promise<PlatformCheckResponse> {
|
|
175
201
|
const response = await axios.post(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
202
|
+
`${this.authServer}auth/email/platform_check`,
|
|
203
|
+
{
|
|
204
|
+
realm_name: this.realmName,
|
|
205
|
+
email,
|
|
206
|
+
},
|
|
181
207
|
);
|
|
182
208
|
if (response.data.error || response.data.errors) {
|
|
183
209
|
throw new Error(response.data.error || response.data.message);
|
|
184
210
|
}
|
|
185
211
|
|
|
186
|
-
return
|
|
212
|
+
return response.status === 200
|
|
213
|
+
? response.data
|
|
214
|
+
: { platforms: [] };
|
|
187
215
|
}
|
|
188
216
|
|
|
189
|
-
public async verifyEmail(
|
|
217
|
+
public async verifyEmail(
|
|
218
|
+
email: string,
|
|
219
|
+
token: string,
|
|
220
|
+
): Promise<boolean> {
|
|
190
221
|
const response = await axios.post(
|
|
191
222
|
`${this.authServer}auth/email/verify`,
|
|
192
223
|
{
|
|
@@ -202,15 +233,19 @@ export class AuthManager {
|
|
|
202
233
|
return response.status === 200;
|
|
203
234
|
}
|
|
204
235
|
|
|
205
|
-
public async doPassReset(
|
|
236
|
+
public async doPassReset(
|
|
237
|
+
email: string,
|
|
238
|
+
token: string,
|
|
239
|
+
newPassword: string,
|
|
240
|
+
): Promise<boolean> {
|
|
206
241
|
const response = await axios.post(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
242
|
+
`${this.authServer}auth/email/do_pass_reset`,
|
|
243
|
+
{
|
|
244
|
+
realm_name: this.realmName,
|
|
245
|
+
email,
|
|
246
|
+
token,
|
|
247
|
+
new_password: newPassword,
|
|
248
|
+
},
|
|
214
249
|
);
|
|
215
250
|
if (response.data.error || response.data.errors) {
|
|
216
251
|
throw new Error(response.data.error || response.data.message);
|
|
@@ -256,7 +291,85 @@ export class AuthManager {
|
|
|
256
291
|
return response.status === 200 || response.status === 201;
|
|
257
292
|
}
|
|
258
293
|
|
|
259
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Updates user account fields. Only sends fields present in the update object.
|
|
296
|
+
* For password, expects: { old: string, new: string }
|
|
297
|
+
*/
|
|
298
|
+
public async updateAccount(update: {
|
|
299
|
+
firstName?: string,
|
|
300
|
+
lastName?: string,
|
|
301
|
+
email?: string,
|
|
302
|
+
password?: { old: string, new: string, },
|
|
303
|
+
}): Promise<boolean> {
|
|
304
|
+
const accessToken = localStorage.getItem('access_token');
|
|
305
|
+
if (!accessToken) {
|
|
306
|
+
throw new Error('Access token not found');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Update name
|
|
310
|
+
if (update.firstName || update.lastName) {
|
|
311
|
+
const response = await axios.post(
|
|
312
|
+
`${this.authServer}auth/email/update_profile`,
|
|
313
|
+
{
|
|
314
|
+
realm_name: this.realmName,
|
|
315
|
+
...(update.firstName && { first_name: update.firstName }),
|
|
316
|
+
...(update.lastName && { last_name: update.lastName }),
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
320
|
+
},
|
|
321
|
+
);
|
|
322
|
+
if (response.data.error || response.data.errors) {
|
|
323
|
+
throw new Error(response.data.error || response.data.message);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Update email
|
|
328
|
+
if (update.email) {
|
|
329
|
+
const response = await axios.post(
|
|
330
|
+
`${this.authServer}auth/email/change_email`,
|
|
331
|
+
{
|
|
332
|
+
realm_name: this.realmName,
|
|
333
|
+
email: update.email,
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
337
|
+
},
|
|
338
|
+
);
|
|
339
|
+
if (response.data.error || response.data.errors) {
|
|
340
|
+
throw new Error(response.data.error || response.data.message);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Update password
|
|
345
|
+
if (update.password && update.email) {
|
|
346
|
+
const response = await axios.post(
|
|
347
|
+
`${this.authServer}auth/email/change_pass`,
|
|
348
|
+
{
|
|
349
|
+
realm_name: this.realmName,
|
|
350
|
+
email: update.email,
|
|
351
|
+
old_password: update.password.old,
|
|
352
|
+
new_password: update.password.new,
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
356
|
+
},
|
|
357
|
+
);
|
|
358
|
+
if (response.data.error || response.data.errors) {
|
|
359
|
+
throw new Error(response.data.error || response.data.message);
|
|
360
|
+
}
|
|
361
|
+
} else if (update.password && !update.email) {
|
|
362
|
+
throw new Error('Email is required to change password');
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
public async changePassword(
|
|
369
|
+
oldPassword: string,
|
|
370
|
+
newPassword: string,
|
|
371
|
+
email: string,
|
|
372
|
+
): Promise<boolean> {
|
|
260
373
|
const accessToken = localStorage.getItem('access_token');
|
|
261
374
|
if (!accessToken) {
|
|
262
375
|
throw new Error('Access token not found');
|
|
@@ -281,10 +394,10 @@ export class AuthManager {
|
|
|
281
394
|
}
|
|
282
395
|
|
|
283
396
|
public async registerUsingEmail(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
397
|
+
firstName: string,
|
|
398
|
+
lastName: string,
|
|
399
|
+
email: string,
|
|
400
|
+
password: string,
|
|
288
401
|
): Promise<void> {
|
|
289
402
|
const response = await axios.post(
|
|
290
403
|
`${this.authServer}auth/email/register`,
|
|
@@ -301,27 +414,35 @@ export class AuthManager {
|
|
|
301
414
|
}
|
|
302
415
|
|
|
303
416
|
if (!response.data.access_token) {
|
|
304
|
-
|
|
417
|
+
throw new Error('Something went wrong');
|
|
305
418
|
}
|
|
306
419
|
|
|
307
420
|
this.saveTokens(response, false);
|
|
308
421
|
}
|
|
309
422
|
|
|
310
|
-
private saveTokens(
|
|
423
|
+
private saveTokens(
|
|
424
|
+
response: AxiosResponse,
|
|
425
|
+
byRefresh: boolean,
|
|
426
|
+
): void {
|
|
311
427
|
localStorage.setItem('access_token', response.data.access_token);
|
|
312
428
|
localStorage.setItem(
|
|
313
429
|
'refresh_token',
|
|
314
430
|
response.data.refresh_token,
|
|
315
431
|
);
|
|
316
432
|
this.onStateChange({
|
|
317
|
-
type: byRefresh
|
|
433
|
+
type: byRefresh
|
|
434
|
+
? AuthEventType.USER_UPDATED
|
|
435
|
+
: AuthEventType.USER_LOGGED_IN,
|
|
318
436
|
user: this.tokenToPayload(response.data.access_token),
|
|
319
|
-
|
|
437
|
+
});
|
|
320
438
|
const user = this.tokenToPayload(response.data.access_token);
|
|
321
439
|
localStorage.setItem('user', JSON.stringify(user));
|
|
322
440
|
}
|
|
323
441
|
|
|
324
|
-
public async loginUsingEmail(
|
|
442
|
+
public async loginUsingEmail(
|
|
443
|
+
email: string,
|
|
444
|
+
password: string,
|
|
445
|
+
): Promise<void> {
|
|
325
446
|
const response = await axios.post(
|
|
326
447
|
`${this.authServer}auth/email/login`,
|
|
327
448
|
{
|
|
@@ -394,18 +515,22 @@ export class AuthManager {
|
|
|
394
515
|
}
|
|
395
516
|
|
|
396
517
|
const userToken: UserTokenPayload = {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
518
|
+
id: decodedToken.id,
|
|
519
|
+
iss: decodedToken.iss,
|
|
520
|
+
sub:
|
|
521
|
+
typeof decodedToken.sub === 'string'
|
|
522
|
+
? parseInt(decodedToken.sub)
|
|
523
|
+
: decodedToken.sub,
|
|
524
|
+
first_name: decodedToken.first_name,
|
|
525
|
+
last_name: decodedToken.last_name,
|
|
526
|
+
email: decodedToken.email,
|
|
527
|
+
aud: decodedToken.aud,
|
|
528
|
+
iat: decodedToken.iat,
|
|
529
|
+
exp: decodedToken.exp,
|
|
530
|
+
scopes: decodedToken.scopes,
|
|
531
|
+
realm: decodedToken.realm,
|
|
532
|
+
provider: decodedToken.provider,
|
|
533
|
+
};
|
|
409
534
|
|
|
410
535
|
const { data: publicKey } = await axios.get(
|
|
411
536
|
`${authServer}public/public_key`,
|
|
@@ -419,7 +544,7 @@ export class AuthManager {
|
|
|
419
544
|
const { data: revokedIds } = await axios.get(
|
|
420
545
|
`${authServer}public/revoked_ids`,
|
|
421
546
|
);
|
|
422
|
-
if(revokedIds.includes(decodedToken.id)){
|
|
547
|
+
if (revokedIds.includes(decodedToken.id)) {
|
|
423
548
|
throw new Error('Token is revoked');
|
|
424
549
|
}
|
|
425
550
|
return userToken;
|
package/src/types.ts
CHANGED
|
@@ -21,9 +21,25 @@ export interface UserTokenPayload {
|
|
|
21
21
|
exp: number;
|
|
22
22
|
scopes: string;
|
|
23
23
|
realm: string;
|
|
24
|
+
provider: Platforms;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export interface AuthManagerEvent {
|
|
27
28
|
type: AuthEventType;
|
|
28
29
|
user?: UserTokenPayload;
|
|
29
30
|
}
|
|
31
|
+
|
|
32
|
+
export interface PlatformCheckResponse {
|
|
33
|
+
platforms: Platforms[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export enum Platforms {
|
|
37
|
+
PASSWORD = 'password',
|
|
38
|
+
GOOGLE = 'google',
|
|
39
|
+
FACEBOOK = 'facebook',
|
|
40
|
+
TWITTER = 'twitter',
|
|
41
|
+
GITHUB = 'github',
|
|
42
|
+
APPLE = 'apple',
|
|
43
|
+
LINKEDIN = 'linkedin',
|
|
44
|
+
MICROSOFT = 'microsoft',
|
|
45
|
+
}
|