@bagelink/auth 1.7.72 → 1.7.76

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.mjs CHANGED
@@ -1077,7 +1077,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1077
1077
  const authResponse = ref(null);
1078
1078
  const { sso: sso2, user, accountInfo: accountInfo2 } = useAuth();
1079
1079
  const route = useRoute();
1080
- const router = useRouter();
1080
+ const router2 = useRouter();
1081
1081
  const providerInfo = computed(() => {
1082
1082
  if (provider.value === null) return null;
1083
1083
  return providers[provider.value];
@@ -1087,7 +1087,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1087
1087
  try {
1088
1088
  await sso2.handleLinkCallback();
1089
1089
  success.value = true;
1090
- setTimeout(() => router.push("/"), timeout);
1090
+ setTimeout(() => router2.push("/"), timeout);
1091
1091
  } catch (err) {
1092
1092
  const errorMessage = err instanceof Error ? err.message : "Failed to link account";
1093
1093
  error.value = errorMessage;
@@ -1106,7 +1106,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1106
1106
  } else {
1107
1107
  authResponse.value = response;
1108
1108
  success.value = true;
1109
- setTimeout(() => router.push("/"), timeout);
1109
+ setTimeout(() => router2.push("/"), timeout);
1110
1110
  }
1111
1111
  } catch (err) {
1112
1112
  const errorMessage = err instanceof Error ? err.message : "Authentication failed";
@@ -1237,10 +1237,10 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
1237
1237
  cardShadow: { type: Boolean, default: true }
1238
1238
  },
1239
1239
  setup(__props) {
1240
- const router = useRouter();
1240
+ const router2 = useRouter();
1241
1241
  function switchForm(form) {
1242
1242
  if (form === "login") {
1243
- router.push("/login");
1243
+ router2.push("/login");
1244
1244
  }
1245
1245
  }
1246
1246
  return (_ctx, _cache) => {
@@ -1281,12 +1281,12 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
1281
1281
  cardShadow: { type: Boolean, default: true }
1282
1282
  },
1283
1283
  setup(__props) {
1284
- const router = useRouter();
1284
+ const router2 = useRouter();
1285
1285
  function switchForm(form) {
1286
1286
  if (form === "signup") {
1287
- router.push("/signup");
1287
+ router2.push("/signup");
1288
1288
  } else if (form === "forgot-password") {
1289
- router.push("/forgot-password");
1289
+ router2.push("/forgot-password");
1290
1290
  }
1291
1291
  }
1292
1292
  return (_ctx, _cache) => {
@@ -1327,12 +1327,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1327
1327
  cardShadow: { type: Boolean, default: true }
1328
1328
  },
1329
1329
  setup(__props) {
1330
- const router = useRouter();
1330
+ const router2 = useRouter();
1331
1331
  const route = useRoute();
1332
1332
  const token = computed(() => route.query.token);
1333
1333
  function switchForm(form) {
1334
1334
  if (form === "login") {
1335
- router.push("/login");
1335
+ router2.push("/login");
1336
1336
  }
1337
1337
  }
1338
1338
  return (_ctx, _cache) => {
@@ -1364,10 +1364,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1364
1364
  cardShadow: { type: Boolean, default: true }
1365
1365
  },
1366
1366
  setup(__props) {
1367
- const router = useRouter();
1367
+ const router2 = useRouter();
1368
1368
  function switchForm(form) {
1369
1369
  if (form === "login") {
1370
- router.push("/login");
1370
+ router2.push("/login");
1371
1371
  }
1372
1372
  }
1373
1373
  return (_ctx, _cache) => {
@@ -1389,70 +1389,56 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1389
1389
  };
1390
1390
  }
1391
1391
  });
1392
- function createAuthRoutes(config = {}) {
1393
- const {
1394
- basePath = "",
1395
- namePrefix = "",
1396
- routeNames = {},
1397
- layout
1398
- } = config;
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(router2, config) {
1393
+ const redirect2 = router2.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
- return routes;
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 createAuthGuard(config = {}) {
1445
- const { redirectTo = "/" } = config;
1446
- return async (to, _from, next) => {
1447
- const { useAuth: useAuth2 } = await Promise.resolve().then(() => useAuth$1);
1448
- const { user } = useAuth2();
1449
- if (to.meta.requiresAuth === false && user.value) {
1450
- next(redirectTo);
1451
- } else {
1452
- next();
1453
- }
1454
- };
1417
+ async function performRedirect(router2, config) {
1418
+ const redirect2 = getRedirectUrl(router2, config);
1419
+ if (redirect2 !== config.fallback && !isValidRedirect(redirect2, config.allowedPaths)) {
1420
+ console.warn("[Auth] Invalid redirect URL detected, using fallback:", redirect2);
1421
+ await router2.push(config.fallback);
1422
+ return;
1423
+ }
1424
+ await router2.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,34 @@ 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;
1909
+ let cachedAuthGuard = null;
1905
1910
  const accountInfo = ref(null);
1911
+ function getRedirectConfig() {
1912
+ if (!redirectConfig) {
1913
+ throw new Error("Redirect config not initialized. Did you call createAuth with redirect config?");
1914
+ }
1915
+ return redirectConfig;
1916
+ }
1906
1917
  function createAuth(params) {
1907
1918
  if (authApi === null) {
1908
1919
  authApi = new AuthApi(params.baseURL);
@@ -1910,7 +1921,13 @@ function createAuth(params) {
1910
1921
  if (eventEmitter === null) {
1911
1922
  eventEmitter = new EventEmitter();
1912
1923
  }
1913
- return {
1924
+ if (params.redirect) {
1925
+ redirectConfig = normalizeRedirectConfig(params.redirect);
1926
+ }
1927
+ if (redirectConfig == null ? void 0 : redirectConfig.autoRedirect) {
1928
+ setupAutoRedirect();
1929
+ }
1930
+ const authInstance = {
1914
1931
  // Event listener methods
1915
1932
  on(event, handler) {
1916
1933
  if (eventEmitter) {
@@ -1927,10 +1944,89 @@ function createAuth(params) {
1927
1944
  eventEmitter.removeAllListeners(event);
1928
1945
  }
1929
1946
  },
1947
+ /**
1948
+ * Connect external dependencies like Vue Router
1949
+ * Automatically sets up router guard when router is provided
1950
+ * @param dependency - Vue Router instance or other plugins
1951
+ * @param options - Configuration options
1952
+ * @param options.guard - Whether to automatically set up auth guard (default: true)
1953
+ * @example
1954
+ * ```ts
1955
+ * // Auto setup (default)
1956
+ * auth.use(router)
1957
+ *
1958
+ * // Manual guard control (for custom composition)
1959
+ * auth.use(router, { guard: false })
1960
+ * router.beforeEach(async (to, from, next) => {
1961
+ * // Custom logic first
1962
+ * if (!hasOrgAccess(to)) return next('/no-access')
1963
+ * // Then run auth guard
1964
+ * return auth.routerGuard()(to, from, next)
1965
+ * })
1966
+ * ```
1967
+ */
1968
+ use(dependency, options = {}) {
1969
+ const { guard = true } = options;
1970
+ if (dependency && (dependency.beforeEach || dependency.push || dependency.currentRoute)) {
1971
+ autoRedirectRouter = dependency;
1972
+ if (guard) {
1973
+ dependency.beforeEach(authInstance.routerGuard());
1974
+ }
1975
+ }
1976
+ return authInstance;
1977
+ },
1978
+ /**
1979
+ * Create a Vue Router navigation guard for authentication
1980
+ * Protects routes requiring authentication and handles redirect logic
1981
+ * Note: Automatically called by auth.use(router), only use directly for custom setups
1982
+ * @example
1983
+ * ```ts
1984
+ * // Automatic (recommended)
1985
+ * auth.use(router)
1986
+ *
1987
+ * // Manual (for custom setups)
1988
+ * router.beforeEach(auth.routerGuard())
1989
+ * ```
1990
+ */
1991
+ routerGuard() {
1992
+ if (cachedAuthGuard === null) {
1993
+ cachedAuthGuard = async (to, from, next) => {
1994
+ const { authGuard: authGuard2 } = await Promise.resolve().then(() => router);
1995
+ const guard = authGuard2();
1996
+ cachedAuthGuard = guard;
1997
+ return guard(to, from, next);
1998
+ };
1999
+ }
2000
+ return cachedAuthGuard;
2001
+ },
2002
+ /**
2003
+ * Vue plugin install method
2004
+ * Makes auth available globally as $auth
2005
+ * @example
2006
+ * ```ts
2007
+ * app.use(auth)
2008
+ * ```
2009
+ */
1930
2010
  install(app) {
1931
2011
  app.config.globalProperties.$auth = useAuth();
1932
2012
  }
1933
2013
  };
2014
+ return authInstance;
2015
+ }
2016
+ function setupAutoRedirect() {
2017
+ if (!eventEmitter || !redirectConfig) return;
2018
+ eventEmitter.on(AuthState.LOGIN, async () => {
2019
+ if (!autoRedirectRouter) {
2020
+ console.warn("[Auth] Auto-redirect enabled but router not set. Call setAuthRouter(router) in your app setup.");
2021
+ return;
2022
+ }
2023
+ const { performRedirect: performRedirect2 } = await Promise.resolve().then(() => redirect);
2024
+ try {
2025
+ await performRedirect2(autoRedirectRouter, redirectConfig);
2026
+ } catch (error) {
2027
+ console.error("[Auth] Auto-redirect error:", error);
2028
+ }
2029
+ });
1934
2030
  }
1935
2031
  function useAuth() {
1936
2032
  if (authApi === null) {
@@ -2180,13 +2276,141 @@ function useAuth() {
2180
2276
  const useAuth$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2181
2277
  __proto__: null,
2182
2278
  createAuth,
2279
+ getRedirectConfig,
2183
2280
  useAuth
2184
2281
  }, Symbol.toStringTag, { value: "Module" }));
2282
+ let authInitialized = false;
2283
+ function resetAuthState() {
2284
+ authInitialized = false;
2285
+ }
2286
+ function authGuard() {
2287
+ return async function guard(to, _from, next) {
2288
+ const auth = useAuth();
2289
+ const config = getRedirectConfig();
2290
+ const requiresAuth = to.meta[config.authMetaKey];
2291
+ const requiresNoAuth = config.noAuthRoutes.includes(to.name);
2292
+ try {
2293
+ if (!authInitialized) {
2294
+ await auth.checkAuth();
2295
+ authInitialized = true;
2296
+ }
2297
+ const isAuthenticated = !!auth.user.value;
2298
+ if (isAuthenticated && requiresNoAuth) {
2299
+ next(config.authenticatedRedirect);
2300
+ return;
2301
+ }
2302
+ if (!isAuthenticated && requiresAuth) {
2303
+ const query = buildLoginQuery(to.fullPath, config);
2304
+ next({
2305
+ name: config.loginRoute,
2306
+ query
2307
+ });
2308
+ return;
2309
+ }
2310
+ next();
2311
+ } catch (error) {
2312
+ console.error("[Auth Guard] Error:", error);
2313
+ next();
2314
+ }
2315
+ };
2316
+ }
2317
+ function composeGuards(guards) {
2318
+ return async (to, from, next) => {
2319
+ let guardIndex = 0;
2320
+ const runNextGuard = async () => {
2321
+ if (guardIndex >= guards.length) {
2322
+ next();
2323
+ return;
2324
+ }
2325
+ const guard = guards[guardIndex];
2326
+ guardIndex++;
2327
+ await guard(to, from, (result) => {
2328
+ if (result !== void 0) {
2329
+ next(result);
2330
+ } else {
2331
+ runNextGuard();
2332
+ }
2333
+ });
2334
+ };
2335
+ await runNextGuard();
2336
+ };
2337
+ }
2338
+ const router = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2339
+ __proto__: null,
2340
+ authGuard,
2341
+ composeGuards,
2342
+ resetAuthState
2343
+ }, Symbol.toStringTag, { value: "Module" }));
2344
+ function createAuthRoutes(config = {}) {
2345
+ const {
2346
+ basePath = "",
2347
+ namePrefix = "",
2348
+ routeNames = {},
2349
+ layout
2350
+ } = config;
2351
+ const createRouteName = (name) => namePrefix ? `${namePrefix}${name}` : name;
2352
+ const routes = [
2353
+ {
2354
+ path: `${basePath}/login`,
2355
+ name: routeNames.login || createRouteName("Login"),
2356
+ component: () => import("./LoginPage-klj1NV4J.js"),
2357
+ meta: { requiresAuth: false }
2358
+ },
2359
+ {
2360
+ path: `${basePath}/signup`,
2361
+ name: routeNames.signup || createRouteName("Signup"),
2362
+ component: () => import("./SignupPage-oUFYApYW.js"),
2363
+ meta: { requiresAuth: false }
2364
+ },
2365
+ {
2366
+ path: `${basePath}/forgot-password`,
2367
+ name: routeNames.forgotPassword || createRouteName("ForgotPassword"),
2368
+ component: () => import("./ForgotPasswordPage-DvttMGb0.js"),
2369
+ meta: { requiresAuth: false }
2370
+ },
2371
+ {
2372
+ path: `${basePath}/reset-password`,
2373
+ name: routeNames.resetPassword || createRouteName("ResetPassword"),
2374
+ component: () => import("./ResetPasswordPage-nvQ4uupb.js"),
2375
+ meta: { requiresAuth: false }
2376
+ },
2377
+ {
2378
+ path: `${basePath}/callback`,
2379
+ name: routeNames.callback || createRouteName("AuthCallback"),
2380
+ component: () => import("./Callback-C-XghN_z.js"),
2381
+ meta: { requiresAuth: false }
2382
+ }
2383
+ ];
2384
+ if (layout) {
2385
+ return [{
2386
+ path: basePath,
2387
+ component: layout,
2388
+ children: routes.map((route) => ({
2389
+ ...route,
2390
+ path: route.path.replace(basePath, "")
2391
+ }))
2392
+ }];
2393
+ }
2394
+ return routes;
2395
+ }
2396
+ function createAuthGuard(config = {}) {
2397
+ const { redirectTo = "/" } = config;
2398
+ return async (to, _from, next) => {
2399
+ const { useAuth: useAuth2 } = await Promise.resolve().then(() => useAuth$1);
2400
+ const { user } = useAuth2();
2401
+ if (to.meta.requiresAuth === false && user.value) {
2402
+ next(redirectTo);
2403
+ } else {
2404
+ next();
2405
+ }
2406
+ };
2407
+ }
2185
2408
  export {
2186
2409
  AuthApi,
2187
2410
  AuthState,
2188
2411
  _sfc_main$4 as Callback,
2189
2412
  DEFAULT_AGENT_ID,
2413
+ DEFAULT_REDIRECT_CONFIG,
2190
2414
  _sfc_main$8 as ForgotPasswordForm,
2191
2415
  _sfc_main$3 as ForgotPasswordPage,
2192
2416
  INTAKE_WORKFLOW_ID,
@@ -2202,13 +2426,22 @@ export {
2202
2426
  _sfc_main as SignupPage,
2203
2427
  StateMismatchError,
2204
2428
  accountToUser,
2429
+ authGuard,
2430
+ buildLoginQuery,
2431
+ composeGuards,
2205
2432
  createAuth,
2206
2433
  createAuthGuard,
2207
2434
  createAuthRoutes,
2208
2435
  getAllSSOProviders,
2436
+ getRedirectConfig,
2437
+ getRedirectUrl,
2209
2438
  getSSOProvider,
2210
2439
  isSupportedProvider,
2440
+ isValidRedirect,
2441
+ normalizeRedirectConfig,
2442
+ performRedirect,
2211
2443
  providers,
2444
+ resetAuthState,
2212
2445
  setAuthContext,
2213
2446
  sso,
2214
2447
  ssoProvidersList,
@@ -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>;
@@ -0,0 +1,36 @@
1
+ import { NavigationGuard, NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
2
+ /**
3
+ * Reset auth initialization state
4
+ * Useful for testing or app reload scenarios
5
+ */
6
+ export declare function resetAuthState(): void;
7
+ /**
8
+ * Auth guard for Vue Router
9
+ *
10
+ * Protects routes requiring authentication and handles redirect logic.
11
+ * Reads configuration from the auth instance created via createAuth().
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const auth = createAuth({
16
+ * baseURL: 'https://api.example.com',
17
+ * redirect: { ... }
18
+ * })
19
+ * router.beforeEach(authGuard())
20
+ * ```
21
+ */
22
+ export declare function authGuard(): (to: RouteLocationNormalized, _from: RouteLocationNormalized, next: NavigationGuardNext) => Promise<void>;
23
+ /**
24
+ * Compose multiple navigation guards into one
25
+ * Guards are executed in order, stopping at the first one that calls next with a value
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * router.beforeEach(composeGuards([
30
+ * authGuard(),
31
+ * orgAccessGuard(),
32
+ * featureFlagGuard(),
33
+ * ]))
34
+ * ```
35
+ */
36
+ export declare function composeGuards(guards: NavigationGuard[]): NavigationGuard;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Redirect configuration types for auth library
3
+ */
4
+ export interface RedirectConfig {
5
+ /**
6
+ * Query parameter key used to store the redirect URL
7
+ * After login, read this param to redirect users back to their intended destination
8
+ * @default 'redirect'
9
+ */
10
+ queryKey?: string;
11
+ /**
12
+ * Default fallback URL when no redirect is specified
13
+ * @default '/'
14
+ */
15
+ fallback?: string;
16
+ /**
17
+ * Routes that require NO authentication (login, signup, forgot password, etc)
18
+ * Authenticated users will be automatically redirected away from these pages
19
+ * @default ['Login', 'Signup', 'ForgotPassword', 'ResetPassword', 'Callback']
20
+ */
21
+ noAuthRoutes?: string[];
22
+ /**
23
+ * Route name to redirect to when authenticated users try to access auth-only pages
24
+ * @default '/'
25
+ */
26
+ authenticatedRedirect?: string;
27
+ /**
28
+ * Route name to redirect to when unauthenticated users try to access protected pages
29
+ * @default 'Login'
30
+ */
31
+ loginRoute?: string;
32
+ /**
33
+ * Meta key used to check if a route requires authentication
34
+ * @default 'auth'
35
+ * @example In your route: `meta: { auth: true }`
36
+ */
37
+ authMetaKey?: string;
38
+ /**
39
+ * Enable automatic redirect handling after login
40
+ * When true, the library automatically redirects users after successful login
41
+ * @default true
42
+ */
43
+ autoRedirect?: boolean;
44
+ /**
45
+ * Enable redirect preservation for protected routes
46
+ * When enabled, the original URL is preserved as a query param after redirecting to login
47
+ * @default true
48
+ */
49
+ preserveRedirect?: boolean;
50
+ /**
51
+ * Optional allowed redirect path patterns for security validation
52
+ * If specified, only URLs matching these patterns will be allowed
53
+ * @default undefined (allows all internal paths)
54
+ */
55
+ allowedPaths?: RegExp[];
56
+ }
57
+ /**
58
+ * Normalized redirect configuration with all defaults applied
59
+ */
60
+ export interface NormalizedRedirectConfig extends Required<Omit<RedirectConfig, 'allowedPaths'>> {
61
+ allowedPaths?: RegExp[];
62
+ }
63
+ /**
64
+ * Default redirect configuration
65
+ */
66
+ export declare const DEFAULT_REDIRECT_CONFIG: NormalizedRedirectConfig;
67
+ /**
68
+ * Normalize redirect configuration by applying defaults
69
+ */
70
+ export declare function normalizeRedirectConfig(config?: RedirectConfig): NormalizedRedirectConfig;
package/dist/useAuth.d.ts CHANGED
@@ -1,12 +1,69 @@
1
1
  import { App } from 'vue';
2
2
  import { AccountInfo, User, NewUser, UpdatePasswordForm, UpdateAccountRequest, AuthEventMap, SSOProvider, SSOInitiateRequest, SSOCallbackRequest, SSOLinkRequest, AuthState } from './types';
3
+ import { RedirectConfig, NormalizedRedirectConfig } from './types/redirect';
3
4
  interface InitParams {
4
5
  baseURL: string;
6
+ /**
7
+ * Redirect configuration for authentication flows
8
+ * @see RedirectConfig
9
+ */
10
+ redirect?: RedirectConfig;
5
11
  }
12
+ /**
13
+ * Get the current redirect configuration
14
+ * Used internally by router guard
15
+ */
16
+ export declare function getRedirectConfig(): NormalizedRedirectConfig;
6
17
  export declare function createAuth(params: InitParams): {
7
18
  on<K extends AuthState>(event: K, handler: AuthEventMap[K]): void;
8
19
  off<K extends AuthState>(event: K, handler: AuthEventMap[K]): void;
9
20
  removeAllListeners<K extends AuthState>(event?: K): void;
21
+ /**
22
+ * Connect external dependencies like Vue Router
23
+ * Automatically sets up router guard when router is provided
24
+ * @param dependency - Vue Router instance or other plugins
25
+ * @param options - Configuration options
26
+ * @param options.guard - Whether to automatically set up auth guard (default: true)
27
+ * @example
28
+ * ```ts
29
+ * // Auto setup (default)
30
+ * auth.use(router)
31
+ *
32
+ * // Manual guard control (for custom composition)
33
+ * auth.use(router, { guard: false })
34
+ * router.beforeEach(async (to, from, next) => {
35
+ * // Custom logic first
36
+ * if (!hasOrgAccess(to)) return next('/no-access')
37
+ * // Then run auth guard
38
+ * return auth.routerGuard()(to, from, next)
39
+ * })
40
+ * ```
41
+ */
42
+ use(dependency: any, options?: {
43
+ guard?: boolean;
44
+ }): /*elided*/ any;
45
+ /**
46
+ * Create a Vue Router navigation guard for authentication
47
+ * Protects routes requiring authentication and handles redirect logic
48
+ * Note: Automatically called by auth.use(router), only use directly for custom setups
49
+ * @example
50
+ * ```ts
51
+ * // Automatic (recommended)
52
+ * auth.use(router)
53
+ *
54
+ * // Manual (for custom setups)
55
+ * router.beforeEach(auth.routerGuard())
56
+ * ```
57
+ */
58
+ routerGuard(): any;
59
+ /**
60
+ * Vue plugin install method
61
+ * Makes auth available globally as $auth
62
+ * @example
63
+ * ```ts
64
+ * app.use(auth)
65
+ * ```
66
+ */
10
67
  install(app: App): void;
11
68
  };
12
69
  export declare function useAuth(): {