@djangocfg/api 2.1.448 → 2.1.450
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/auth-server.cjs +1 -2272
- package/dist/auth-server.cjs.map +1 -1
- package/dist/auth-server.d.cts +1 -35
- package/dist/auth-server.d.ts +1 -35
- package/dist/auth-server.mjs +1 -2272
- package/dist/auth-server.mjs.map +1 -1
- package/dist/auth.cjs +285 -146
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +137 -2
- package/dist/auth.d.ts +137 -2
- package/dist/auth.mjs +294 -155
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +35 -0
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.d.cts +147 -2
- package/dist/clients.d.ts +147 -2
- package/dist/clients.mjs +35 -0
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +11 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +11 -0
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +35 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +169 -6
- package/dist/index.d.ts +169 -6
- package/dist/index.mjs +35 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -4
- package/src/_api/generated/_cfg_accounts/api.ts +8 -0
- package/src/_api/generated/_cfg_accounts/openapi.json +84 -5
- package/src/_api/generated/_cfg_accounts/schemas/OAuthTokenResponse.ts +2 -2
- package/src/_api/generated/_cfg_accounts/schemas/OTPRequestResponse.ts +2 -0
- package/src/_api/generated/_cfg_accounts/schemas/WebmailLink.ts +15 -0
- package/src/_api/generated/_cfg_accounts/schemas/WebmailLinkProviderEnum.ts +9 -0
- package/src/_api/generated/_cfg_accounts/schemas/index.ts +2 -0
- package/src/_api/generated/_cfg_centrifugo/api.ts +8 -0
- package/src/_api/generated/_cfg_totp/api.ts +8 -0
- package/src/_api/generated/helpers/auth.ts +12 -0
- package/src/_api/generated/openapi.json +84 -5
- package/src/_api/generated/types.gen.ts +131 -2
- package/src/auth/__tests__/jwt.test.ts +119 -0
- package/src/auth/__tests__/onUnauthorized.test.ts +206 -0
- package/src/auth/__tests__/refreshRotation.test.ts +119 -0
- package/src/auth/__tests__/sessionBootstrap.test.ts +76 -0
- package/src/auth/context/AuthContext.tsx +131 -14
- package/src/auth/hooks/useAuthForm.ts +5 -2
- package/src/auth/hooks/useAuthFormState.ts +4 -1
- package/src/auth/hooks/useTokenRefresh.ts +28 -62
- package/src/auth/middlewares/index.ts +7 -7
- package/src/auth/refreshHandler.ts +79 -0
- package/src/auth/types/form.ts +10 -0
- package/src/auth/types/index.ts +1 -0
- package/src/auth/utils/jwt.ts +66 -0
- package/src/auth/middlewares/tokenRefresh.ts +0 -161
package/dist/auth.mjs
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
useContext as useContext2,
|
|
28
28
|
useEffect as useEffect9,
|
|
29
29
|
useMemo as useMemo3,
|
|
30
|
-
useRef as
|
|
30
|
+
useRef as useRef6,
|
|
31
31
|
useState as useState12
|
|
32
32
|
} from "react";
|
|
33
33
|
import { SWRConfig } from "swr";
|
|
@@ -161,6 +161,7 @@ var useAuthFormState = /* @__PURE__ */ __name((initialIdentifier = "") => {
|
|
|
161
161
|
const [acceptedTerms, setAcceptedTerms] = useState2(true);
|
|
162
162
|
const [step, setStep] = useState2("identifier");
|
|
163
163
|
const [error, setError] = useState2("");
|
|
164
|
+
const [webmail, setWebmail] = useState2(null);
|
|
164
165
|
const [twoFactorSessionId, setTwoFactorSessionId] = useState2(null);
|
|
165
166
|
const [shouldPrompt2FA, setShouldPrompt2FA] = useState2(false);
|
|
166
167
|
const [twoFactorCode, setTwoFactorCode] = useState2("");
|
|
@@ -200,6 +201,7 @@ var useAuthFormState = /* @__PURE__ */ __name((initialIdentifier = "") => {
|
|
|
200
201
|
rateLimitSeconds,
|
|
201
202
|
isRateLimited: rateLimitSeconds > 0,
|
|
202
203
|
rateLimitLabel: formatCountdown(rateLimitSeconds),
|
|
204
|
+
webmail,
|
|
203
205
|
// Handlers
|
|
204
206
|
setIdentifier,
|
|
205
207
|
setOtp,
|
|
@@ -212,7 +214,8 @@ var useAuthFormState = /* @__PURE__ */ __name((initialIdentifier = "") => {
|
|
|
212
214
|
setShouldPrompt2FA,
|
|
213
215
|
setTwoFactorCode,
|
|
214
216
|
setUseBackupCode,
|
|
215
|
-
startRateLimitCountdown
|
|
217
|
+
startRateLimitCountdown,
|
|
218
|
+
setWebmail
|
|
216
219
|
};
|
|
217
220
|
}, "useAuthFormState");
|
|
218
221
|
|
|
@@ -598,6 +601,17 @@ var auth = {
|
|
|
598
601
|
*/
|
|
599
602
|
setRefreshHandler(fn) {
|
|
600
603
|
_refreshHandler = fn;
|
|
604
|
+
},
|
|
605
|
+
/**
|
|
606
|
+
* Proactively run the registered refresh handler right now, reusing the
|
|
607
|
+
* SAME single-flight promise as the 401-recovery interceptor. Callers
|
|
608
|
+
* (e.g. an expiry timer / focus / reconnect) get token rotation,
|
|
609
|
+
* de-duplication and rotated-token persistence for free — they must NOT
|
|
610
|
+
* re-implement any of it. Returns the fresh access token, or null if
|
|
611
|
+
* there is no handler / no refresh token / the refresh failed.
|
|
612
|
+
*/
|
|
613
|
+
refreshNow() {
|
|
614
|
+
return tryRefresh();
|
|
601
615
|
}
|
|
602
616
|
};
|
|
603
617
|
async function tryRefresh() {
|
|
@@ -2321,6 +2335,14 @@ var API = class {
|
|
|
2321
2335
|
setRefreshHandler(fn) {
|
|
2322
2336
|
auth.setRefreshHandler(fn);
|
|
2323
2337
|
}
|
|
2338
|
+
/**
|
|
2339
|
+
* Proactively refresh now via the registered handler, sharing the single
|
|
2340
|
+
* 401-recovery flight (rotation + dedup + rotated-token persistence).
|
|
2341
|
+
* See `auth.refreshNow`.
|
|
2342
|
+
*/
|
|
2343
|
+
refreshNow() {
|
|
2344
|
+
return auth.refreshNow();
|
|
2345
|
+
}
|
|
2324
2346
|
};
|
|
2325
2347
|
|
|
2326
2348
|
// src/_api/generated/_cfg_centrifugo/api.ts
|
|
@@ -2385,6 +2407,14 @@ var API2 = class {
|
|
|
2385
2407
|
setRefreshHandler(fn) {
|
|
2386
2408
|
auth.setRefreshHandler(fn);
|
|
2387
2409
|
}
|
|
2410
|
+
/**
|
|
2411
|
+
* Proactively refresh now via the registered handler, sharing the single
|
|
2412
|
+
* 401-recovery flight (rotation + dedup + rotated-token persistence).
|
|
2413
|
+
* See `auth.refreshNow`.
|
|
2414
|
+
*/
|
|
2415
|
+
refreshNow() {
|
|
2416
|
+
return auth.refreshNow();
|
|
2417
|
+
}
|
|
2388
2418
|
};
|
|
2389
2419
|
|
|
2390
2420
|
// src/_api/generated/_cfg_totp/api.ts
|
|
@@ -2452,6 +2482,14 @@ var API3 = class {
|
|
|
2452
2482
|
setRefreshHandler(fn) {
|
|
2453
2483
|
auth.setRefreshHandler(fn);
|
|
2454
2484
|
}
|
|
2485
|
+
/**
|
|
2486
|
+
* Proactively refresh now via the registered handler, sharing the single
|
|
2487
|
+
* 401-recovery flight (rotation + dedup + rotated-token persistence).
|
|
2488
|
+
* See `auth.refreshNow`.
|
|
2489
|
+
*/
|
|
2490
|
+
refreshNow() {
|
|
2491
|
+
return auth.refreshNow();
|
|
2492
|
+
}
|
|
2455
2493
|
};
|
|
2456
2494
|
|
|
2457
2495
|
// src/_api/generated/index.ts
|
|
@@ -2672,7 +2710,8 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2672
2710
|
setShouldPrompt2FA,
|
|
2673
2711
|
setTwoFactorCode,
|
|
2674
2712
|
setUseBackupCode,
|
|
2675
|
-
startRateLimitCountdown
|
|
2713
|
+
startRateLimitCountdown,
|
|
2714
|
+
setWebmail
|
|
2676
2715
|
} = formState;
|
|
2677
2716
|
const twoFactor = useTwoFactor({
|
|
2678
2717
|
onSuccess: /* @__PURE__ */ __name(() => {
|
|
@@ -2724,6 +2763,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2724
2763
|
const result = await requestOTP(identifier, sourceUrl);
|
|
2725
2764
|
if (result.success) {
|
|
2726
2765
|
saveIdentifierToStorage(identifier);
|
|
2766
|
+
setWebmail(result.webmail ?? null);
|
|
2727
2767
|
setStep("otp");
|
|
2728
2768
|
onIdentifierSuccess?.(identifier);
|
|
2729
2769
|
} else {
|
|
@@ -2753,6 +2793,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2753
2793
|
setIsLoading,
|
|
2754
2794
|
setStep,
|
|
2755
2795
|
clearError,
|
|
2796
|
+
setWebmail,
|
|
2756
2797
|
startRateLimitCountdown,
|
|
2757
2798
|
onIdentifierSuccess,
|
|
2758
2799
|
onError,
|
|
@@ -2808,6 +2849,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2808
2849
|
const result = await requestOTP(identifier, sourceUrl);
|
|
2809
2850
|
if (result.success) {
|
|
2810
2851
|
saveIdentifierToStorage(identifier);
|
|
2852
|
+
setWebmail(result.webmail ?? null);
|
|
2811
2853
|
setOtp("");
|
|
2812
2854
|
} else {
|
|
2813
2855
|
if (result.retryAfter) {
|
|
@@ -2825,7 +2867,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2825
2867
|
} finally {
|
|
2826
2868
|
setIsLoading(false);
|
|
2827
2869
|
}
|
|
2828
|
-
}, [identifier, requestOTP, saveIdentifierToStorage, setOtp, setError, setIsLoading, clearError, startRateLimitCountdown, onError, sourceUrl]);
|
|
2870
|
+
}, [identifier, requestOTP, saveIdentifierToStorage, setOtp, setError, setIsLoading, clearError, startRateLimitCountdown, setWebmail, onError, sourceUrl]);
|
|
2829
2871
|
const handleBackToIdentifier = useCallback5(() => {
|
|
2830
2872
|
setStep("identifier");
|
|
2831
2873
|
clearError();
|
|
@@ -3727,51 +3769,91 @@ function getCacheMetadata() {
|
|
|
3727
3769
|
__name(getCacheMetadata, "getCacheMetadata");
|
|
3728
3770
|
|
|
3729
3771
|
// src/auth/hooks/useTokenRefresh.ts
|
|
3730
|
-
import { useCallback as useCallback9, useEffect as useEffect7
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3772
|
+
import { useCallback as useCallback9, useEffect as useEffect7 } from "react";
|
|
3773
|
+
|
|
3774
|
+
// src/auth/refreshHandler.ts
|
|
3775
|
+
var _registered = false;
|
|
3776
|
+
function ensureRefreshHandler() {
|
|
3777
|
+
if (_registered) return;
|
|
3778
|
+
_registered = true;
|
|
3779
|
+
CfgAccountsApi.setRefreshHandler(async (refresh) => {
|
|
3780
|
+
const result = await CfgAccountsAuth.cfgAccountsTokenRefreshCreate({
|
|
3781
|
+
body: { refresh },
|
|
3782
|
+
throwOnError: true
|
|
3783
|
+
});
|
|
3784
|
+
const access = result.data?.access;
|
|
3785
|
+
if (!access) {
|
|
3786
|
+
authLogger.error("Refresh response missing access token");
|
|
3787
|
+
return null;
|
|
3788
|
+
}
|
|
3789
|
+
return { access, refresh: result.data?.refresh ?? refresh };
|
|
3790
|
+
});
|
|
3791
|
+
authLogger.debug("Canonical refresh handler registered");
|
|
3792
|
+
}
|
|
3793
|
+
__name(ensureRefreshHandler, "ensureRefreshHandler");
|
|
3794
|
+
function triggerRefresh() {
|
|
3795
|
+
ensureRefreshHandler();
|
|
3796
|
+
const maybe = CfgAccountsApi;
|
|
3797
|
+
if (typeof maybe.refreshNow === "function") {
|
|
3798
|
+
return maybe.refreshNow();
|
|
3799
|
+
}
|
|
3800
|
+
authLogger.warn("api.refreshNow() unavailable \u2014 run `make generate` to regenerate the client");
|
|
3801
|
+
return Promise.resolve(null);
|
|
3802
|
+
}
|
|
3803
|
+
__name(triggerRefresh, "triggerRefresh");
|
|
3804
|
+
|
|
3805
|
+
// src/auth/utils/jwt.ts
|
|
3806
|
+
function decodeSegment(segment) {
|
|
3734
3807
|
try {
|
|
3735
|
-
const
|
|
3736
|
-
|
|
3808
|
+
const base64 = segment.replace(/-/g, "+").replace(/_/g, "/");
|
|
3809
|
+
if (typeof atob !== "function") return null;
|
|
3810
|
+
const json = atob(base64);
|
|
3811
|
+
return JSON.parse(json);
|
|
3737
3812
|
} catch {
|
|
3738
3813
|
return null;
|
|
3739
3814
|
}
|
|
3740
3815
|
}
|
|
3816
|
+
__name(decodeSegment, "decodeSegment");
|
|
3817
|
+
function getTokenExpiry(token) {
|
|
3818
|
+
if (!token || typeof token !== "string") return null;
|
|
3819
|
+
const parts = token.split(".");
|
|
3820
|
+
if (parts.length !== 3) return null;
|
|
3821
|
+
const payload = decodeSegment(parts[1]);
|
|
3822
|
+
if (!payload || typeof payload !== "object") return null;
|
|
3823
|
+
const exp = payload.exp;
|
|
3824
|
+
if (typeof exp !== "number" || !Number.isFinite(exp)) return null;
|
|
3825
|
+
return exp * 1e3;
|
|
3826
|
+
}
|
|
3741
3827
|
__name(getTokenExpiry, "getTokenExpiry");
|
|
3742
|
-
function
|
|
3828
|
+
function isTokenExpired(token, skewMs = 0, now = Date.now()) {
|
|
3829
|
+
const expiry = getTokenExpiry(token);
|
|
3830
|
+
if (expiry === null) return true;
|
|
3831
|
+
return expiry - skewMs <= now;
|
|
3832
|
+
}
|
|
3833
|
+
__name(isTokenExpired, "isTokenExpired");
|
|
3834
|
+
function isTokenExpiringSoon(token, thresholdMs, now = Date.now()) {
|
|
3743
3835
|
const expiry = getTokenExpiry(token);
|
|
3744
|
-
if (
|
|
3745
|
-
|
|
3746
|
-
return timeUntilExpiry < thresholdMs;
|
|
3836
|
+
if (expiry === null) return false;
|
|
3837
|
+
return expiry - now < thresholdMs;
|
|
3747
3838
|
}
|
|
3748
3839
|
__name(isTokenExpiringSoon, "isTokenExpiringSoon");
|
|
3840
|
+
|
|
3841
|
+
// src/auth/hooks/useTokenRefresh.ts
|
|
3842
|
+
var TOKEN_REFRESH_THRESHOLD_MS = 10 * 60 * 1e3;
|
|
3843
|
+
var CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3749
3844
|
function useTokenRefresh(options = {}) {
|
|
3750
3845
|
const { enabled = true, onRefresh, onRefreshError } = options;
|
|
3751
|
-
const isRefreshingRef = useRef5(false);
|
|
3752
3846
|
const refreshToken = useCallback9(async () => {
|
|
3753
|
-
if (
|
|
3754
|
-
authLogger.debug("Token refresh already in progress");
|
|
3755
|
-
return false;
|
|
3756
|
-
}
|
|
3757
|
-
const refreshTokenValue = CfgAccountsApi.getRefreshToken();
|
|
3758
|
-
if (!refreshTokenValue) {
|
|
3847
|
+
if (!CfgAccountsApi.getRefreshToken()) {
|
|
3759
3848
|
authLogger.warn("No refresh token available");
|
|
3760
3849
|
return false;
|
|
3761
3850
|
}
|
|
3762
|
-
isRefreshingRef.current = true;
|
|
3763
3851
|
authLogger.info("Refreshing token...");
|
|
3764
3852
|
try {
|
|
3765
|
-
const
|
|
3766
|
-
body: { refresh: refreshTokenValue },
|
|
3767
|
-
throwOnError: true
|
|
3768
|
-
});
|
|
3769
|
-
const newAccessToken = result.data.access;
|
|
3853
|
+
const newAccessToken = await triggerRefresh();
|
|
3770
3854
|
if (!newAccessToken) {
|
|
3771
|
-
throw new Error("
|
|
3855
|
+
throw new Error("Token refresh failed");
|
|
3772
3856
|
}
|
|
3773
|
-
CfgAccountsApi.setToken(newAccessToken);
|
|
3774
|
-
CfgAccountsApi.setRefreshToken(refreshTokenValue);
|
|
3775
3857
|
authLogger.info("Token refreshed successfully");
|
|
3776
3858
|
onRefresh?.(newAccessToken);
|
|
3777
3859
|
return true;
|
|
@@ -3779,8 +3861,6 @@ function useTokenRefresh(options = {}) {
|
|
|
3779
3861
|
authLogger.error("Token refresh error:", error);
|
|
3780
3862
|
onRefreshError?.(error instanceof Error ? error : new Error(String(error)));
|
|
3781
3863
|
return false;
|
|
3782
|
-
} finally {
|
|
3783
|
-
isRefreshingRef.current = false;
|
|
3784
3864
|
}
|
|
3785
3865
|
}, [onRefresh, onRefreshError]);
|
|
3786
3866
|
const checkAndRefresh = useCallback9(async () => {
|
|
@@ -3867,7 +3947,7 @@ import {
|
|
|
3867
3947
|
useContext,
|
|
3868
3948
|
useEffect as useEffect8,
|
|
3869
3949
|
useMemo as useMemo2,
|
|
3870
|
-
useRef as
|
|
3950
|
+
useRef as useRef5,
|
|
3871
3951
|
useState as useState11
|
|
3872
3952
|
} from "react";
|
|
3873
3953
|
|
|
@@ -3971,8 +4051,8 @@ var OAuthTokenResponseSchema = z10.object({
|
|
|
3971
4051
|
access: z10.string().nullable().optional(),
|
|
3972
4052
|
refresh: z10.string().nullable().optional(),
|
|
3973
4053
|
user: z10.object({}).passthrough().nullable().optional(),
|
|
3974
|
-
is_new_user: z10.boolean(),
|
|
3975
|
-
is_new_connection: z10.boolean(),
|
|
4054
|
+
is_new_user: z10.boolean().default(false).optional(),
|
|
4055
|
+
is_new_connection: z10.boolean().default(false).optional(),
|
|
3976
4056
|
should_prompt_2fa: z10.boolean().optional()
|
|
3977
4057
|
});
|
|
3978
4058
|
|
|
@@ -3989,9 +4069,27 @@ var OAuthProvidersResponseSchema = z11.object({
|
|
|
3989
4069
|
import useSWRMutation7 from "swr/mutation";
|
|
3990
4070
|
|
|
3991
4071
|
// src/_api/generated/_cfg_accounts/schemas/OTPRequestResponse.ts
|
|
4072
|
+
import { z as z14 } from "zod";
|
|
4073
|
+
|
|
4074
|
+
// src/_api/generated/_cfg_accounts/schemas/WebmailLink.ts
|
|
4075
|
+
import { z as z13 } from "zod";
|
|
4076
|
+
|
|
4077
|
+
// src/_api/generated/_cfg_accounts/schemas/WebmailLinkProviderEnum.ts
|
|
3992
4078
|
import { z as z12 } from "zod";
|
|
3993
|
-
var
|
|
3994
|
-
|
|
4079
|
+
var WebmailLinkProviderEnumSchema = z12.enum(["gmail", "outlook", "yahoo", "icloud", "proton", "zoho", "aol", "fastmail", "gmx", "mailcom", "mail_ru", "yandex", "rambler", "qq", "netease", "sina", "aliyun", "naver", "daum", "web_de", "tonline", "seznam", "wp_pl", "o2_pl", "interia", "libero", "virgilio", "orange", "laposte", "free_fr", "sfr"]);
|
|
4080
|
+
|
|
4081
|
+
// src/_api/generated/_cfg_accounts/schemas/WebmailLink.ts
|
|
4082
|
+
var WebmailLinkSchema = z13.object({
|
|
4083
|
+
provider: WebmailLinkProviderEnumSchema,
|
|
4084
|
+
provider_name: z13.string(),
|
|
4085
|
+
url: z13.string(),
|
|
4086
|
+
is_search: z13.boolean()
|
|
4087
|
+
});
|
|
4088
|
+
|
|
4089
|
+
// src/_api/generated/_cfg_accounts/schemas/OTPRequestResponse.ts
|
|
4090
|
+
var OTPRequestResponseSchema = z14.object({
|
|
4091
|
+
message: z14.string(),
|
|
4092
|
+
webmail: WebmailLinkSchema.nullable().optional()
|
|
3995
4093
|
});
|
|
3996
4094
|
|
|
3997
4095
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOtpRequestCreate.ts
|
|
@@ -4045,52 +4143,52 @@ __name(useCfgAccountsOtpRequestCreate, "useCfgAccountsOtpRequestCreate");
|
|
|
4045
4143
|
import useSWRMutation8 from "swr/mutation";
|
|
4046
4144
|
|
|
4047
4145
|
// src/_api/generated/_cfg_accounts/schemas/OTPVerifyResponse.ts
|
|
4048
|
-
import { z as
|
|
4146
|
+
import { z as z17 } from "zod";
|
|
4049
4147
|
|
|
4050
4148
|
// src/_api/generated/_cfg_accounts/schemas/User.ts
|
|
4051
|
-
import { z as
|
|
4149
|
+
import { z as z16 } from "zod";
|
|
4052
4150
|
|
|
4053
4151
|
// src/_api/generated/_cfg_accounts/schemas/CentrifugoToken.ts
|
|
4054
|
-
import { z as
|
|
4055
|
-
var CentrifugoTokenSchema =
|
|
4056
|
-
token:
|
|
4057
|
-
centrifugo_url:
|
|
4058
|
-
expires_at:
|
|
4059
|
-
channels:
|
|
4152
|
+
import { z as z15 } from "zod";
|
|
4153
|
+
var CentrifugoTokenSchema = z15.object({
|
|
4154
|
+
token: z15.string(),
|
|
4155
|
+
centrifugo_url: z15.string(),
|
|
4156
|
+
expires_at: z15.string().datetime({ offset: true }),
|
|
4157
|
+
channels: z15.array(z15.string())
|
|
4060
4158
|
});
|
|
4061
4159
|
|
|
4062
4160
|
// src/_api/generated/_cfg_accounts/schemas/User.ts
|
|
4063
|
-
var UserSchema =
|
|
4064
|
-
id:
|
|
4065
|
-
email:
|
|
4066
|
-
first_name:
|
|
4067
|
-
last_name:
|
|
4068
|
-
full_name:
|
|
4069
|
-
initials:
|
|
4070
|
-
display_username:
|
|
4071
|
-
company:
|
|
4072
|
-
phone:
|
|
4073
|
-
position:
|
|
4074
|
-
language:
|
|
4075
|
-
timezone:
|
|
4076
|
-
avatar:
|
|
4077
|
-
is_staff:
|
|
4078
|
-
is_superuser:
|
|
4079
|
-
date_joined:
|
|
4080
|
-
last_login:
|
|
4081
|
-
unanswered_messages_count:
|
|
4161
|
+
var UserSchema = z16.object({
|
|
4162
|
+
id: z16.number().int(),
|
|
4163
|
+
email: z16.email(),
|
|
4164
|
+
first_name: z16.string().max(50).nullable().optional(),
|
|
4165
|
+
last_name: z16.string().max(50).nullable().optional(),
|
|
4166
|
+
full_name: z16.string(),
|
|
4167
|
+
initials: z16.string(),
|
|
4168
|
+
display_username: z16.string(),
|
|
4169
|
+
company: z16.string().max(100).nullable().optional(),
|
|
4170
|
+
phone: z16.string().max(20).nullable().optional(),
|
|
4171
|
+
position: z16.string().max(100).nullable().optional(),
|
|
4172
|
+
language: z16.string().max(10).nullable().optional(),
|
|
4173
|
+
timezone: z16.string().max(64).nullable().optional(),
|
|
4174
|
+
avatar: z16.string().nullable(),
|
|
4175
|
+
is_staff: z16.boolean(),
|
|
4176
|
+
is_superuser: z16.boolean(),
|
|
4177
|
+
date_joined: z16.string().datetime({ offset: true }),
|
|
4178
|
+
last_login: z16.string().datetime({ offset: true }).nullable(),
|
|
4179
|
+
unanswered_messages_count: z16.number().int().default(0),
|
|
4082
4180
|
centrifugo: CentrifugoTokenSchema.nullable(),
|
|
4083
|
-
api_key:
|
|
4181
|
+
api_key: z16.string().nullable()
|
|
4084
4182
|
});
|
|
4085
4183
|
|
|
4086
4184
|
// src/_api/generated/_cfg_accounts/schemas/OTPVerifyResponse.ts
|
|
4087
|
-
var OTPVerifyResponseSchema =
|
|
4088
|
-
requires_2fa:
|
|
4089
|
-
session_id:
|
|
4090
|
-
refresh:
|
|
4091
|
-
access:
|
|
4185
|
+
var OTPVerifyResponseSchema = z17.object({
|
|
4186
|
+
requires_2fa: z17.boolean().default(false).optional(),
|
|
4187
|
+
session_id: z17.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).nullable().optional(),
|
|
4188
|
+
refresh: z17.string().nullable().optional(),
|
|
4189
|
+
access: z17.string().nullable().optional(),
|
|
4092
4190
|
user: UserSchema.nullable().optional(),
|
|
4093
|
-
should_prompt_2fa:
|
|
4191
|
+
should_prompt_2fa: z17.boolean().optional()
|
|
4094
4192
|
});
|
|
4095
4193
|
|
|
4096
4194
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOtpVerifyCreate.ts
|
|
@@ -4192,10 +4290,10 @@ __name(useCfgAccountsProfileAvatarCreate, "useCfgAccountsProfileAvatarCreate");
|
|
|
4192
4290
|
import useSWRMutation10 from "swr/mutation";
|
|
4193
4291
|
|
|
4194
4292
|
// src/_api/generated/_cfg_accounts/schemas/AccountDeleteResponse.ts
|
|
4195
|
-
import { z as
|
|
4196
|
-
var AccountDeleteResponseSchema =
|
|
4197
|
-
success:
|
|
4198
|
-
message:
|
|
4293
|
+
import { z as z18 } from "zod";
|
|
4294
|
+
var AccountDeleteResponseSchema = z18.object({
|
|
4295
|
+
success: z18.boolean(),
|
|
4296
|
+
message: z18.string()
|
|
4199
4297
|
});
|
|
4200
4298
|
|
|
4201
4299
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfilePartialPartialUpdate.ts
|
|
@@ -4307,10 +4405,10 @@ __name(useCfgAccountsProfileUpdateUpdate, "useCfgAccountsProfileUpdateUpdate");
|
|
|
4307
4405
|
import useSWRMutation15 from "swr/mutation";
|
|
4308
4406
|
|
|
4309
4407
|
// src/_api/generated/_cfg_accounts/schemas/TokenRefresh.ts
|
|
4310
|
-
import { z as
|
|
4311
|
-
var TokenRefreshSchema =
|
|
4312
|
-
access:
|
|
4313
|
-
refresh:
|
|
4408
|
+
import { z as z19 } from "zod";
|
|
4409
|
+
var TokenRefreshSchema = z19.object({
|
|
4410
|
+
access: z19.string(),
|
|
4411
|
+
refresh: z19.string()
|
|
4314
4412
|
});
|
|
4315
4413
|
|
|
4316
4414
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsTokenRefreshCreate.ts
|
|
@@ -4361,98 +4459,98 @@ function useCfgAccountsTokenRefreshCreate(config) {
|
|
|
4361
4459
|
__name(useCfgAccountsTokenRefreshCreate, "useCfgAccountsTokenRefreshCreate");
|
|
4362
4460
|
|
|
4363
4461
|
// src/_api/generated/_cfg_accounts/schemas/APIKeyRequest.ts
|
|
4364
|
-
import { z as
|
|
4365
|
-
var APIKeyRequestSchema =
|
|
4366
|
-
key:
|
|
4367
|
-
reissued_at:
|
|
4368
|
-
created_at:
|
|
4462
|
+
import { z as z20 } from "zod";
|
|
4463
|
+
var APIKeyRequestSchema = z20.object({
|
|
4464
|
+
key: z20.string().min(1),
|
|
4465
|
+
reissued_at: z20.string().datetime({ offset: true }).nullable(),
|
|
4466
|
+
created_at: z20.string().datetime({ offset: true })
|
|
4369
4467
|
});
|
|
4370
4468
|
|
|
4371
4469
|
// src/_api/generated/_cfg_accounts/schemas/APIKeyTestRequest.ts
|
|
4372
|
-
import { z as
|
|
4373
|
-
var APIKeyTestRequestSchema =
|
|
4374
|
-
key:
|
|
4470
|
+
import { z as z21 } from "zod";
|
|
4471
|
+
var APIKeyTestRequestSchema = z21.object({
|
|
4472
|
+
key: z21.string().min(1)
|
|
4375
4473
|
});
|
|
4376
4474
|
|
|
4377
4475
|
// src/_api/generated/_cfg_accounts/schemas/CfgUserUpdateRequest.ts
|
|
4378
|
-
import { z as
|
|
4379
|
-
var CfgUserUpdateRequestSchema =
|
|
4380
|
-
first_name:
|
|
4381
|
-
last_name:
|
|
4382
|
-
company:
|
|
4383
|
-
phone:
|
|
4384
|
-
position:
|
|
4385
|
-
language:
|
|
4386
|
-
timezone:
|
|
4476
|
+
import { z as z22 } from "zod";
|
|
4477
|
+
var CfgUserUpdateRequestSchema = z22.object({
|
|
4478
|
+
first_name: z22.string().max(50).optional(),
|
|
4479
|
+
last_name: z22.string().max(50).optional(),
|
|
4480
|
+
company: z22.string().max(100).optional(),
|
|
4481
|
+
phone: z22.string().max(20).optional(),
|
|
4482
|
+
position: z22.string().max(100).optional(),
|
|
4483
|
+
language: z22.string().max(10).optional(),
|
|
4484
|
+
timezone: z22.string().max(64).optional()
|
|
4387
4485
|
});
|
|
4388
4486
|
|
|
4389
4487
|
// src/_api/generated/_cfg_accounts/schemas/OAuthAuthorizeRequestRequest.ts
|
|
4390
|
-
import { z as
|
|
4391
|
-
var OAuthAuthorizeRequestRequestSchema =
|
|
4392
|
-
redirect_uri:
|
|
4393
|
-
source_url:
|
|
4488
|
+
import { z as z23 } from "zod";
|
|
4489
|
+
var OAuthAuthorizeRequestRequestSchema = z23.object({
|
|
4490
|
+
redirect_uri: z23.string().optional(),
|
|
4491
|
+
source_url: z23.string().optional()
|
|
4394
4492
|
});
|
|
4395
4493
|
|
|
4396
4494
|
// src/_api/generated/_cfg_accounts/schemas/OAuthCallbackRequestRequest.ts
|
|
4397
|
-
import { z as
|
|
4398
|
-
var OAuthCallbackRequestRequestSchema =
|
|
4399
|
-
code:
|
|
4400
|
-
state:
|
|
4401
|
-
redirect_uri:
|
|
4495
|
+
import { z as z24 } from "zod";
|
|
4496
|
+
var OAuthCallbackRequestRequestSchema = z24.object({
|
|
4497
|
+
code: z24.string().min(10).max(500),
|
|
4498
|
+
state: z24.string().min(20).max(100),
|
|
4499
|
+
redirect_uri: z24.string().optional()
|
|
4402
4500
|
});
|
|
4403
4501
|
|
|
4404
4502
|
// src/_api/generated/_cfg_accounts/schemas/OAuthDisconnectRequestRequest.ts
|
|
4405
|
-
import { z as
|
|
4406
|
-
var OAuthDisconnectRequestRequestSchema =
|
|
4503
|
+
import { z as z25 } from "zod";
|
|
4504
|
+
var OAuthDisconnectRequestRequestSchema = z25.object({
|
|
4407
4505
|
provider: OAuthProviderEnumSchema
|
|
4408
4506
|
});
|
|
4409
4507
|
|
|
4410
4508
|
// src/_api/generated/_cfg_accounts/schemas/OAuthError.ts
|
|
4411
|
-
import { z as
|
|
4412
|
-
var OAuthErrorSchema =
|
|
4413
|
-
error:
|
|
4414
|
-
error_description:
|
|
4509
|
+
import { z as z26 } from "zod";
|
|
4510
|
+
var OAuthErrorSchema = z26.object({
|
|
4511
|
+
error: z26.string(),
|
|
4512
|
+
error_description: z26.string().optional()
|
|
4415
4513
|
});
|
|
4416
4514
|
|
|
4417
4515
|
// src/_api/generated/_cfg_accounts/schemas/OTPErrorResponse.ts
|
|
4418
|
-
import { z as
|
|
4419
|
-
var OTPErrorResponseSchema =
|
|
4420
|
-
error:
|
|
4421
|
-
error_code:
|
|
4422
|
-
retry_after:
|
|
4516
|
+
import { z as z27 } from "zod";
|
|
4517
|
+
var OTPErrorResponseSchema = z27.object({
|
|
4518
|
+
error: z27.string(),
|
|
4519
|
+
error_code: z27.string().nullable().optional(),
|
|
4520
|
+
retry_after: z27.number().int().nullable().optional()
|
|
4423
4521
|
});
|
|
4424
4522
|
|
|
4425
4523
|
// src/_api/generated/_cfg_accounts/schemas/OTPRequestRequest.ts
|
|
4426
|
-
import { z as
|
|
4427
|
-
var OTPRequestRequestSchema =
|
|
4428
|
-
identifier:
|
|
4429
|
-
source_url:
|
|
4524
|
+
import { z as z28 } from "zod";
|
|
4525
|
+
var OTPRequestRequestSchema = z28.object({
|
|
4526
|
+
identifier: z28.string().min(1),
|
|
4527
|
+
source_url: z28.string().optional()
|
|
4430
4528
|
});
|
|
4431
4529
|
|
|
4432
4530
|
// src/_api/generated/_cfg_accounts/schemas/OTPVerifyRequest.ts
|
|
4433
|
-
import { z as
|
|
4434
|
-
var OTPVerifyRequestSchema =
|
|
4435
|
-
identifier:
|
|
4436
|
-
otp:
|
|
4437
|
-
source_url:
|
|
4531
|
+
import { z as z29 } from "zod";
|
|
4532
|
+
var OTPVerifyRequestSchema = z29.object({
|
|
4533
|
+
identifier: z29.string().min(1),
|
|
4534
|
+
otp: z29.string().min(4).max(4),
|
|
4535
|
+
source_url: z29.string().optional()
|
|
4438
4536
|
});
|
|
4439
4537
|
|
|
4440
4538
|
// src/_api/generated/_cfg_accounts/schemas/PatchedCfgUserUpdateRequest.ts
|
|
4441
|
-
import { z as
|
|
4442
|
-
var PatchedCfgUserUpdateRequestSchema =
|
|
4443
|
-
first_name:
|
|
4444
|
-
last_name:
|
|
4445
|
-
company:
|
|
4446
|
-
phone:
|
|
4447
|
-
position:
|
|
4448
|
-
language:
|
|
4449
|
-
timezone:
|
|
4539
|
+
import { z as z30 } from "zod";
|
|
4540
|
+
var PatchedCfgUserUpdateRequestSchema = z30.object({
|
|
4541
|
+
first_name: z30.string().max(50).optional(),
|
|
4542
|
+
last_name: z30.string().max(50).optional(),
|
|
4543
|
+
company: z30.string().max(100).optional(),
|
|
4544
|
+
phone: z30.string().max(20).optional(),
|
|
4545
|
+
position: z30.string().max(100).optional(),
|
|
4546
|
+
language: z30.string().max(10).optional(),
|
|
4547
|
+
timezone: z30.string().max(64).optional()
|
|
4450
4548
|
});
|
|
4451
4549
|
|
|
4452
4550
|
// src/_api/generated/_cfg_accounts/schemas/TokenRefreshRequest.ts
|
|
4453
|
-
import { z as
|
|
4454
|
-
var TokenRefreshRequestSchema =
|
|
4455
|
-
refresh:
|
|
4551
|
+
import { z as z31 } from "zod";
|
|
4552
|
+
var TokenRefreshRequestSchema = z31.object({
|
|
4553
|
+
refresh: z31.string().min(1)
|
|
4456
4554
|
});
|
|
4457
4555
|
|
|
4458
4556
|
// src/auth/context/AccountsContext.tsx
|
|
@@ -4465,8 +4563,8 @@ function AccountsProvider({ children }) {
|
|
|
4465
4563
|
});
|
|
4466
4564
|
const [isLoadingProfile, setIsLoadingProfile] = useState11(false);
|
|
4467
4565
|
const [profileError, setProfileError] = useState11(null);
|
|
4468
|
-
const profileRef =
|
|
4469
|
-
const isLoadingRef =
|
|
4566
|
+
const profileRef = useRef5(profile);
|
|
4567
|
+
const isLoadingRef = useRef5(false);
|
|
4470
4568
|
useEffect8(() => {
|
|
4471
4569
|
profileRef.current = profile;
|
|
4472
4570
|
}, [profile]);
|
|
@@ -4606,8 +4704,15 @@ var hasValidTokens = /* @__PURE__ */ __name(() => {
|
|
|
4606
4704
|
if (typeof window === "undefined") return false;
|
|
4607
4705
|
return CfgAccountsApi.isAuthenticated();
|
|
4608
4706
|
}, "hasValidTokens");
|
|
4707
|
+
var isSessionDeadOnBootstrap = /* @__PURE__ */ __name((accessToken, refreshToken, now = Date.now()) => {
|
|
4708
|
+
const accessDead = isTokenExpired(accessToken, 0, now);
|
|
4709
|
+
if (!accessDead) return false;
|
|
4710
|
+
const refreshDead = isTokenExpired(refreshToken, 0, now);
|
|
4711
|
+
return refreshDead;
|
|
4712
|
+
}, "isSessionDeadOnBootstrap");
|
|
4609
4713
|
var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
4610
4714
|
const accounts = useAccountsContext();
|
|
4715
|
+
ensureRefreshHandler();
|
|
4611
4716
|
const redirectManager = useAuthRedirectManager({
|
|
4612
4717
|
fallbackUrl: config?.routes?.defaultCallback || defaultRoutes.defaultCallback,
|
|
4613
4718
|
clearOnUse: true
|
|
@@ -4620,23 +4725,17 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4620
4725
|
return true;
|
|
4621
4726
|
});
|
|
4622
4727
|
const [initialized, setInitialized] = useState12(false);
|
|
4728
|
+
const [authTick, setAuthTick] = useState12(0);
|
|
4729
|
+
const bumpAuthTick = useCallback12(() => setAuthTick((t) => t + 1), []);
|
|
4730
|
+
const onUnauthorizedRef = useRef6(false);
|
|
4623
4731
|
const router = useCfgRouter();
|
|
4624
4732
|
const pathname = usePathname3();
|
|
4625
4733
|
const queryParams = useQueryParams();
|
|
4626
4734
|
const [storedEmail, setStoredEmail, clearStoredEmail] = useLocalStorage(EMAIL_STORAGE_KEY, null);
|
|
4627
|
-
useTokenRefresh({
|
|
4628
|
-
enabled: true,
|
|
4629
|
-
onRefresh: /* @__PURE__ */ __name((newToken) => {
|
|
4630
|
-
authLogger.info("Token auto-refreshed successfully");
|
|
4631
|
-
}, "onRefresh"),
|
|
4632
|
-
onRefreshError: /* @__PURE__ */ __name((error) => {
|
|
4633
|
-
authLogger.warn("Token auto-refresh failed:", error.message);
|
|
4634
|
-
}, "onRefreshError")
|
|
4635
|
-
});
|
|
4636
4735
|
const user = accounts.profile;
|
|
4637
|
-
const userRef =
|
|
4638
|
-
const configRef =
|
|
4639
|
-
const isLoadingProfileRef =
|
|
4736
|
+
const userRef = useRef6(user);
|
|
4737
|
+
const configRef = useRef6(config);
|
|
4738
|
+
const isLoadingProfileRef = useRef6(false);
|
|
4640
4739
|
useEffect9(() => {
|
|
4641
4740
|
userRef.current = user;
|
|
4642
4741
|
}, [user]);
|
|
@@ -4649,7 +4748,23 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4649
4748
|
clearProfileCache();
|
|
4650
4749
|
setInitialized(true);
|
|
4651
4750
|
setIsLoading(false);
|
|
4652
|
-
|
|
4751
|
+
bumpAuthTick();
|
|
4752
|
+
}, [bumpAuthTick]);
|
|
4753
|
+
const handleProactiveRefreshError = useCallback12((error) => {
|
|
4754
|
+
authLogger.warn("Proactive token refresh failed \u2014 session is dead, redirecting to login:", error.message);
|
|
4755
|
+
if (onUnauthorizedRef.current) return;
|
|
4756
|
+
onUnauthorizedRef.current = true;
|
|
4757
|
+
clearAuthState("proactiveRefresh:failed");
|
|
4758
|
+
const authCallbackUrl = configRef.current?.routes?.defaultAuthCallback || defaultRoutes.defaultAuthCallback;
|
|
4759
|
+
router.hardReplace(authCallbackUrl);
|
|
4760
|
+
}, [clearAuthState, router]);
|
|
4761
|
+
useTokenRefresh({
|
|
4762
|
+
enabled: true,
|
|
4763
|
+
onRefresh: /* @__PURE__ */ __name(() => {
|
|
4764
|
+
authLogger.info("Token auto-refreshed successfully");
|
|
4765
|
+
}, "onRefresh"),
|
|
4766
|
+
onRefreshError: handleProactiveRefreshError
|
|
4767
|
+
});
|
|
4653
4768
|
const handleGlobalAuthError = useCallback12((error, context = "API Request") => {
|
|
4654
4769
|
const isAuthError = error?.status === 401 || error?.statusCode === 401 || error?.code === "token_not_valid" || error?.code === "authentication_failed";
|
|
4655
4770
|
if (isAuthError) {
|
|
@@ -4662,7 +4777,21 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4662
4777
|
}
|
|
4663
4778
|
return false;
|
|
4664
4779
|
}, [clearAuthState]);
|
|
4665
|
-
|
|
4780
|
+
useEffect9(() => {
|
|
4781
|
+
const handler = /* @__PURE__ */ __name(() => {
|
|
4782
|
+
if (onUnauthorizedRef.current) return;
|
|
4783
|
+
onUnauthorizedRef.current = true;
|
|
4784
|
+
authLogger.warn("Unrecoverable 401 (refresh failed) \u2014 clearing session and redirecting to login");
|
|
4785
|
+
clearAuthState("onUnauthorized:401");
|
|
4786
|
+
const authCallbackUrl = configRef.current?.routes?.defaultAuthCallback || defaultRoutes.defaultAuthCallback;
|
|
4787
|
+
router.hardReplace(authCallbackUrl);
|
|
4788
|
+
}, "handler");
|
|
4789
|
+
CfgAccountsApi.onUnauthorized(handler);
|
|
4790
|
+
return () => {
|
|
4791
|
+
CfgAccountsApi.onUnauthorized(null);
|
|
4792
|
+
};
|
|
4793
|
+
}, [clearAuthState, router]);
|
|
4794
|
+
const isAutoLoggingOutRef = useRef6(false);
|
|
4666
4795
|
const swrOnError = useCallback12((error) => {
|
|
4667
4796
|
const isAuthError = error?.status === 401 || error?.statusCode === 401 || error?.code === "token_not_valid" || error?.code === "authentication_failed";
|
|
4668
4797
|
if (isAuthError && !isAutoLoggingOutRef.current) {
|
|
@@ -4726,6 +4855,11 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4726
4855
|
authLogger.info("Token from API:", token ? `${token.substring(0, 20)}...` : "null");
|
|
4727
4856
|
authLogger.info("Refresh token from API:", refreshToken2 ? `${refreshToken2.substring(0, 20)}...` : "null");
|
|
4728
4857
|
authLogger.info("localStorage keys:", Object.keys(localStorage).filter((k) => k.includes("token") || k.includes("auth")));
|
|
4858
|
+
if (!isInIframe && isSessionDeadOnBootstrap(token, refreshToken2)) {
|
|
4859
|
+
authLogger.warn("Bootstrap: dead session in storage (access + refresh both unusable) \u2014 clearing and showing login");
|
|
4860
|
+
clearAuthState("initializeAuth:deadSession");
|
|
4861
|
+
return;
|
|
4862
|
+
}
|
|
4729
4863
|
const hasTokens = hasValidTokens();
|
|
4730
4864
|
authLogger.info("Has tokens:", hasTokens);
|
|
4731
4865
|
if (userRef.current) {
|
|
@@ -4826,7 +4960,8 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4826
4960
|
});
|
|
4827
4961
|
return {
|
|
4828
4962
|
success: true,
|
|
4829
|
-
message: result.message || `OTP code sent to your email address
|
|
4963
|
+
message: result.message || `OTP code sent to your email address`,
|
|
4964
|
+
webmail: result.webmail ?? null
|
|
4830
4965
|
};
|
|
4831
4966
|
} catch (error) {
|
|
4832
4967
|
authLogger.error("Request OTP error:", error);
|
|
@@ -4981,7 +5116,9 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4981
5116
|
() => ({
|
|
4982
5117
|
user,
|
|
4983
5118
|
isLoading,
|
|
4984
|
-
// Consider authenticated if we have valid tokens, even without user profile
|
|
5119
|
+
// Consider authenticated if we have valid tokens, even without user profile.
|
|
5120
|
+
// `authTick` (in deps) forces recompute after tokens are cleared/set, since
|
|
5121
|
+
// token state lives in storage, not React state.
|
|
4985
5122
|
isAuthenticated: CfgAccountsApi.isAuthenticated(),
|
|
4986
5123
|
isAdminUser,
|
|
4987
5124
|
loadCurrentProfile,
|
|
@@ -5007,6 +5144,8 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5007
5144
|
[
|
|
5008
5145
|
user,
|
|
5009
5146
|
isLoading,
|
|
5147
|
+
authTick,
|
|
5148
|
+
// recompute isAuthenticated when tokens are cleared/set
|
|
5010
5149
|
isAdminUser,
|
|
5011
5150
|
loadCurrentProfile,
|
|
5012
5151
|
checkAuthAndRedirect,
|