@bagelink/auth 1.7.72 → 1.7.74
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/README.md +283 -248
- package/dist/index.cjs +208 -62
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +208 -62
- package/dist/redirect.d.ts +21 -0
- package/dist/router.d.ts +22 -0
- package/dist/types/redirect.d.ts +70 -0
- package/dist/useAuth.d.ts +23 -0
- package/package.json +1 -1
- package/src/index.ts +10 -2
- package/src/redirect.ts +95 -0
- package/src/router.ts +86 -0
- package/src/types/redirect.ts +96 -0
- package/src/useAuth.ts +72 -1
package/dist/index.cjs
CHANGED
|
@@ -1391,70 +1391,56 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
1391
1391
|
};
|
|
1392
1392
|
}
|
|
1393
1393
|
});
|
|
1394
|
-
function
|
|
1395
|
-
const
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
const createRouteName = (name) => namePrefix ? `${namePrefix}${name}` : name;
|
|
1402
|
-
const routes = [
|
|
1403
|
-
{
|
|
1404
|
-
path: `${basePath}/login`,
|
|
1405
|
-
name: routeNames.login || createRouteName("Login"),
|
|
1406
|
-
component: () => Promise.resolve().then(() => require("./LoginPage-hv1wc54S.cjs")),
|
|
1407
|
-
meta: { requiresAuth: false }
|
|
1408
|
-
},
|
|
1409
|
-
{
|
|
1410
|
-
path: `${basePath}/signup`,
|
|
1411
|
-
name: routeNames.signup || createRouteName("Signup"),
|
|
1412
|
-
component: () => Promise.resolve().then(() => require("./SignupPage-m36w9PLJ.cjs")),
|
|
1413
|
-
meta: { requiresAuth: false }
|
|
1414
|
-
},
|
|
1415
|
-
{
|
|
1416
|
-
path: `${basePath}/forgot-password`,
|
|
1417
|
-
name: routeNames.forgotPassword || createRouteName("ForgotPassword"),
|
|
1418
|
-
component: () => Promise.resolve().then(() => require("./ForgotPasswordPage-BV9tyhHl.cjs")),
|
|
1419
|
-
meta: { requiresAuth: false }
|
|
1420
|
-
},
|
|
1421
|
-
{
|
|
1422
|
-
path: `${basePath}/reset-password`,
|
|
1423
|
-
name: routeNames.resetPassword || createRouteName("ResetPassword"),
|
|
1424
|
-
component: () => Promise.resolve().then(() => require("./ResetPasswordPage-COPrJmW8.cjs")),
|
|
1425
|
-
meta: { requiresAuth: false }
|
|
1426
|
-
},
|
|
1427
|
-
{
|
|
1428
|
-
path: `${basePath}/callback`,
|
|
1429
|
-
name: routeNames.callback || createRouteName("AuthCallback"),
|
|
1430
|
-
component: () => Promise.resolve().then(() => require("./Callback-BHqVaZZm.cjs")),
|
|
1431
|
-
meta: { requiresAuth: false }
|
|
1432
|
-
}
|
|
1433
|
-
];
|
|
1434
|
-
if (layout) {
|
|
1435
|
-
return [{
|
|
1436
|
-
path: basePath,
|
|
1437
|
-
component: layout,
|
|
1438
|
-
children: routes.map((route) => ({
|
|
1439
|
-
...route,
|
|
1440
|
-
path: route.path.replace(basePath, "")
|
|
1441
|
-
}))
|
|
1442
|
-
}];
|
|
1394
|
+
function getRedirectUrl(router, config) {
|
|
1395
|
+
const redirect2 = router.currentRoute.value.query[config.queryKey];
|
|
1396
|
+
return redirect2 || config.fallback;
|
|
1397
|
+
}
|
|
1398
|
+
function isValidRedirect(redirectUrl, allowedPaths) {
|
|
1399
|
+
if (!redirectUrl) {
|
|
1400
|
+
return false;
|
|
1443
1401
|
}
|
|
1444
|
-
|
|
1402
|
+
if (redirectUrl.startsWith("http://") || redirectUrl.startsWith("https://")) {
|
|
1403
|
+
return false;
|
|
1404
|
+
}
|
|
1405
|
+
if (redirectUrl.startsWith("//")) {
|
|
1406
|
+
return false;
|
|
1407
|
+
}
|
|
1408
|
+
if (redirectUrl.startsWith("javascript:") || redirectUrl.startsWith("data:")) {
|
|
1409
|
+
return false;
|
|
1410
|
+
}
|
|
1411
|
+
if (!redirectUrl.startsWith("/")) {
|
|
1412
|
+
return false;
|
|
1413
|
+
}
|
|
1414
|
+
if (allowedPaths && allowedPaths.length > 0) {
|
|
1415
|
+
return allowedPaths.some((pattern) => pattern.test(redirectUrl));
|
|
1416
|
+
}
|
|
1417
|
+
return true;
|
|
1445
1418
|
}
|
|
1446
|
-
function
|
|
1447
|
-
const
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
next();
|
|
1455
|
-
}
|
|
1456
|
-
};
|
|
1419
|
+
async function performRedirect(router, config) {
|
|
1420
|
+
const redirect2 = getRedirectUrl(router, config);
|
|
1421
|
+
if (redirect2 !== config.fallback && !isValidRedirect(redirect2, config.allowedPaths)) {
|
|
1422
|
+
console.warn("[Auth] Invalid redirect URL detected, using fallback:", redirect2);
|
|
1423
|
+
await router.push(config.fallback);
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1426
|
+
await router.push(redirect2);
|
|
1457
1427
|
}
|
|
1428
|
+
function buildLoginQuery(currentPath, config) {
|
|
1429
|
+
if (!config.preserveRedirect) {
|
|
1430
|
+
return {};
|
|
1431
|
+
}
|
|
1432
|
+
if (isValidRedirect(currentPath, config.allowedPaths)) {
|
|
1433
|
+
return { [config.queryKey]: currentPath };
|
|
1434
|
+
}
|
|
1435
|
+
return {};
|
|
1436
|
+
}
|
|
1437
|
+
const redirect = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1438
|
+
__proto__: null,
|
|
1439
|
+
buildLoginQuery,
|
|
1440
|
+
getRedirectUrl,
|
|
1441
|
+
isValidRedirect,
|
|
1442
|
+
performRedirect
|
|
1443
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1458
1444
|
let authApiRef = null;
|
|
1459
1445
|
function setAuthContext(authApi2) {
|
|
1460
1446
|
authApiRef = authApi2;
|
|
@@ -1902,9 +1888,36 @@ function accountToUser(account) {
|
|
|
1902
1888
|
lastLogin: account.last_login
|
|
1903
1889
|
};
|
|
1904
1890
|
}
|
|
1891
|
+
const DEFAULT_REDIRECT_CONFIG = {
|
|
1892
|
+
queryKey: "redirect",
|
|
1893
|
+
fallback: "/",
|
|
1894
|
+
noAuthRoutes: ["Login", "Signup", "ForgotPassword", "ResetPassword", "Callback"],
|
|
1895
|
+
authenticatedRedirect: "/",
|
|
1896
|
+
loginRoute: "Login",
|
|
1897
|
+
authMetaKey: "auth",
|
|
1898
|
+
autoRedirect: true,
|
|
1899
|
+
preserveRedirect: true
|
|
1900
|
+
};
|
|
1901
|
+
function normalizeRedirectConfig(config) {
|
|
1902
|
+
return {
|
|
1903
|
+
...DEFAULT_REDIRECT_CONFIG,
|
|
1904
|
+
...config
|
|
1905
|
+
};
|
|
1906
|
+
}
|
|
1905
1907
|
let authApi = null;
|
|
1906
1908
|
let eventEmitter = null;
|
|
1909
|
+
let redirectConfig = null;
|
|
1910
|
+
let autoRedirectRouter = null;
|
|
1907
1911
|
const accountInfo = vue.ref(null);
|
|
1912
|
+
function setAuthRouter(router) {
|
|
1913
|
+
autoRedirectRouter = router;
|
|
1914
|
+
}
|
|
1915
|
+
function getRedirectConfig() {
|
|
1916
|
+
if (!redirectConfig) {
|
|
1917
|
+
throw new Error("Redirect config not initialized. Did you call createAuth with redirect config?");
|
|
1918
|
+
}
|
|
1919
|
+
return redirectConfig;
|
|
1920
|
+
}
|
|
1908
1921
|
function createAuth(params) {
|
|
1909
1922
|
if (authApi === null) {
|
|
1910
1923
|
authApi = new AuthApi(params.baseURL);
|
|
@@ -1912,7 +1925,13 @@ function createAuth(params) {
|
|
|
1912
1925
|
if (eventEmitter === null) {
|
|
1913
1926
|
eventEmitter = new EventEmitter();
|
|
1914
1927
|
}
|
|
1915
|
-
|
|
1928
|
+
if (params.redirect) {
|
|
1929
|
+
redirectConfig = normalizeRedirectConfig(params.redirect);
|
|
1930
|
+
}
|
|
1931
|
+
if (redirectConfig == null ? void 0 : redirectConfig.autoRedirect) {
|
|
1932
|
+
setupAutoRedirect();
|
|
1933
|
+
}
|
|
1934
|
+
const authInstance = {
|
|
1916
1935
|
// Event listener methods
|
|
1917
1936
|
on(event, handler) {
|
|
1918
1937
|
if (eventEmitter) {
|
|
@@ -1933,6 +1952,22 @@ function createAuth(params) {
|
|
|
1933
1952
|
app.config.globalProperties.$auth = useAuth();
|
|
1934
1953
|
}
|
|
1935
1954
|
};
|
|
1955
|
+
return authInstance;
|
|
1956
|
+
}
|
|
1957
|
+
function setupAutoRedirect() {
|
|
1958
|
+
if (!eventEmitter || !redirectConfig) return;
|
|
1959
|
+
eventEmitter.on(AuthState.LOGIN, async () => {
|
|
1960
|
+
if (!autoRedirectRouter) {
|
|
1961
|
+
console.warn("[Auth] Auto-redirect enabled but router not set. Call setAuthRouter(router) in your app setup.");
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1964
|
+
const { performRedirect: performRedirect2 } = await Promise.resolve().then(() => redirect);
|
|
1965
|
+
try {
|
|
1966
|
+
await performRedirect2(autoRedirectRouter, redirectConfig);
|
|
1967
|
+
} catch (error) {
|
|
1968
|
+
console.error("[Auth] Auto-redirect error:", error);
|
|
1969
|
+
}
|
|
1970
|
+
});
|
|
1936
1971
|
}
|
|
1937
1972
|
function useAuth() {
|
|
1938
1973
|
if (authApi === null) {
|
|
@@ -2182,12 +2217,114 @@ function useAuth() {
|
|
|
2182
2217
|
const useAuth$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2183
2218
|
__proto__: null,
|
|
2184
2219
|
createAuth,
|
|
2220
|
+
getRedirectConfig,
|
|
2221
|
+
setAuthRouter,
|
|
2185
2222
|
useAuth
|
|
2186
2223
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2224
|
+
let authInitialized = false;
|
|
2225
|
+
function resetAuthState() {
|
|
2226
|
+
authInitialized = false;
|
|
2227
|
+
}
|
|
2228
|
+
function authGuard() {
|
|
2229
|
+
return async function guard(to, _from, next) {
|
|
2230
|
+
const auth = useAuth();
|
|
2231
|
+
const config = getRedirectConfig();
|
|
2232
|
+
const requiresAuth = to.meta[config.authMetaKey];
|
|
2233
|
+
const requiresNoAuth = config.noAuthRoutes.includes(to.name);
|
|
2234
|
+
try {
|
|
2235
|
+
if (!authInitialized) {
|
|
2236
|
+
await auth.checkAuth();
|
|
2237
|
+
authInitialized = true;
|
|
2238
|
+
}
|
|
2239
|
+
const isAuthenticated = !!auth.user.value;
|
|
2240
|
+
if (isAuthenticated && requiresNoAuth) {
|
|
2241
|
+
next(config.authenticatedRedirect);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
if (!isAuthenticated && requiresAuth) {
|
|
2245
|
+
const query = buildLoginQuery(to.fullPath, config);
|
|
2246
|
+
next({
|
|
2247
|
+
name: config.loginRoute,
|
|
2248
|
+
query
|
|
2249
|
+
});
|
|
2250
|
+
return;
|
|
2251
|
+
}
|
|
2252
|
+
next();
|
|
2253
|
+
} catch (error) {
|
|
2254
|
+
console.error("[Auth Guard] Error:", error);
|
|
2255
|
+
next();
|
|
2256
|
+
}
|
|
2257
|
+
};
|
|
2258
|
+
}
|
|
2259
|
+
function createAuthRoutes(config = {}) {
|
|
2260
|
+
const {
|
|
2261
|
+
basePath = "",
|
|
2262
|
+
namePrefix = "",
|
|
2263
|
+
routeNames = {},
|
|
2264
|
+
layout
|
|
2265
|
+
} = config;
|
|
2266
|
+
const createRouteName = (name) => namePrefix ? `${namePrefix}${name}` : name;
|
|
2267
|
+
const routes = [
|
|
2268
|
+
{
|
|
2269
|
+
path: `${basePath}/login`,
|
|
2270
|
+
name: routeNames.login || createRouteName("Login"),
|
|
2271
|
+
component: () => Promise.resolve().then(() => require("./LoginPage-hv1wc54S.cjs")),
|
|
2272
|
+
meta: { requiresAuth: false }
|
|
2273
|
+
},
|
|
2274
|
+
{
|
|
2275
|
+
path: `${basePath}/signup`,
|
|
2276
|
+
name: routeNames.signup || createRouteName("Signup"),
|
|
2277
|
+
component: () => Promise.resolve().then(() => require("./SignupPage-m36w9PLJ.cjs")),
|
|
2278
|
+
meta: { requiresAuth: false }
|
|
2279
|
+
},
|
|
2280
|
+
{
|
|
2281
|
+
path: `${basePath}/forgot-password`,
|
|
2282
|
+
name: routeNames.forgotPassword || createRouteName("ForgotPassword"),
|
|
2283
|
+
component: () => Promise.resolve().then(() => require("./ForgotPasswordPage-BV9tyhHl.cjs")),
|
|
2284
|
+
meta: { requiresAuth: false }
|
|
2285
|
+
},
|
|
2286
|
+
{
|
|
2287
|
+
path: `${basePath}/reset-password`,
|
|
2288
|
+
name: routeNames.resetPassword || createRouteName("ResetPassword"),
|
|
2289
|
+
component: () => Promise.resolve().then(() => require("./ResetPasswordPage-COPrJmW8.cjs")),
|
|
2290
|
+
meta: { requiresAuth: false }
|
|
2291
|
+
},
|
|
2292
|
+
{
|
|
2293
|
+
path: `${basePath}/callback`,
|
|
2294
|
+
name: routeNames.callback || createRouteName("AuthCallback"),
|
|
2295
|
+
component: () => Promise.resolve().then(() => require("./Callback-BHqVaZZm.cjs")),
|
|
2296
|
+
meta: { requiresAuth: false }
|
|
2297
|
+
}
|
|
2298
|
+
];
|
|
2299
|
+
if (layout) {
|
|
2300
|
+
return [{
|
|
2301
|
+
path: basePath,
|
|
2302
|
+
component: layout,
|
|
2303
|
+
children: routes.map((route) => ({
|
|
2304
|
+
...route,
|
|
2305
|
+
path: route.path.replace(basePath, "")
|
|
2306
|
+
}))
|
|
2307
|
+
}];
|
|
2308
|
+
}
|
|
2309
|
+
return routes;
|
|
2310
|
+
}
|
|
2311
|
+
function createAuthGuard(config = {}) {
|
|
2312
|
+
const { redirectTo = "/" } = config;
|
|
2313
|
+
return async (to, _from, next) => {
|
|
2314
|
+
const { useAuth: useAuth2 } = await Promise.resolve().then(() => useAuth$1);
|
|
2315
|
+
const { user } = useAuth2();
|
|
2316
|
+
if (to.meta.requiresAuth === false && user.value) {
|
|
2317
|
+
next(redirectTo);
|
|
2318
|
+
} else {
|
|
2319
|
+
next();
|
|
2320
|
+
}
|
|
2321
|
+
};
|
|
2322
|
+
}
|
|
2187
2323
|
exports.AuthApi = AuthApi;
|
|
2188
2324
|
exports.AuthState = AuthState;
|
|
2189
2325
|
exports.Callback = _sfc_main$4;
|
|
2190
2326
|
exports.DEFAULT_AGENT_ID = DEFAULT_AGENT_ID;
|
|
2327
|
+
exports.DEFAULT_REDIRECT_CONFIG = DEFAULT_REDIRECT_CONFIG;
|
|
2191
2328
|
exports.ForgotPasswordForm = _sfc_main$8;
|
|
2192
2329
|
exports.ForgotPasswordPage = _sfc_main$3;
|
|
2193
2330
|
exports.INTAKE_WORKFLOW_ID = INTAKE_WORKFLOW_ID;
|
|
@@ -2203,14 +2340,23 @@ exports.SignupForm = _sfc_main$5;
|
|
|
2203
2340
|
exports.SignupPage = _sfc_main;
|
|
2204
2341
|
exports.StateMismatchError = StateMismatchError;
|
|
2205
2342
|
exports.accountToUser = accountToUser;
|
|
2343
|
+
exports.authGuard = authGuard;
|
|
2344
|
+
exports.buildLoginQuery = buildLoginQuery;
|
|
2206
2345
|
exports.createAuth = createAuth;
|
|
2207
2346
|
exports.createAuthGuard = createAuthGuard;
|
|
2208
2347
|
exports.createAuthRoutes = createAuthRoutes;
|
|
2209
2348
|
exports.getAllSSOProviders = getAllSSOProviders;
|
|
2349
|
+
exports.getRedirectConfig = getRedirectConfig;
|
|
2350
|
+
exports.getRedirectUrl = getRedirectUrl;
|
|
2210
2351
|
exports.getSSOProvider = getSSOProvider;
|
|
2211
2352
|
exports.isSupportedProvider = isSupportedProvider;
|
|
2353
|
+
exports.isValidRedirect = isValidRedirect;
|
|
2354
|
+
exports.normalizeRedirectConfig = normalizeRedirectConfig;
|
|
2355
|
+
exports.performRedirect = performRedirect;
|
|
2212
2356
|
exports.providers = providers;
|
|
2357
|
+
exports.resetAuthState = resetAuthState;
|
|
2213
2358
|
exports.setAuthContext = setAuthContext;
|
|
2359
|
+
exports.setAuthRouter = setAuthRouter;
|
|
2214
2360
|
exports.sso = sso;
|
|
2215
2361
|
exports.ssoProvidersList = ssoProvidersList;
|
|
2216
2362
|
exports.useAuth = useAuth;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,11 @@ export { default as ForgotPasswordPage } from './pages/ForgotPasswordPage.vue';
|
|
|
9
9
|
export { default as LoginPage } from './pages/LoginPage.vue';
|
|
10
10
|
export { default as ResetPasswordPage } from './pages/ResetPasswordPage.vue';
|
|
11
11
|
export { default as SignupPage } from './pages/SignupPage.vue';
|
|
12
|
+
export * from './redirect';
|
|
13
|
+
export * from './router';
|
|
12
14
|
export * from './routes';
|
|
13
15
|
export * from './sso';
|
|
14
16
|
export * from './types';
|
|
15
17
|
export type { ForgotPasswordTexts, LoginTexts, ResetPasswordTexts, SignupTexts, } from './types/';
|
|
18
|
+
export * from './types/redirect';
|
|
16
19
|
export * from './useAuth';
|
package/dist/index.mjs
CHANGED
|
@@ -1389,70 +1389,56 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1389
1389
|
};
|
|
1390
1390
|
}
|
|
1391
1391
|
});
|
|
1392
|
-
function
|
|
1393
|
-
const
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
const createRouteName = (name) => namePrefix ? `${namePrefix}${name}` : name;
|
|
1400
|
-
const routes = [
|
|
1401
|
-
{
|
|
1402
|
-
path: `${basePath}/login`,
|
|
1403
|
-
name: routeNames.login || createRouteName("Login"),
|
|
1404
|
-
component: () => import("./LoginPage-klj1NV4J.js"),
|
|
1405
|
-
meta: { requiresAuth: false }
|
|
1406
|
-
},
|
|
1407
|
-
{
|
|
1408
|
-
path: `${basePath}/signup`,
|
|
1409
|
-
name: routeNames.signup || createRouteName("Signup"),
|
|
1410
|
-
component: () => import("./SignupPage-oUFYApYW.js"),
|
|
1411
|
-
meta: { requiresAuth: false }
|
|
1412
|
-
},
|
|
1413
|
-
{
|
|
1414
|
-
path: `${basePath}/forgot-password`,
|
|
1415
|
-
name: routeNames.forgotPassword || createRouteName("ForgotPassword"),
|
|
1416
|
-
component: () => import("./ForgotPasswordPage-DvttMGb0.js"),
|
|
1417
|
-
meta: { requiresAuth: false }
|
|
1418
|
-
},
|
|
1419
|
-
{
|
|
1420
|
-
path: `${basePath}/reset-password`,
|
|
1421
|
-
name: routeNames.resetPassword || createRouteName("ResetPassword"),
|
|
1422
|
-
component: () => import("./ResetPasswordPage-nvQ4uupb.js"),
|
|
1423
|
-
meta: { requiresAuth: false }
|
|
1424
|
-
},
|
|
1425
|
-
{
|
|
1426
|
-
path: `${basePath}/callback`,
|
|
1427
|
-
name: routeNames.callback || createRouteName("AuthCallback"),
|
|
1428
|
-
component: () => import("./Callback-C-XghN_z.js"),
|
|
1429
|
-
meta: { requiresAuth: false }
|
|
1430
|
-
}
|
|
1431
|
-
];
|
|
1432
|
-
if (layout) {
|
|
1433
|
-
return [{
|
|
1434
|
-
path: basePath,
|
|
1435
|
-
component: layout,
|
|
1436
|
-
children: routes.map((route) => ({
|
|
1437
|
-
...route,
|
|
1438
|
-
path: route.path.replace(basePath, "")
|
|
1439
|
-
}))
|
|
1440
|
-
}];
|
|
1392
|
+
function getRedirectUrl(router, config) {
|
|
1393
|
+
const redirect2 = router.currentRoute.value.query[config.queryKey];
|
|
1394
|
+
return redirect2 || config.fallback;
|
|
1395
|
+
}
|
|
1396
|
+
function isValidRedirect(redirectUrl, allowedPaths) {
|
|
1397
|
+
if (!redirectUrl) {
|
|
1398
|
+
return false;
|
|
1441
1399
|
}
|
|
1442
|
-
|
|
1400
|
+
if (redirectUrl.startsWith("http://") || redirectUrl.startsWith("https://")) {
|
|
1401
|
+
return false;
|
|
1402
|
+
}
|
|
1403
|
+
if (redirectUrl.startsWith("//")) {
|
|
1404
|
+
return false;
|
|
1405
|
+
}
|
|
1406
|
+
if (redirectUrl.startsWith("javascript:") || redirectUrl.startsWith("data:")) {
|
|
1407
|
+
return false;
|
|
1408
|
+
}
|
|
1409
|
+
if (!redirectUrl.startsWith("/")) {
|
|
1410
|
+
return false;
|
|
1411
|
+
}
|
|
1412
|
+
if (allowedPaths && allowedPaths.length > 0) {
|
|
1413
|
+
return allowedPaths.some((pattern) => pattern.test(redirectUrl));
|
|
1414
|
+
}
|
|
1415
|
+
return true;
|
|
1443
1416
|
}
|
|
1444
|
-
function
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
next();
|
|
1453
|
-
}
|
|
1454
|
-
};
|
|
1417
|
+
async function performRedirect(router, config) {
|
|
1418
|
+
const redirect2 = getRedirectUrl(router, config);
|
|
1419
|
+
if (redirect2 !== config.fallback && !isValidRedirect(redirect2, config.allowedPaths)) {
|
|
1420
|
+
console.warn("[Auth] Invalid redirect URL detected, using fallback:", redirect2);
|
|
1421
|
+
await router.push(config.fallback);
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
await router.push(redirect2);
|
|
1455
1425
|
}
|
|
1426
|
+
function buildLoginQuery(currentPath, config) {
|
|
1427
|
+
if (!config.preserveRedirect) {
|
|
1428
|
+
return {};
|
|
1429
|
+
}
|
|
1430
|
+
if (isValidRedirect(currentPath, config.allowedPaths)) {
|
|
1431
|
+
return { [config.queryKey]: currentPath };
|
|
1432
|
+
}
|
|
1433
|
+
return {};
|
|
1434
|
+
}
|
|
1435
|
+
const redirect = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1436
|
+
__proto__: null,
|
|
1437
|
+
buildLoginQuery,
|
|
1438
|
+
getRedirectUrl,
|
|
1439
|
+
isValidRedirect,
|
|
1440
|
+
performRedirect
|
|
1441
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1456
1442
|
let authApiRef = null;
|
|
1457
1443
|
function setAuthContext(authApi2) {
|
|
1458
1444
|
authApiRef = authApi2;
|
|
@@ -1900,9 +1886,36 @@ function accountToUser(account) {
|
|
|
1900
1886
|
lastLogin: account.last_login
|
|
1901
1887
|
};
|
|
1902
1888
|
}
|
|
1889
|
+
const DEFAULT_REDIRECT_CONFIG = {
|
|
1890
|
+
queryKey: "redirect",
|
|
1891
|
+
fallback: "/",
|
|
1892
|
+
noAuthRoutes: ["Login", "Signup", "ForgotPassword", "ResetPassword", "Callback"],
|
|
1893
|
+
authenticatedRedirect: "/",
|
|
1894
|
+
loginRoute: "Login",
|
|
1895
|
+
authMetaKey: "auth",
|
|
1896
|
+
autoRedirect: true,
|
|
1897
|
+
preserveRedirect: true
|
|
1898
|
+
};
|
|
1899
|
+
function normalizeRedirectConfig(config) {
|
|
1900
|
+
return {
|
|
1901
|
+
...DEFAULT_REDIRECT_CONFIG,
|
|
1902
|
+
...config
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1903
1905
|
let authApi = null;
|
|
1904
1906
|
let eventEmitter = null;
|
|
1907
|
+
let redirectConfig = null;
|
|
1908
|
+
let autoRedirectRouter = null;
|
|
1905
1909
|
const accountInfo = ref(null);
|
|
1910
|
+
function setAuthRouter(router) {
|
|
1911
|
+
autoRedirectRouter = router;
|
|
1912
|
+
}
|
|
1913
|
+
function getRedirectConfig() {
|
|
1914
|
+
if (!redirectConfig) {
|
|
1915
|
+
throw new Error("Redirect config not initialized. Did you call createAuth with redirect config?");
|
|
1916
|
+
}
|
|
1917
|
+
return redirectConfig;
|
|
1918
|
+
}
|
|
1906
1919
|
function createAuth(params) {
|
|
1907
1920
|
if (authApi === null) {
|
|
1908
1921
|
authApi = new AuthApi(params.baseURL);
|
|
@@ -1910,7 +1923,13 @@ function createAuth(params) {
|
|
|
1910
1923
|
if (eventEmitter === null) {
|
|
1911
1924
|
eventEmitter = new EventEmitter();
|
|
1912
1925
|
}
|
|
1913
|
-
|
|
1926
|
+
if (params.redirect) {
|
|
1927
|
+
redirectConfig = normalizeRedirectConfig(params.redirect);
|
|
1928
|
+
}
|
|
1929
|
+
if (redirectConfig == null ? void 0 : redirectConfig.autoRedirect) {
|
|
1930
|
+
setupAutoRedirect();
|
|
1931
|
+
}
|
|
1932
|
+
const authInstance = {
|
|
1914
1933
|
// Event listener methods
|
|
1915
1934
|
on(event, handler) {
|
|
1916
1935
|
if (eventEmitter) {
|
|
@@ -1931,6 +1950,22 @@ function createAuth(params) {
|
|
|
1931
1950
|
app.config.globalProperties.$auth = useAuth();
|
|
1932
1951
|
}
|
|
1933
1952
|
};
|
|
1953
|
+
return authInstance;
|
|
1954
|
+
}
|
|
1955
|
+
function setupAutoRedirect() {
|
|
1956
|
+
if (!eventEmitter || !redirectConfig) return;
|
|
1957
|
+
eventEmitter.on(AuthState.LOGIN, async () => {
|
|
1958
|
+
if (!autoRedirectRouter) {
|
|
1959
|
+
console.warn("[Auth] Auto-redirect enabled but router not set. Call setAuthRouter(router) in your app setup.");
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
const { performRedirect: performRedirect2 } = await Promise.resolve().then(() => redirect);
|
|
1963
|
+
try {
|
|
1964
|
+
await performRedirect2(autoRedirectRouter, redirectConfig);
|
|
1965
|
+
} catch (error) {
|
|
1966
|
+
console.error("[Auth] Auto-redirect error:", error);
|
|
1967
|
+
}
|
|
1968
|
+
});
|
|
1934
1969
|
}
|
|
1935
1970
|
function useAuth() {
|
|
1936
1971
|
if (authApi === null) {
|
|
@@ -2180,13 +2215,115 @@ function useAuth() {
|
|
|
2180
2215
|
const useAuth$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2181
2216
|
__proto__: null,
|
|
2182
2217
|
createAuth,
|
|
2218
|
+
getRedirectConfig,
|
|
2219
|
+
setAuthRouter,
|
|
2183
2220
|
useAuth
|
|
2184
2221
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2222
|
+
let authInitialized = false;
|
|
2223
|
+
function resetAuthState() {
|
|
2224
|
+
authInitialized = false;
|
|
2225
|
+
}
|
|
2226
|
+
function authGuard() {
|
|
2227
|
+
return async function guard(to, _from, next) {
|
|
2228
|
+
const auth = useAuth();
|
|
2229
|
+
const config = getRedirectConfig();
|
|
2230
|
+
const requiresAuth = to.meta[config.authMetaKey];
|
|
2231
|
+
const requiresNoAuth = config.noAuthRoutes.includes(to.name);
|
|
2232
|
+
try {
|
|
2233
|
+
if (!authInitialized) {
|
|
2234
|
+
await auth.checkAuth();
|
|
2235
|
+
authInitialized = true;
|
|
2236
|
+
}
|
|
2237
|
+
const isAuthenticated = !!auth.user.value;
|
|
2238
|
+
if (isAuthenticated && requiresNoAuth) {
|
|
2239
|
+
next(config.authenticatedRedirect);
|
|
2240
|
+
return;
|
|
2241
|
+
}
|
|
2242
|
+
if (!isAuthenticated && requiresAuth) {
|
|
2243
|
+
const query = buildLoginQuery(to.fullPath, config);
|
|
2244
|
+
next({
|
|
2245
|
+
name: config.loginRoute,
|
|
2246
|
+
query
|
|
2247
|
+
});
|
|
2248
|
+
return;
|
|
2249
|
+
}
|
|
2250
|
+
next();
|
|
2251
|
+
} catch (error) {
|
|
2252
|
+
console.error("[Auth Guard] Error:", error);
|
|
2253
|
+
next();
|
|
2254
|
+
}
|
|
2255
|
+
};
|
|
2256
|
+
}
|
|
2257
|
+
function createAuthRoutes(config = {}) {
|
|
2258
|
+
const {
|
|
2259
|
+
basePath = "",
|
|
2260
|
+
namePrefix = "",
|
|
2261
|
+
routeNames = {},
|
|
2262
|
+
layout
|
|
2263
|
+
} = config;
|
|
2264
|
+
const createRouteName = (name) => namePrefix ? `${namePrefix}${name}` : name;
|
|
2265
|
+
const routes = [
|
|
2266
|
+
{
|
|
2267
|
+
path: `${basePath}/login`,
|
|
2268
|
+
name: routeNames.login || createRouteName("Login"),
|
|
2269
|
+
component: () => import("./LoginPage-klj1NV4J.js"),
|
|
2270
|
+
meta: { requiresAuth: false }
|
|
2271
|
+
},
|
|
2272
|
+
{
|
|
2273
|
+
path: `${basePath}/signup`,
|
|
2274
|
+
name: routeNames.signup || createRouteName("Signup"),
|
|
2275
|
+
component: () => import("./SignupPage-oUFYApYW.js"),
|
|
2276
|
+
meta: { requiresAuth: false }
|
|
2277
|
+
},
|
|
2278
|
+
{
|
|
2279
|
+
path: `${basePath}/forgot-password`,
|
|
2280
|
+
name: routeNames.forgotPassword || createRouteName("ForgotPassword"),
|
|
2281
|
+
component: () => import("./ForgotPasswordPage-DvttMGb0.js"),
|
|
2282
|
+
meta: { requiresAuth: false }
|
|
2283
|
+
},
|
|
2284
|
+
{
|
|
2285
|
+
path: `${basePath}/reset-password`,
|
|
2286
|
+
name: routeNames.resetPassword || createRouteName("ResetPassword"),
|
|
2287
|
+
component: () => import("./ResetPasswordPage-nvQ4uupb.js"),
|
|
2288
|
+
meta: { requiresAuth: false }
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
path: `${basePath}/callback`,
|
|
2292
|
+
name: routeNames.callback || createRouteName("AuthCallback"),
|
|
2293
|
+
component: () => import("./Callback-C-XghN_z.js"),
|
|
2294
|
+
meta: { requiresAuth: false }
|
|
2295
|
+
}
|
|
2296
|
+
];
|
|
2297
|
+
if (layout) {
|
|
2298
|
+
return [{
|
|
2299
|
+
path: basePath,
|
|
2300
|
+
component: layout,
|
|
2301
|
+
children: routes.map((route) => ({
|
|
2302
|
+
...route,
|
|
2303
|
+
path: route.path.replace(basePath, "")
|
|
2304
|
+
}))
|
|
2305
|
+
}];
|
|
2306
|
+
}
|
|
2307
|
+
return routes;
|
|
2308
|
+
}
|
|
2309
|
+
function createAuthGuard(config = {}) {
|
|
2310
|
+
const { redirectTo = "/" } = config;
|
|
2311
|
+
return async (to, _from, next) => {
|
|
2312
|
+
const { useAuth: useAuth2 } = await Promise.resolve().then(() => useAuth$1);
|
|
2313
|
+
const { user } = useAuth2();
|
|
2314
|
+
if (to.meta.requiresAuth === false && user.value) {
|
|
2315
|
+
next(redirectTo);
|
|
2316
|
+
} else {
|
|
2317
|
+
next();
|
|
2318
|
+
}
|
|
2319
|
+
};
|
|
2320
|
+
}
|
|
2185
2321
|
export {
|
|
2186
2322
|
AuthApi,
|
|
2187
2323
|
AuthState,
|
|
2188
2324
|
_sfc_main$4 as Callback,
|
|
2189
2325
|
DEFAULT_AGENT_ID,
|
|
2326
|
+
DEFAULT_REDIRECT_CONFIG,
|
|
2190
2327
|
_sfc_main$8 as ForgotPasswordForm,
|
|
2191
2328
|
_sfc_main$3 as ForgotPasswordPage,
|
|
2192
2329
|
INTAKE_WORKFLOW_ID,
|
|
@@ -2202,14 +2339,23 @@ export {
|
|
|
2202
2339
|
_sfc_main as SignupPage,
|
|
2203
2340
|
StateMismatchError,
|
|
2204
2341
|
accountToUser,
|
|
2342
|
+
authGuard,
|
|
2343
|
+
buildLoginQuery,
|
|
2205
2344
|
createAuth,
|
|
2206
2345
|
createAuthGuard,
|
|
2207
2346
|
createAuthRoutes,
|
|
2208
2347
|
getAllSSOProviders,
|
|
2348
|
+
getRedirectConfig,
|
|
2349
|
+
getRedirectUrl,
|
|
2209
2350
|
getSSOProvider,
|
|
2210
2351
|
isSupportedProvider,
|
|
2352
|
+
isValidRedirect,
|
|
2353
|
+
normalizeRedirectConfig,
|
|
2354
|
+
performRedirect,
|
|
2211
2355
|
providers,
|
|
2356
|
+
resetAuthState,
|
|
2212
2357
|
setAuthContext,
|
|
2358
|
+
setAuthRouter,
|
|
2213
2359
|
sso,
|
|
2214
2360
|
ssoProvidersList,
|
|
2215
2361
|
useAuth
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Router } from 'vue-router';
|
|
2
|
+
import { NormalizedRedirectConfig } from './types/redirect';
|
|
3
|
+
/**
|
|
4
|
+
* Redirect utilities for handling post-authentication navigation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Get redirect URL from current route query params
|
|
8
|
+
*/
|
|
9
|
+
export declare function getRedirectUrl(router: Router, config: NormalizedRedirectConfig): string;
|
|
10
|
+
/**
|
|
11
|
+
* Validate redirect URL is safe (prevents open redirect attacks)
|
|
12
|
+
*/
|
|
13
|
+
export declare function isValidRedirect(redirectUrl: string, allowedPaths?: RegExp[]): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Perform redirect after login with security validation
|
|
16
|
+
*/
|
|
17
|
+
export declare function performRedirect(router: Router, config: NormalizedRedirectConfig): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Build query params for redirect to login
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildLoginQuery(currentPath: string, config: NormalizedRedirectConfig): Record<string, string>;
|