@bagelink/auth 1.6.47 → 1.6.51
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/index.cjs +40 -37
- package/dist/index.mjs +40 -37
- package/package.json +1 -1
- package/src/api.ts +1 -1
- package/src/sso.ts +17 -17
- package/src/types.ts +2 -2
- package/src/useAuth.ts +14 -14
- package/src/utils.ts +6 -3
package/dist/index.cjs
CHANGED
|
@@ -22,7 +22,10 @@ class EventEmitter {
|
|
|
22
22
|
if (!this.listeners.has(event)) {
|
|
23
23
|
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
24
24
|
}
|
|
25
|
-
this.listeners.get(event)
|
|
25
|
+
const listeners = this.listeners.get(event);
|
|
26
|
+
if (listeners !== void 0) {
|
|
27
|
+
listeners.add(handler);
|
|
28
|
+
}
|
|
26
29
|
}
|
|
27
30
|
off(event, handler) {
|
|
28
31
|
const eventListeners = this.listeners.get(event);
|
|
@@ -39,7 +42,7 @@ class EventEmitter {
|
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
removeAllListeners(event) {
|
|
42
|
-
if (event) {
|
|
45
|
+
if (event !== void 0) {
|
|
43
46
|
this.listeners.delete(event);
|
|
44
47
|
} else {
|
|
45
48
|
this.listeners.clear();
|
|
@@ -47,7 +50,7 @@ class EventEmitter {
|
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
function queryParams() {
|
|
50
|
-
if ("undefined"
|
|
53
|
+
if (typeof window === "undefined" || !window.location.search) {
|
|
51
54
|
return {};
|
|
52
55
|
}
|
|
53
56
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -68,7 +71,7 @@ class AuthApi {
|
|
|
68
71
|
this.api.interceptors.request.use((config) => {
|
|
69
72
|
const urlParams = new URLSearchParams(window.location.search);
|
|
70
73
|
const resetToken = urlParams.get("token");
|
|
71
|
-
if (
|
|
74
|
+
if (resetToken !== null) {
|
|
72
75
|
config.headers["X-Reset-Token"] = resetToken;
|
|
73
76
|
}
|
|
74
77
|
return config;
|
|
@@ -284,7 +287,7 @@ function setAuthContext(authApi) {
|
|
|
284
287
|
authApiRef = authApi;
|
|
285
288
|
}
|
|
286
289
|
function getAuthApi() {
|
|
287
|
-
if (
|
|
290
|
+
if (authApiRef === null || authApiRef === void 0) {
|
|
288
291
|
throw new Error("SSO auth context not initialized. Make sure to call useAuth() before using SSO methods.");
|
|
289
292
|
}
|
|
290
293
|
return authApiRef;
|
|
@@ -350,17 +353,17 @@ function waitForPopupCallback(popup, provider, timeoutMs = 9e4) {
|
|
|
350
353
|
}, timeoutMs);
|
|
351
354
|
function onMessage(ev) {
|
|
352
355
|
try {
|
|
353
|
-
if (
|
|
356
|
+
if (window.location.origin !== ev.origin) {
|
|
354
357
|
return;
|
|
355
358
|
}
|
|
356
|
-
const data = ev.data
|
|
357
|
-
if ("auth:complete"
|
|
359
|
+
const data = ev.data ?? {};
|
|
360
|
+
if (data.type !== "auth:complete" || provider !== data.provider) {
|
|
358
361
|
return;
|
|
359
362
|
}
|
|
360
363
|
cleanup();
|
|
361
|
-
if (data.error) {
|
|
364
|
+
if (data.error !== void 0 && data.error !== null) {
|
|
362
365
|
reject(new SSOError(data.error, "OAUTH_ERROR"));
|
|
363
|
-
} else if (data.code) {
|
|
366
|
+
} else if (data.code !== void 0 && data.code !== null) {
|
|
364
367
|
resolve({ code: data.code, state: data.state });
|
|
365
368
|
}
|
|
366
369
|
} catch {
|
|
@@ -374,19 +377,19 @@ function waitForPopupCallback(popup, provider, timeoutMs = 9e4) {
|
|
|
374
377
|
return;
|
|
375
378
|
}
|
|
376
379
|
const url = new URL(popup.location.href);
|
|
377
|
-
if (
|
|
380
|
+
if (window.location.origin === url.origin) {
|
|
378
381
|
const code = url.searchParams.get("code");
|
|
379
382
|
const state = url.searchParams.get("state") ?? void 0;
|
|
380
383
|
const error = url.searchParams.get("error");
|
|
381
|
-
if (code || error) {
|
|
384
|
+
if (code !== null && code !== "" || error !== null && error !== "") {
|
|
382
385
|
cleanup();
|
|
383
386
|
try {
|
|
384
387
|
popup.close();
|
|
385
388
|
} catch {
|
|
386
389
|
}
|
|
387
|
-
if (error) {
|
|
390
|
+
if (error !== null && error !== "") {
|
|
388
391
|
reject(new SSOError(error, "OAUTH_ERROR"));
|
|
389
|
-
} else if (code) {
|
|
392
|
+
} else if (code !== null && code !== "") {
|
|
390
393
|
resolve({ code, state });
|
|
391
394
|
}
|
|
392
395
|
}
|
|
@@ -410,7 +413,7 @@ function waitForPopupCallback(popup, provider, timeoutMs = 9e4) {
|
|
|
410
413
|
}
|
|
411
414
|
function createSSOProvider(config) {
|
|
412
415
|
const getDefaultRedirectUri = () => {
|
|
413
|
-
if ("undefined"
|
|
416
|
+
if (typeof window !== "undefined") {
|
|
414
417
|
return `${window.location.origin}/auth/callback`;
|
|
415
418
|
}
|
|
416
419
|
return `/auth/callback`;
|
|
@@ -422,7 +425,7 @@ function createSSOProvider(config) {
|
|
|
422
425
|
const auth = getAuthApi();
|
|
423
426
|
const redirectUri = options.redirectUri ?? getDefaultRedirectUri();
|
|
424
427
|
const state = options.state ?? generateState();
|
|
425
|
-
if ("undefined"
|
|
428
|
+
if (typeof sessionStorage !== "undefined") {
|
|
426
429
|
sessionStorage.setItem(getStateKey(), state);
|
|
427
430
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id);
|
|
428
431
|
}
|
|
@@ -440,7 +443,7 @@ function createSSOProvider(config) {
|
|
|
440
443
|
const redirectUri = options.redirectUri ?? getDefaultRedirectUri();
|
|
441
444
|
const state = options.state ?? generateState();
|
|
442
445
|
const timeout = options.popupTimeout ?? 9e4;
|
|
443
|
-
if ("undefined"
|
|
446
|
+
if (typeof sessionStorage !== "undefined") {
|
|
444
447
|
sessionStorage.setItem(getStateKey(), state);
|
|
445
448
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id);
|
|
446
449
|
}
|
|
@@ -465,11 +468,11 @@ function createSSOProvider(config) {
|
|
|
465
468
|
},
|
|
466
469
|
async callback(code, state) {
|
|
467
470
|
const auth = getAuthApi();
|
|
468
|
-
if ("undefined" !==
|
|
471
|
+
if (typeof sessionStorage !== "undefined" && state !== void 0 && state !== "") {
|
|
469
472
|
const storedState = sessionStorage.getItem(getStateKey());
|
|
470
473
|
sessionStorage.removeItem(getStateKey());
|
|
471
474
|
sessionStorage.removeItem(`oauth_provider:${state}`);
|
|
472
|
-
if (storedState && storedState !== state) {
|
|
475
|
+
if (storedState !== null && storedState !== state) {
|
|
473
476
|
throw new StateMismatchError();
|
|
474
477
|
}
|
|
475
478
|
}
|
|
@@ -481,11 +484,11 @@ function createSSOProvider(config) {
|
|
|
481
484
|
},
|
|
482
485
|
async link(code, state) {
|
|
483
486
|
const auth = getAuthApi();
|
|
484
|
-
if ("undefined" !==
|
|
487
|
+
if (typeof sessionStorage !== "undefined" && state !== void 0 && state !== "") {
|
|
485
488
|
const storedState = sessionStorage.getItem(getStateKey());
|
|
486
489
|
sessionStorage.removeItem(getStateKey());
|
|
487
490
|
sessionStorage.removeItem(`oauth_provider:${state}`);
|
|
488
|
-
if (storedState && storedState !== state) {
|
|
491
|
+
if (storedState !== null && storedState !== state) {
|
|
489
492
|
throw new StateMismatchError();
|
|
490
493
|
}
|
|
491
494
|
}
|
|
@@ -683,7 +686,7 @@ var AuthState = /* @__PURE__ */ ((AuthState2) => {
|
|
|
683
686
|
return AuthState2;
|
|
684
687
|
})(AuthState || {});
|
|
685
688
|
function accountToUser(account) {
|
|
686
|
-
if (
|
|
689
|
+
if (account === null) {
|
|
687
690
|
return null;
|
|
688
691
|
}
|
|
689
692
|
if (account.person !== void 0) {
|
|
@@ -714,7 +717,7 @@ function accountToUser(account) {
|
|
|
714
717
|
};
|
|
715
718
|
}
|
|
716
719
|
const emailMethod = account.authentication_methods.find(
|
|
717
|
-
(m) => "password"
|
|
720
|
+
(m) => m.type === "password" || m.type === "email_token"
|
|
718
721
|
);
|
|
719
722
|
return {
|
|
720
723
|
id: account.id,
|
|
@@ -734,10 +737,10 @@ const accountInfo = vue.ref(null);
|
|
|
734
737
|
function initAuth({
|
|
735
738
|
baseURL
|
|
736
739
|
}) {
|
|
737
|
-
if (
|
|
740
|
+
if (authApi === null) {
|
|
738
741
|
authApi = new AuthApi(baseURL);
|
|
739
742
|
}
|
|
740
|
-
if (
|
|
743
|
+
if (eventEmitter === null) {
|
|
741
744
|
eventEmitter = new EventEmitter();
|
|
742
745
|
}
|
|
743
746
|
return {
|
|
@@ -763,10 +766,10 @@ function initAuth({
|
|
|
763
766
|
};
|
|
764
767
|
}
|
|
765
768
|
function useAuth() {
|
|
766
|
-
if (
|
|
769
|
+
if (authApi === null) {
|
|
767
770
|
throw new Error("Auth not initialized. Call initAuth first.");
|
|
768
771
|
}
|
|
769
|
-
if (
|
|
772
|
+
if (eventEmitter === null) {
|
|
770
773
|
throw new Error("Event emitter not initialized. Call initAuth first.");
|
|
771
774
|
}
|
|
772
775
|
const api = authApi;
|
|
@@ -778,7 +781,7 @@ function useAuth() {
|
|
|
778
781
|
},
|
|
779
782
|
loginWithSSO: async (params) => {
|
|
780
783
|
const { data } = await api.ssoCallback(params);
|
|
781
|
-
if (
|
|
784
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
782
785
|
await checkAuth();
|
|
783
786
|
}
|
|
784
787
|
emitter.emit(AuthState.LOGIN);
|
|
@@ -799,7 +802,7 @@ function useAuth() {
|
|
|
799
802
|
return user.value?.name ?? "";
|
|
800
803
|
};
|
|
801
804
|
const getIsLoggedIn = () => {
|
|
802
|
-
return
|
|
805
|
+
return user.value !== null;
|
|
803
806
|
};
|
|
804
807
|
const getEmail = () => {
|
|
805
808
|
return user.value?.email ?? "";
|
|
@@ -811,10 +814,10 @@ function useAuth() {
|
|
|
811
814
|
return user.value?.type ?? "person";
|
|
812
815
|
};
|
|
813
816
|
const isPersonAccount = () => {
|
|
814
|
-
return
|
|
817
|
+
return user.value?.type === "person";
|
|
815
818
|
};
|
|
816
819
|
const isEntityAccount = () => {
|
|
817
|
-
return
|
|
820
|
+
return user.value?.type === "entity";
|
|
818
821
|
};
|
|
819
822
|
async function logout() {
|
|
820
823
|
const logoutPromise = api.logout();
|
|
@@ -828,7 +831,7 @@ function useAuth() {
|
|
|
828
831
|
credentials.email.toLowerCase(),
|
|
829
832
|
credentials.password
|
|
830
833
|
);
|
|
831
|
-
if (
|
|
834
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
832
835
|
await checkAuth();
|
|
833
836
|
}
|
|
834
837
|
emitter.emit(AuthState.LOGIN);
|
|
@@ -848,7 +851,7 @@ function useAuth() {
|
|
|
848
851
|
}
|
|
849
852
|
}
|
|
850
853
|
async function signup(newUser) {
|
|
851
|
-
const hasPassword = newUser.password !== void 0 &&
|
|
854
|
+
const hasPassword = newUser.password !== void 0 && newUser.password.length > 0;
|
|
852
855
|
if (hasPassword && newUser.password !== newUser.confirmPassword) {
|
|
853
856
|
throw new Error("Passwords do not match");
|
|
854
857
|
}
|
|
@@ -859,7 +862,7 @@ function useAuth() {
|
|
|
859
862
|
phone_number: newUser.phone_number,
|
|
860
863
|
password: newUser.password
|
|
861
864
|
});
|
|
862
|
-
if (
|
|
865
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
863
866
|
await checkAuth();
|
|
864
867
|
}
|
|
865
868
|
emitter.emit(AuthState.SIGNUP);
|
|
@@ -917,7 +920,7 @@ function useAuth() {
|
|
|
917
920
|
}
|
|
918
921
|
async function getSessions(accountId) {
|
|
919
922
|
const id = accountId ?? user.value?.accountId;
|
|
920
|
-
if (id === void 0 ||
|
|
923
|
+
if (id === void 0 || id === "") {
|
|
921
924
|
throw new Error("No account ID available");
|
|
922
925
|
}
|
|
923
926
|
return api.getSessions(id);
|
|
@@ -927,7 +930,7 @@ function useAuth() {
|
|
|
927
930
|
}
|
|
928
931
|
async function revokeAllSessions(accountId) {
|
|
929
932
|
const id = accountId ?? user.value?.accountId;
|
|
930
|
-
if (id === void 0 ||
|
|
933
|
+
if (id === void 0 || id === "") {
|
|
931
934
|
throw new Error("No account ID available");
|
|
932
935
|
}
|
|
933
936
|
await api.revokeAllSessions(id);
|
|
@@ -938,7 +941,7 @@ function useAuth() {
|
|
|
938
941
|
}
|
|
939
942
|
async function loginWithSSO(params) {
|
|
940
943
|
const { data } = await api.ssoCallback(params);
|
|
941
|
-
if (
|
|
944
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
942
945
|
await checkAuth();
|
|
943
946
|
}
|
|
944
947
|
emitter.emit(AuthState.LOGIN);
|
package/dist/index.mjs
CHANGED
|
@@ -16,7 +16,10 @@ class EventEmitter {
|
|
|
16
16
|
if (!this.listeners.has(event)) {
|
|
17
17
|
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
18
18
|
}
|
|
19
|
-
this.listeners.get(event)
|
|
19
|
+
const listeners = this.listeners.get(event);
|
|
20
|
+
if (listeners !== void 0) {
|
|
21
|
+
listeners.add(handler);
|
|
22
|
+
}
|
|
20
23
|
}
|
|
21
24
|
off(event, handler) {
|
|
22
25
|
const eventListeners = this.listeners.get(event);
|
|
@@ -33,7 +36,7 @@ class EventEmitter {
|
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
removeAllListeners(event) {
|
|
36
|
-
if (event) {
|
|
39
|
+
if (event !== void 0) {
|
|
37
40
|
this.listeners.delete(event);
|
|
38
41
|
} else {
|
|
39
42
|
this.listeners.clear();
|
|
@@ -41,7 +44,7 @@ class EventEmitter {
|
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
function queryParams() {
|
|
44
|
-
if ("undefined"
|
|
47
|
+
if (typeof window === "undefined" || !window.location.search) {
|
|
45
48
|
return {};
|
|
46
49
|
}
|
|
47
50
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -62,7 +65,7 @@ class AuthApi {
|
|
|
62
65
|
this.api.interceptors.request.use((config) => {
|
|
63
66
|
const urlParams = new URLSearchParams(window.location.search);
|
|
64
67
|
const resetToken = urlParams.get("token");
|
|
65
|
-
if (
|
|
68
|
+
if (resetToken !== null) {
|
|
66
69
|
config.headers["X-Reset-Token"] = resetToken;
|
|
67
70
|
}
|
|
68
71
|
return config;
|
|
@@ -278,7 +281,7 @@ function setAuthContext(authApi) {
|
|
|
278
281
|
authApiRef = authApi;
|
|
279
282
|
}
|
|
280
283
|
function getAuthApi() {
|
|
281
|
-
if (
|
|
284
|
+
if (authApiRef === null || authApiRef === void 0) {
|
|
282
285
|
throw new Error("SSO auth context not initialized. Make sure to call useAuth() before using SSO methods.");
|
|
283
286
|
}
|
|
284
287
|
return authApiRef;
|
|
@@ -344,17 +347,17 @@ function waitForPopupCallback(popup, provider, timeoutMs = 9e4) {
|
|
|
344
347
|
}, timeoutMs);
|
|
345
348
|
function onMessage(ev) {
|
|
346
349
|
try {
|
|
347
|
-
if (
|
|
350
|
+
if (window.location.origin !== ev.origin) {
|
|
348
351
|
return;
|
|
349
352
|
}
|
|
350
|
-
const data = ev.data
|
|
351
|
-
if ("auth:complete"
|
|
353
|
+
const data = ev.data ?? {};
|
|
354
|
+
if (data.type !== "auth:complete" || provider !== data.provider) {
|
|
352
355
|
return;
|
|
353
356
|
}
|
|
354
357
|
cleanup();
|
|
355
|
-
if (data.error) {
|
|
358
|
+
if (data.error !== void 0 && data.error !== null) {
|
|
356
359
|
reject(new SSOError(data.error, "OAUTH_ERROR"));
|
|
357
|
-
} else if (data.code) {
|
|
360
|
+
} else if (data.code !== void 0 && data.code !== null) {
|
|
358
361
|
resolve({ code: data.code, state: data.state });
|
|
359
362
|
}
|
|
360
363
|
} catch {
|
|
@@ -368,19 +371,19 @@ function waitForPopupCallback(popup, provider, timeoutMs = 9e4) {
|
|
|
368
371
|
return;
|
|
369
372
|
}
|
|
370
373
|
const url = new URL(popup.location.href);
|
|
371
|
-
if (
|
|
374
|
+
if (window.location.origin === url.origin) {
|
|
372
375
|
const code = url.searchParams.get("code");
|
|
373
376
|
const state = url.searchParams.get("state") ?? void 0;
|
|
374
377
|
const error = url.searchParams.get("error");
|
|
375
|
-
if (code || error) {
|
|
378
|
+
if (code !== null && code !== "" || error !== null && error !== "") {
|
|
376
379
|
cleanup();
|
|
377
380
|
try {
|
|
378
381
|
popup.close();
|
|
379
382
|
} catch {
|
|
380
383
|
}
|
|
381
|
-
if (error) {
|
|
384
|
+
if (error !== null && error !== "") {
|
|
382
385
|
reject(new SSOError(error, "OAUTH_ERROR"));
|
|
383
|
-
} else if (code) {
|
|
386
|
+
} else if (code !== null && code !== "") {
|
|
384
387
|
resolve({ code, state });
|
|
385
388
|
}
|
|
386
389
|
}
|
|
@@ -404,7 +407,7 @@ function waitForPopupCallback(popup, provider, timeoutMs = 9e4) {
|
|
|
404
407
|
}
|
|
405
408
|
function createSSOProvider(config) {
|
|
406
409
|
const getDefaultRedirectUri = () => {
|
|
407
|
-
if ("undefined"
|
|
410
|
+
if (typeof window !== "undefined") {
|
|
408
411
|
return `${window.location.origin}/auth/callback`;
|
|
409
412
|
}
|
|
410
413
|
return `/auth/callback`;
|
|
@@ -416,7 +419,7 @@ function createSSOProvider(config) {
|
|
|
416
419
|
const auth = getAuthApi();
|
|
417
420
|
const redirectUri = options.redirectUri ?? getDefaultRedirectUri();
|
|
418
421
|
const state = options.state ?? generateState();
|
|
419
|
-
if ("undefined"
|
|
422
|
+
if (typeof sessionStorage !== "undefined") {
|
|
420
423
|
sessionStorage.setItem(getStateKey(), state);
|
|
421
424
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id);
|
|
422
425
|
}
|
|
@@ -434,7 +437,7 @@ function createSSOProvider(config) {
|
|
|
434
437
|
const redirectUri = options.redirectUri ?? getDefaultRedirectUri();
|
|
435
438
|
const state = options.state ?? generateState();
|
|
436
439
|
const timeout = options.popupTimeout ?? 9e4;
|
|
437
|
-
if ("undefined"
|
|
440
|
+
if (typeof sessionStorage !== "undefined") {
|
|
438
441
|
sessionStorage.setItem(getStateKey(), state);
|
|
439
442
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id);
|
|
440
443
|
}
|
|
@@ -459,11 +462,11 @@ function createSSOProvider(config) {
|
|
|
459
462
|
},
|
|
460
463
|
async callback(code, state) {
|
|
461
464
|
const auth = getAuthApi();
|
|
462
|
-
if ("undefined" !==
|
|
465
|
+
if (typeof sessionStorage !== "undefined" && state !== void 0 && state !== "") {
|
|
463
466
|
const storedState = sessionStorage.getItem(getStateKey());
|
|
464
467
|
sessionStorage.removeItem(getStateKey());
|
|
465
468
|
sessionStorage.removeItem(`oauth_provider:${state}`);
|
|
466
|
-
if (storedState && storedState !== state) {
|
|
469
|
+
if (storedState !== null && storedState !== state) {
|
|
467
470
|
throw new StateMismatchError();
|
|
468
471
|
}
|
|
469
472
|
}
|
|
@@ -475,11 +478,11 @@ function createSSOProvider(config) {
|
|
|
475
478
|
},
|
|
476
479
|
async link(code, state) {
|
|
477
480
|
const auth = getAuthApi();
|
|
478
|
-
if ("undefined" !==
|
|
481
|
+
if (typeof sessionStorage !== "undefined" && state !== void 0 && state !== "") {
|
|
479
482
|
const storedState = sessionStorage.getItem(getStateKey());
|
|
480
483
|
sessionStorage.removeItem(getStateKey());
|
|
481
484
|
sessionStorage.removeItem(`oauth_provider:${state}`);
|
|
482
|
-
if (storedState && storedState !== state) {
|
|
485
|
+
if (storedState !== null && storedState !== state) {
|
|
483
486
|
throw new StateMismatchError();
|
|
484
487
|
}
|
|
485
488
|
}
|
|
@@ -677,7 +680,7 @@ var AuthState = /* @__PURE__ */ ((AuthState2) => {
|
|
|
677
680
|
return AuthState2;
|
|
678
681
|
})(AuthState || {});
|
|
679
682
|
function accountToUser(account) {
|
|
680
|
-
if (
|
|
683
|
+
if (account === null) {
|
|
681
684
|
return null;
|
|
682
685
|
}
|
|
683
686
|
if (account.person !== void 0) {
|
|
@@ -708,7 +711,7 @@ function accountToUser(account) {
|
|
|
708
711
|
};
|
|
709
712
|
}
|
|
710
713
|
const emailMethod = account.authentication_methods.find(
|
|
711
|
-
(m) => "password"
|
|
714
|
+
(m) => m.type === "password" || m.type === "email_token"
|
|
712
715
|
);
|
|
713
716
|
return {
|
|
714
717
|
id: account.id,
|
|
@@ -728,10 +731,10 @@ const accountInfo = ref(null);
|
|
|
728
731
|
function initAuth({
|
|
729
732
|
baseURL
|
|
730
733
|
}) {
|
|
731
|
-
if (
|
|
734
|
+
if (authApi === null) {
|
|
732
735
|
authApi = new AuthApi(baseURL);
|
|
733
736
|
}
|
|
734
|
-
if (
|
|
737
|
+
if (eventEmitter === null) {
|
|
735
738
|
eventEmitter = new EventEmitter();
|
|
736
739
|
}
|
|
737
740
|
return {
|
|
@@ -757,10 +760,10 @@ function initAuth({
|
|
|
757
760
|
};
|
|
758
761
|
}
|
|
759
762
|
function useAuth() {
|
|
760
|
-
if (
|
|
763
|
+
if (authApi === null) {
|
|
761
764
|
throw new Error("Auth not initialized. Call initAuth first.");
|
|
762
765
|
}
|
|
763
|
-
if (
|
|
766
|
+
if (eventEmitter === null) {
|
|
764
767
|
throw new Error("Event emitter not initialized. Call initAuth first.");
|
|
765
768
|
}
|
|
766
769
|
const api = authApi;
|
|
@@ -772,7 +775,7 @@ function useAuth() {
|
|
|
772
775
|
},
|
|
773
776
|
loginWithSSO: async (params) => {
|
|
774
777
|
const { data } = await api.ssoCallback(params);
|
|
775
|
-
if (
|
|
778
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
776
779
|
await checkAuth();
|
|
777
780
|
}
|
|
778
781
|
emitter.emit(AuthState.LOGIN);
|
|
@@ -793,7 +796,7 @@ function useAuth() {
|
|
|
793
796
|
return user.value?.name ?? "";
|
|
794
797
|
};
|
|
795
798
|
const getIsLoggedIn = () => {
|
|
796
|
-
return
|
|
799
|
+
return user.value !== null;
|
|
797
800
|
};
|
|
798
801
|
const getEmail = () => {
|
|
799
802
|
return user.value?.email ?? "";
|
|
@@ -805,10 +808,10 @@ function useAuth() {
|
|
|
805
808
|
return user.value?.type ?? "person";
|
|
806
809
|
};
|
|
807
810
|
const isPersonAccount = () => {
|
|
808
|
-
return
|
|
811
|
+
return user.value?.type === "person";
|
|
809
812
|
};
|
|
810
813
|
const isEntityAccount = () => {
|
|
811
|
-
return
|
|
814
|
+
return user.value?.type === "entity";
|
|
812
815
|
};
|
|
813
816
|
async function logout() {
|
|
814
817
|
const logoutPromise = api.logout();
|
|
@@ -822,7 +825,7 @@ function useAuth() {
|
|
|
822
825
|
credentials.email.toLowerCase(),
|
|
823
826
|
credentials.password
|
|
824
827
|
);
|
|
825
|
-
if (
|
|
828
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
826
829
|
await checkAuth();
|
|
827
830
|
}
|
|
828
831
|
emitter.emit(AuthState.LOGIN);
|
|
@@ -842,7 +845,7 @@ function useAuth() {
|
|
|
842
845
|
}
|
|
843
846
|
}
|
|
844
847
|
async function signup(newUser) {
|
|
845
|
-
const hasPassword = newUser.password !== void 0 &&
|
|
848
|
+
const hasPassword = newUser.password !== void 0 && newUser.password.length > 0;
|
|
846
849
|
if (hasPassword && newUser.password !== newUser.confirmPassword) {
|
|
847
850
|
throw new Error("Passwords do not match");
|
|
848
851
|
}
|
|
@@ -853,7 +856,7 @@ function useAuth() {
|
|
|
853
856
|
phone_number: newUser.phone_number,
|
|
854
857
|
password: newUser.password
|
|
855
858
|
});
|
|
856
|
-
if (
|
|
859
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
857
860
|
await checkAuth();
|
|
858
861
|
}
|
|
859
862
|
emitter.emit(AuthState.SIGNUP);
|
|
@@ -911,7 +914,7 @@ function useAuth() {
|
|
|
911
914
|
}
|
|
912
915
|
async function getSessions(accountId) {
|
|
913
916
|
const id = accountId ?? user.value?.accountId;
|
|
914
|
-
if (id === void 0 ||
|
|
917
|
+
if (id === void 0 || id === "") {
|
|
915
918
|
throw new Error("No account ID available");
|
|
916
919
|
}
|
|
917
920
|
return api.getSessions(id);
|
|
@@ -921,7 +924,7 @@ function useAuth() {
|
|
|
921
924
|
}
|
|
922
925
|
async function revokeAllSessions(accountId) {
|
|
923
926
|
const id = accountId ?? user.value?.accountId;
|
|
924
|
-
if (id === void 0 ||
|
|
927
|
+
if (id === void 0 || id === "") {
|
|
925
928
|
throw new Error("No account ID available");
|
|
926
929
|
}
|
|
927
930
|
await api.revokeAllSessions(id);
|
|
@@ -932,7 +935,7 @@ function useAuth() {
|
|
|
932
935
|
}
|
|
933
936
|
async function loginWithSSO(params) {
|
|
934
937
|
const { data } = await api.ssoCallback(params);
|
|
935
|
-
if (
|
|
938
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
936
939
|
await checkAuth();
|
|
937
940
|
}
|
|
938
941
|
emitter.emit(AuthState.LOGIN);
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -53,7 +53,7 @@ export class AuthApi {
|
|
|
53
53
|
// Handle password reset token from URL
|
|
54
54
|
const urlParams = new URLSearchParams(window.location.search)
|
|
55
55
|
const resetToken = urlParams.get('token')
|
|
56
|
-
if (
|
|
56
|
+
if (resetToken !== null) {
|
|
57
57
|
config.headers['X-Reset-Token'] = resetToken
|
|
58
58
|
}
|
|
59
59
|
return config
|
package/src/sso.ts
CHANGED
|
@@ -16,7 +16,7 @@ export function setAuthContext(authApi: any) {
|
|
|
16
16
|
* Get current auth context
|
|
17
17
|
*/
|
|
18
18
|
function getAuthApi() {
|
|
19
|
-
if (
|
|
19
|
+
if (authApiRef === null || authApiRef === undefined) {
|
|
20
20
|
throw new Error('SSO auth context not initialized. Make sure to call useAuth() before using SSO methods.')
|
|
21
21
|
}
|
|
22
22
|
return authApiRef
|
|
@@ -220,15 +220,15 @@ function waitForPopupCallback(popup: Window, provider: string, timeoutMs = 90000
|
|
|
220
220
|
function onMessage(ev: MessageEvent) {
|
|
221
221
|
try {
|
|
222
222
|
// Strict origin check
|
|
223
|
-
if (
|
|
223
|
+
if (window.location.origin !== ev.origin) { return }
|
|
224
224
|
|
|
225
|
-
const data = ev.data
|
|
226
|
-
if ('auth:complete'
|
|
225
|
+
const data = ev.data ?? {}
|
|
226
|
+
if (data.type !== 'auth:complete' || provider !== data.provider) { return }
|
|
227
227
|
|
|
228
228
|
cleanup()
|
|
229
|
-
if (data.error) {
|
|
229
|
+
if (data.error !== undefined && data.error !== null) {
|
|
230
230
|
reject(new SSOError(data.error, 'OAUTH_ERROR'))
|
|
231
|
-
} else if (data.code) {
|
|
231
|
+
} else if (data.code !== undefined && data.code !== null) {
|
|
232
232
|
resolve({ code: data.code, state: data.state })
|
|
233
233
|
}
|
|
234
234
|
} catch {
|
|
@@ -247,12 +247,12 @@ function waitForPopupCallback(popup: Window, provider: string, timeoutMs = 90000
|
|
|
247
247
|
|
|
248
248
|
// Try to read popup URL (only works when same-origin)
|
|
249
249
|
const url = new URL(popup.location.href)
|
|
250
|
-
if (
|
|
250
|
+
if (window.location.origin === url.origin) {
|
|
251
251
|
const code = url.searchParams.get('code')
|
|
252
252
|
const state = url.searchParams.get('state') ?? undefined
|
|
253
253
|
const error = url.searchParams.get('error')
|
|
254
254
|
|
|
255
|
-
if (code || error) {
|
|
255
|
+
if ((code !== null && code !== '') || (error !== null && error !== '')) {
|
|
256
256
|
cleanup()
|
|
257
257
|
try {
|
|
258
258
|
popup.close()
|
|
@@ -260,9 +260,9 @@ function waitForPopupCallback(popup: Window, provider: string, timeoutMs = 90000
|
|
|
260
260
|
// Ignore close errors
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
if (error) {
|
|
263
|
+
if (error !== null && error !== '') {
|
|
264
264
|
reject(new SSOError(error, 'OAUTH_ERROR'))
|
|
265
|
-
} else if (code) {
|
|
265
|
+
} else if (code !== null && code !== '') {
|
|
266
266
|
resolve({ code, state })
|
|
267
267
|
}
|
|
268
268
|
}
|
|
@@ -295,7 +295,7 @@ function waitForPopupCallback(popup: Window, provider: string, timeoutMs = 90000
|
|
|
295
295
|
*/
|
|
296
296
|
function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
297
297
|
const getDefaultRedirectUri = () => {
|
|
298
|
-
if ('undefined'
|
|
298
|
+
if (typeof window !== 'undefined') {
|
|
299
299
|
return `${window.location.origin}/auth/callback`
|
|
300
300
|
}
|
|
301
301
|
return `/auth/callback`
|
|
@@ -315,7 +315,7 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
315
315
|
const state = options.state ?? generateState()
|
|
316
316
|
|
|
317
317
|
// Store state AND provider in sessionStorage for verification
|
|
318
|
-
if ('undefined'
|
|
318
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
319
319
|
sessionStorage.setItem(getStateKey(), state)
|
|
320
320
|
// Map state -> provider so we can identify which provider on callback
|
|
321
321
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id)
|
|
@@ -339,7 +339,7 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
339
339
|
const timeout = options.popupTimeout ?? 90000
|
|
340
340
|
|
|
341
341
|
// Store state AND provider in sessionStorage for verification
|
|
342
|
-
if ('undefined'
|
|
342
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
343
343
|
sessionStorage.setItem(getStateKey(), state)
|
|
344
344
|
// Map state -> provider so we can identify which provider on callback
|
|
345
345
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id)
|
|
@@ -373,13 +373,13 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
373
373
|
const auth = getAuthApi()
|
|
374
374
|
|
|
375
375
|
// Verify state if it was stored (per-provider key)
|
|
376
|
-
if ('undefined' !==
|
|
376
|
+
if (typeof sessionStorage !== 'undefined' && state !== undefined && state !== '') {
|
|
377
377
|
const storedState = sessionStorage.getItem(getStateKey())
|
|
378
378
|
sessionStorage.removeItem(getStateKey())
|
|
379
379
|
// Clean up provider mapping
|
|
380
380
|
sessionStorage.removeItem(`oauth_provider:${state}`)
|
|
381
381
|
|
|
382
|
-
if (storedState && storedState !== state) {
|
|
382
|
+
if (storedState !== null && storedState !== state) {
|
|
383
383
|
throw new StateMismatchError()
|
|
384
384
|
}
|
|
385
385
|
}
|
|
@@ -395,13 +395,13 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
395
395
|
const auth = getAuthApi()
|
|
396
396
|
|
|
397
397
|
// Verify state if it was stored (per-provider key)
|
|
398
|
-
if ('undefined' !==
|
|
398
|
+
if (typeof sessionStorage !== 'undefined' && state !== undefined && state !== '') {
|
|
399
399
|
const storedState = sessionStorage.getItem(getStateKey())
|
|
400
400
|
sessionStorage.removeItem(getStateKey())
|
|
401
401
|
// Clean up provider mapping
|
|
402
402
|
sessionStorage.removeItem(`oauth_provider:${state}`)
|
|
403
403
|
|
|
404
|
-
if (storedState && storedState !== state) {
|
|
404
|
+
if (storedState !== null && storedState !== state) {
|
|
405
405
|
throw new StateMismatchError()
|
|
406
406
|
}
|
|
407
407
|
}
|
package/src/types.ts
CHANGED
|
@@ -311,7 +311,7 @@ export type SSOUnlinkResponse = AxiosResponse<MessageResponse>
|
|
|
311
311
|
* Extract unified user from account info
|
|
312
312
|
*/
|
|
313
313
|
export function accountToUser(account: AccountInfo | null): User | null {
|
|
314
|
-
if (
|
|
314
|
+
if (account === null) { return null }
|
|
315
315
|
|
|
316
316
|
// Person account - most common case
|
|
317
317
|
if (account.person !== undefined) {
|
|
@@ -347,7 +347,7 @@ export function accountToUser(account: AccountInfo | null): User | null {
|
|
|
347
347
|
// Fallback - use account info directly
|
|
348
348
|
// Extract email from authentication methods
|
|
349
349
|
const emailMethod = account.authentication_methods.find(
|
|
350
|
-
m => 'password'
|
|
350
|
+
m => m.type === 'password' || m.type === 'email_token',
|
|
351
351
|
)
|
|
352
352
|
|
|
353
353
|
return {
|
package/src/useAuth.ts
CHANGED
|
@@ -28,11 +28,11 @@ export function initAuth({
|
|
|
28
28
|
}: {
|
|
29
29
|
baseURL: string
|
|
30
30
|
}) {
|
|
31
|
-
if (
|
|
31
|
+
if (authApi === null) {
|
|
32
32
|
authApi = new AuthApi(baseURL)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
if (
|
|
35
|
+
if (eventEmitter === null) {
|
|
36
36
|
eventEmitter = new EventEmitter()
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -65,11 +65,11 @@ export function initAuth({
|
|
|
65
65
|
|
|
66
66
|
// Composable
|
|
67
67
|
export function useAuth() {
|
|
68
|
-
if (
|
|
68
|
+
if (authApi === null) {
|
|
69
69
|
throw new Error('Auth not initialized. Call initAuth first.')
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
if (
|
|
72
|
+
if (eventEmitter === null) {
|
|
73
73
|
throw new Error('Event emitter not initialized. Call initAuth first.')
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -84,7 +84,7 @@ export function useAuth() {
|
|
|
84
84
|
},
|
|
85
85
|
loginWithSSO: async (params: SSOCallbackRequest) => {
|
|
86
86
|
const { data } = await api.ssoCallback(params)
|
|
87
|
-
if (
|
|
87
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
88
88
|
await checkAuth()
|
|
89
89
|
}
|
|
90
90
|
emitter.emit(AuthState.LOGIN)
|
|
@@ -110,7 +110,7 @@ export function useAuth() {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
const getIsLoggedIn = () => {
|
|
113
|
-
return
|
|
113
|
+
return user.value !== null
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
const getEmail = () => {
|
|
@@ -126,11 +126,11 @@ export function useAuth() {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
const isPersonAccount = () => {
|
|
129
|
-
return
|
|
129
|
+
return user.value?.type === 'person'
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
const isEntityAccount = () => {
|
|
133
|
-
return
|
|
133
|
+
return user.value?.type === 'entity'
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
// Actions
|
|
@@ -153,7 +153,7 @@ export function useAuth() {
|
|
|
153
153
|
)
|
|
154
154
|
|
|
155
155
|
// If successful and not requiring verification, fetch user data
|
|
156
|
-
if (
|
|
156
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
157
157
|
await checkAuth()
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -177,7 +177,7 @@ export function useAuth() {
|
|
|
177
177
|
|
|
178
178
|
async function signup(newUser: NewUser) {
|
|
179
179
|
// Check password match if password is provided
|
|
180
|
-
const hasPassword = newUser.password !== undefined &&
|
|
180
|
+
const hasPassword = newUser.password !== undefined && newUser.password.length > 0
|
|
181
181
|
if (hasPassword && newUser.password !== newUser.confirmPassword) {
|
|
182
182
|
throw new Error('Passwords do not match')
|
|
183
183
|
}
|
|
@@ -191,7 +191,7 @@ export function useAuth() {
|
|
|
191
191
|
})
|
|
192
192
|
|
|
193
193
|
// If successful and not requiring verification, fetch user data
|
|
194
|
-
if (
|
|
194
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
195
195
|
await checkAuth()
|
|
196
196
|
}
|
|
197
197
|
|
|
@@ -264,7 +264,7 @@ export function useAuth() {
|
|
|
264
264
|
|
|
265
265
|
async function getSessions(accountId?: string) {
|
|
266
266
|
const id = accountId ?? user.value?.accountId
|
|
267
|
-
if (id === undefined ||
|
|
267
|
+
if (id === undefined || id === '') {
|
|
268
268
|
throw new Error('No account ID available')
|
|
269
269
|
}
|
|
270
270
|
return api.getSessions(id)
|
|
@@ -276,7 +276,7 @@ export function useAuth() {
|
|
|
276
276
|
|
|
277
277
|
async function revokeAllSessions(accountId?: string) {
|
|
278
278
|
const id = accountId ?? user.value?.accountId
|
|
279
|
-
if (id === undefined ||
|
|
279
|
+
if (id === undefined || id === '') {
|
|
280
280
|
throw new Error('No account ID available')
|
|
281
281
|
}
|
|
282
282
|
await api.revokeAllSessions(id)
|
|
@@ -302,7 +302,7 @@ export function useAuth() {
|
|
|
302
302
|
const { data } = await api.ssoCallback(params)
|
|
303
303
|
|
|
304
304
|
// If successful and not requiring verification, fetch user data
|
|
305
|
-
if (
|
|
305
|
+
if (data.success === true && data.requires_verification !== true) {
|
|
306
306
|
await checkAuth()
|
|
307
307
|
}
|
|
308
308
|
|
package/src/utils.ts
CHANGED
|
@@ -19,7 +19,10 @@ export class EventEmitter {
|
|
|
19
19
|
if (!this.listeners.has(event)) {
|
|
20
20
|
this.listeners.set(event, new Set())
|
|
21
21
|
}
|
|
22
|
-
this.listeners.get(event)
|
|
22
|
+
const listeners = this.listeners.get(event)
|
|
23
|
+
if (listeners !== undefined) {
|
|
24
|
+
listeners.add(handler)
|
|
25
|
+
}
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
off<K extends AuthState>(event: K, handler: AuthEventMap[K]): void {
|
|
@@ -37,7 +40,7 @@ export class EventEmitter {
|
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
removeAllListeners<K extends AuthState>(event?: K): void {
|
|
40
|
-
if (event) {
|
|
43
|
+
if (event !== undefined) {
|
|
41
44
|
this.listeners.delete(event)
|
|
42
45
|
} else {
|
|
43
46
|
this.listeners.clear()
|
|
@@ -46,7 +49,7 @@ export class EventEmitter {
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
export function queryParams(): Record<string, string> {
|
|
49
|
-
if ('undefined'
|
|
52
|
+
if (typeof window === 'undefined' || !window.location.search) {
|
|
50
53
|
return {}
|
|
51
54
|
}
|
|
52
55
|
const params = new URLSearchParams(window.location.search)
|