@securitydept/client-react 0.3.0-beta.1 → 0.3.0-beta.11
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 +6 -0
- package/dist/index.d.mts +101 -84
- package/dist/index.mjs +404 -71
- package/dist/index.mjs.map +1 -1
- package/dist/tanstack-router/index.d.mts +76 -415
- package/dist/tanstack-router/index.mjs +96 -380
- package/dist/tanstack-router/index.mjs.map +1 -1
- package/package.json +16 -5
|
@@ -1,428 +1,89 @@
|
|
|
1
|
-
import { AuthRequirement,
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* The adapter reads `staticData` (set via `beforeLoad` or `staticData` option)
|
|
10
|
-
* to find auth requirements.
|
|
11
|
-
*/
|
|
12
|
-
interface TanStackRouteMatch {
|
|
13
|
-
/** Route identifier (the route's `id` field). */
|
|
14
|
-
routeId: string;
|
|
15
|
-
/**
|
|
16
|
-
* Static route context, typically set via `beforeLoad` or `staticData`.
|
|
17
|
-
* Auth requirements should be declared here under a well-known key.
|
|
18
|
-
*
|
|
19
|
-
* Typed as `object` (not `Record<string, unknown>`) to remain structurally
|
|
20
|
-
* compatible with TanStack Router's open `StaticDataRouteOption` interface,
|
|
21
|
-
* which does not carry an index signature.
|
|
22
|
-
*/
|
|
23
|
-
staticData?: object;
|
|
24
|
-
/** Route context merged from parent. */
|
|
25
|
-
context?: object;
|
|
26
|
-
/** Route loader data, if available. */
|
|
27
|
-
loaderData?: object;
|
|
1
|
+
import { AuthRequirement, EnvironmentValidators, FoundationEnvironment, RequirementBehaviourWithRouteContext, RequirementPlannerHost, RequirementPlannerHostBehaviour, RequirementsComposition, RouteBehaviourContextExtra, RouteTreeSegment, RouterTrait, SecuritydeptInjectorTrait, WithTraitInputValidator } from "@securitydept/client";
|
|
2
|
+
import { AnyRouter, NavigateOptions } from "@tanstack/react-router";
|
|
3
|
+
//#region src/tanstack-router/auth-coordination/route-metadata.d.ts
|
|
4
|
+
interface TanStackRouteMatchLike {
|
|
5
|
+
readonly id?: string;
|
|
6
|
+
readonly routeId?: string;
|
|
7
|
+
readonly pathname?: string;
|
|
8
|
+
readonly staticData?: object;
|
|
28
9
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*/
|
|
40
|
-
requirementsKey?: string;
|
|
10
|
+
declare function projectTanStackRouteSegments<TAuthRequirement extends AuthRequirement = AuthRequirement>(matches: readonly TanStackRouteMatchLike[]): RouteTreeSegment<TAuthRequirement>[];
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/tanstack-router/auth-coordination/route-guard.d.ts
|
|
13
|
+
interface SecuritydeptTanStackRouterContext {
|
|
14
|
+
readonly securitydeptInjector: SecuritydeptInjectorTrait;
|
|
15
|
+
readonly router?: {
|
|
16
|
+
readonly state: {
|
|
17
|
+
readonly matches: readonly TanStackRouteMatchLike[];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
41
20
|
}
|
|
42
|
-
interface
|
|
43
|
-
|
|
44
|
-
|
|
21
|
+
interface TanStackBeforeLoadContextLike {
|
|
22
|
+
readonly context: SecuritydeptTanStackRouterContext;
|
|
23
|
+
readonly matches: readonly TanStackRouteMatchLike[];
|
|
24
|
+
readonly location: {
|
|
25
|
+
readonly href: string;
|
|
26
|
+
};
|
|
45
27
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* `attemptedUrl` is the TanStack Router target URL for the navigation being
|
|
50
|
-
* guarded. Use it as `postAuthRedirectUri` when a handler starts a full-page
|
|
51
|
-
* auth redirect; do not infer this from `window.location`, because the current
|
|
52
|
-
* document URL can still point at the previously committed route.
|
|
53
|
-
*/
|
|
54
|
-
interface TanStackRouteUnauthenticatedContext {
|
|
55
|
-
readonly location: TanStackRouteLocation;
|
|
56
|
-
readonly attemptedUrl: string;
|
|
57
|
-
readonly matches: readonly TanStackRouteMatch[];
|
|
58
|
-
readonly cause: string | undefined;
|
|
28
|
+
interface CreateTanStackBeforeLoadWithPlannerHostOptions<TAuthRequirement extends AuthRequirement = AuthRequirement, TBehaviour extends Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>> = Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>>> {
|
|
29
|
+
readonly plannerHost: RequirementPlannerHost<TBehaviour>;
|
|
30
|
+
readonly behaviour?: never;
|
|
59
31
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Options for {@link withTanStackRouteRequirements}.
|
|
65
|
-
*/
|
|
66
|
-
interface WithTanStackRouteRequirementsOptions {
|
|
67
|
-
/**
|
|
68
|
-
* How this route segment composes with its parent route chain.
|
|
69
|
-
* @default RequirementsClientSetComposition.Merge
|
|
70
|
-
*/
|
|
71
|
-
composition?: RequirementsClientSetComposition;
|
|
72
|
-
/**
|
|
73
|
-
* Additional staticData properties to merge into the returned object.
|
|
74
|
-
*/
|
|
75
|
-
extra?: Record<string, unknown>;
|
|
32
|
+
interface CreateTanStackBeforeLoadWithBehaviourOptions<TAuthRequirement extends AuthRequirement = AuthRequirement, TBehaviour extends Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>> = Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>>> {
|
|
33
|
+
readonly plannerHost?: never;
|
|
34
|
+
readonly behaviour?: RequirementPlannerHostBehaviour<TAuthRequirement, RouteBehaviourContextExtra, TBehaviour>;
|
|
76
35
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* This is the TanStack Router equivalent of Angular's `withRouteRequirements()`.
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```ts
|
|
85
|
-
* import { createRoute } from "@tanstack/react-router";
|
|
86
|
-
* import { withTanStackRouteRequirements } from "@securitydept/client-react/tanstack-router";
|
|
87
|
-
*
|
|
88
|
-
* const dashboardRoute = createRoute({
|
|
89
|
-
* getParentRoute: () => rootRoute,
|
|
90
|
-
* path: "dashboard",
|
|
91
|
-
* staticData: withTanStackRouteRequirements([
|
|
92
|
-
* { id: "session", kind: "session" },
|
|
93
|
-
* ]),
|
|
94
|
-
* });
|
|
95
|
-
*
|
|
96
|
-
* // Child route replaces parent requirements:
|
|
97
|
-
* const publicRoute = createRoute({
|
|
98
|
-
* getParentRoute: () => dashboardRoute,
|
|
99
|
-
* path: "public",
|
|
100
|
-
* staticData: withTanStackRouteRequirements([], {
|
|
101
|
-
* composition: RequirementsClientSetComposition.Replace,
|
|
102
|
-
* }),
|
|
103
|
-
* });
|
|
104
|
-
* ```
|
|
105
|
-
*
|
|
106
|
-
* @param requirements - Auth requirements for this route segment.
|
|
107
|
-
* @param options - Optional composition strategy and extra staticData.
|
|
108
|
-
*/
|
|
109
|
-
declare function withTanStackRouteRequirements(requirements: AuthRequirement[], options?: WithTanStackRouteRequirementsOptions): Record<string, unknown>;
|
|
110
|
-
/**
|
|
111
|
-
* Extract and compose auth requirements from a TanStack Router matched route
|
|
112
|
-
* chain, respecting merge/replace/inherit composition at each segment.
|
|
113
|
-
*
|
|
114
|
-
* This is the TanStack Router equivalent of Angular's
|
|
115
|
-
* `extractFullRouteRequirements()`. It walks the matched route chain from root
|
|
116
|
-
* to leaf and applies the composition strategy declared at each segment:
|
|
117
|
-
*
|
|
118
|
-
* - `inherit` — keep parent requirements unchanged
|
|
119
|
-
* - `merge` — append child requirements, replacing same-id parent entries
|
|
120
|
-
* - `replace` — discard parent chain, use only child's requirements
|
|
121
|
-
*
|
|
122
|
-
* @param matches - Matched route chain from root to leaf (as from `useMatches()`).
|
|
123
|
-
* @param options - Optional key override.
|
|
124
|
-
*/
|
|
125
|
-
declare function extractTanStackRouteRequirements(matches: readonly TanStackRouteMatch[], options?: TanStackRouterAdapterOptions): AuthRequirement[];
|
|
126
|
-
/**
|
|
127
|
-
* Route-level auth requirement declaration for composition resolution.
|
|
128
|
-
*/
|
|
129
|
-
interface RouteRequirementsDeclaration {
|
|
130
|
-
requirements: readonly AuthRequirement[];
|
|
131
|
-
composition: RequirementsClientSetComposition;
|
|
36
|
+
type CreateTanStackBeforeLoadOptions<TAuthRequirement extends AuthRequirement = AuthRequirement, TBehaviour extends Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>> = Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>>> = CreateTanStackBeforeLoadWithPlannerHostOptions<TAuthRequirement, TBehaviour> | CreateTanStackBeforeLoadWithBehaviourOptions<TAuthRequirement, TBehaviour>;
|
|
37
|
+
declare class TanStackRouteSecurityBlockedError extends Error {
|
|
38
|
+
readonly requirement: AuthRequirement;
|
|
39
|
+
constructor(requirement: AuthRequirement);
|
|
132
40
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
* - `merge` appends child requirements and replaces same-id parent entries
|
|
140
|
-
* - `replace` discards the parent chain and uses only the child's requirements
|
|
141
|
-
*/
|
|
142
|
-
declare function resolveEffectiveRequirements(parentRequirements: readonly AuthRequirement[], child: RouteRequirementsDeclaration): AuthRequirement[];
|
|
143
|
-
/**
|
|
144
|
-
* Project TanStack Router matched route entries into the SDK's
|
|
145
|
-
* `RouteMatchNode[]` contract.
|
|
146
|
-
*
|
|
147
|
-
* Each match entry is mapped to a `RouteMatchNode`:
|
|
148
|
-
* - `routeId` is taken from `match.routeId`
|
|
149
|
-
* - `requirements` is read from `match.staticData[requirementsKey]`
|
|
150
|
-
*
|
|
151
|
-
* Entries with no requirements produce nodes with an empty requirements array,
|
|
152
|
-
* preserving the full chain for shared-prefix diffing.
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* ```ts
|
|
156
|
-
* import { useMatches } from "@tanstack/react-router";
|
|
157
|
-
* import { projectTanStackRouteMatches } from "@securitydept/client-react/tanstack-router";
|
|
158
|
-
*
|
|
159
|
-
* const matches = useMatches();
|
|
160
|
-
* const routeChain = projectTanStackRouteMatches(matches);
|
|
161
|
-
* orchestrator.activateMatchedRoutes(routeChain);
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
|
-
declare function projectTanStackRouteMatches(matches: readonly TanStackRouteMatch[], options?: TanStackRouterAdapterOptions): RouteMatchNode[];
|
|
165
|
-
/**
|
|
166
|
-
* Create a route-change activator that projects TanStack Router matches and
|
|
167
|
-
* activates them on the orchestrator.
|
|
168
|
-
*
|
|
169
|
-
* This is framework-agnostic (not a React hook) and can be called from a
|
|
170
|
-
* `useEffect`, route subscriber, or any mechanism that notifies match changes.
|
|
171
|
-
*
|
|
172
|
-
* @example
|
|
173
|
-
* ```ts
|
|
174
|
-
* import { useMatches } from "@@tanstack/react-router";
|
|
175
|
-
* import { createTanStackRouteActivator } from "@securitydept/client-react/tanstack-router";
|
|
176
|
-
*
|
|
177
|
-
* const activator = createTanStackRouteActivator(orchestrator);
|
|
178
|
-
*
|
|
179
|
-
* function RouteOrchestrationBridge() {
|
|
180
|
-
* const matches = useMatches();
|
|
181
|
-
* useEffect(() => activator.activate(matches), [matches]);
|
|
182
|
-
* return null;
|
|
183
|
-
* }
|
|
184
|
-
* ```
|
|
185
|
-
*/
|
|
186
|
-
declare function createTanStackRouteActivator(orchestrator: {
|
|
187
|
-
activateMatchedRoutes(chain: readonly RouteMatchNode[]): void;
|
|
188
|
-
deactivateRoute(): void;
|
|
189
|
-
}, options?: TanStackRouterAdapterOptions): {
|
|
190
|
-
/** Project matches and activate the route chain on the orchestrator. */activate(matches: readonly TanStackRouteMatch[]): void; /** Deactivate the current route (e.g. on unmount or navigation away). */
|
|
191
|
-
deactivate(): void;
|
|
192
|
-
};
|
|
193
|
-
/**
|
|
194
|
-
* Root-level runtime policy for a secured TanStack Router route tree.
|
|
195
|
-
*
|
|
196
|
-
* This is the TanStack Router equivalent of Angular's
|
|
197
|
-
* `SecureRouteRootSecurityOptions`. Non-serializable runtime callbacks
|
|
198
|
-
* (planner host, onUnauthenticated handlers) live here, NOT in individual
|
|
199
|
-
* route `staticData`.
|
|
200
|
-
*
|
|
201
|
-
* @example
|
|
202
|
-
* ```ts
|
|
203
|
-
* const routeSecurityPolicy = createTanStackRouteSecurityPolicy({
|
|
204
|
-
* requirementHandlers: {
|
|
205
|
-
* frontend_oidc: (failingRequirement) => {
|
|
206
|
-
* redirectToLogin(failingRequirement);
|
|
207
|
-
* return false;
|
|
208
|
-
* },
|
|
209
|
-
* },
|
|
210
|
-
* });
|
|
211
|
-
*
|
|
212
|
-
* // Use in beforeLoad:
|
|
213
|
-
* const protectedRoute = createRoute({
|
|
214
|
-
* beforeLoad: ({ matches }) => {
|
|
215
|
-
* routeSecurityPolicy.enforce(matches);
|
|
216
|
-
* },
|
|
217
|
-
* });
|
|
218
|
-
* ```
|
|
219
|
-
*/
|
|
220
|
-
interface TanStackRouteSecurityPolicyOptions {
|
|
221
|
-
/**
|
|
222
|
-
* Per-requirement-kind handlers.
|
|
223
|
-
* Keys are `AuthRequirement.kind` strings.
|
|
224
|
-
*/
|
|
225
|
-
requirementHandlers?: Record<string, TanStackRouteUnauthenticatedHandler>;
|
|
226
|
-
/**
|
|
227
|
-
* Fallback handler when no kind-specific handler matches.
|
|
228
|
-
*/
|
|
229
|
-
defaultOnUnauthenticated?: TanStackRouteUnauthenticatedHandler;
|
|
230
|
-
/**
|
|
231
|
-
* Custom key for reading requirements from staticData.
|
|
232
|
-
* @default "authRequirements"
|
|
233
|
-
*/
|
|
234
|
-
requirementsKey?: string;
|
|
41
|
+
declare function createTanStackBeforeLoad<TAuthRequirement extends AuthRequirement = AuthRequirement, TBehaviour extends Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>> = Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>>>(options?: CreateTanStackBeforeLoadOptions<TAuthRequirement, TBehaviour>): (context: TanStackBeforeLoadContextLike) => Promise<void>;
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/tanstack-router/auth-coordination/secure-routes.d.ts
|
|
44
|
+
interface CreateTanStackRouterContextOptions {
|
|
45
|
+
readonly environment?: FoundationEnvironment;
|
|
46
|
+
readonly injector?: SecuritydeptInjectorTrait;
|
|
235
47
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
/** All requirements are met — allow navigation. */
|
|
242
|
-
readonly allMet: boolean;
|
|
243
|
-
/** The first unmet requirement, if any. */
|
|
244
|
-
readonly pendingRequirement: AuthRequirement | undefined;
|
|
245
|
-
/** Handler action for the pending requirement (from policy). */
|
|
246
|
-
readonly action: TanStackRouteUnauthenticatedAction | Promise<TanStackRouteUnauthenticatedAction> | undefined;
|
|
247
|
-
/** The full effective requirements after composition. */
|
|
248
|
-
readonly effectiveRequirements: readonly AuthRequirement[];
|
|
48
|
+
interface TanStackRouteSecurityOptions<TAuthRequirement extends AuthRequirement = AuthRequirement, TBehaviour extends Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>> = Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>>> {
|
|
49
|
+
readonly requirements?: readonly TAuthRequirement[];
|
|
50
|
+
readonly composition?: RequirementsComposition;
|
|
51
|
+
readonly plannerHost?: RequirementPlannerHost<TBehaviour>;
|
|
52
|
+
readonly behaviour?: RequirementPlannerHostBehaviour<TAuthRequirement, RouteBehaviourContextExtra, TBehaviour>;
|
|
249
53
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
* return false;
|
|
273
|
-
* },
|
|
274
|
-
* },
|
|
275
|
-
* defaultOnUnauthenticated: () => "/login",
|
|
276
|
-
* });
|
|
277
|
-
*
|
|
278
|
-
* // In a route's beforeLoad or a React effect:
|
|
279
|
-
* const result = policy.evaluate(matches, (req) => isAuthenticated(req.kind));
|
|
280
|
-
* if (!result.allMet && typeof result.action === "string") {
|
|
281
|
-
* navigate({ to: result.action });
|
|
282
|
-
* }
|
|
283
|
-
* ```
|
|
284
|
-
*/
|
|
285
|
-
declare function createTanStackRouteSecurityPolicy(options?: TanStackRouteSecurityPolicyOptions): {
|
|
286
|
-
/**
|
|
287
|
-
* Evaluate the route security policy for a matched route chain.
|
|
288
|
-
*
|
|
289
|
-
* @param matches - The matched route chain (root → leaf).
|
|
290
|
-
* @param checkAuthenticated - Returns true if a requirement is met.
|
|
291
|
-
*/
|
|
292
|
-
evaluate(matches: readonly TanStackRouteMatch[], checkAuthenticated: (requirement: AuthRequirement) => boolean, context?: TanStackRouteUnauthenticatedContext): TanStackRouteSecurityResult;
|
|
293
|
-
/**
|
|
294
|
-
* Async-capable evaluation for router guards that must wait for auth
|
|
295
|
-
* freshness checks before deciding whether navigation is allowed.
|
|
296
|
-
*/
|
|
297
|
-
evaluateAsync(matches: readonly TanStackRouteMatch[], checkAuthenticated: TanStackRouteAuthenticatedCheck, context?: TanStackRouteUnauthenticatedContext): Promise<TanStackRouteSecurityResult>;
|
|
298
|
-
};
|
|
299
|
-
/**
|
|
300
|
-
* Navigation-blocked error thrown by {@link createSecureBeforeLoad} when a
|
|
301
|
-
* requirement is unmet and the handler returns `false`.
|
|
302
|
-
*/
|
|
303
|
-
declare class RouteSecurityBlockedError extends Error {
|
|
304
|
-
readonly requirement: AuthRequirement;
|
|
305
|
-
readonly result: TanStackRouteSecurityResult;
|
|
306
|
-
constructor(requirement: AuthRequirement, result: TanStackRouteSecurityResult);
|
|
54
|
+
interface CreateTanStackRouteSecurityPatchOptions {
|
|
55
|
+
readonly staticData?: object;
|
|
56
|
+
}
|
|
57
|
+
interface TanStackRouteSecurityPatch {
|
|
58
|
+
readonly staticData: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
interface TanStackRouteRootSecurityPatch extends TanStackRouteSecurityPatch {
|
|
61
|
+
readonly beforeLoad: (context: TanStackBeforeLoadContextLike) => Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
declare function createTanStackRouterContext(options?: CreateTanStackRouterContextOptions): Pick<SecuritydeptTanStackRouterContext, "securitydeptInjector">;
|
|
64
|
+
declare function secureRoute<TAuthRequirement extends AuthRequirement = AuthRequirement, TBehaviour extends Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>> = Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>>>(security: TanStackRouteSecurityOptions<TAuthRequirement, TBehaviour>, options?: CreateTanStackRouteSecurityPatchOptions): TanStackRouteSecurityPatch;
|
|
65
|
+
declare function secureRouteRoot<TAuthRequirement extends AuthRequirement = AuthRequirement, TBehaviour extends Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>> = Partial<RequirementBehaviourWithRouteContext<TAuthRequirement>>>(security: TanStackRouteSecurityOptions<TAuthRequirement, TBehaviour>, options?: CreateTanStackRouteSecurityPatchOptions): TanStackRouteRootSecurityPatch;
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/tanstack-router/router.d.ts
|
|
68
|
+
interface TanStackRouterLocationLike {
|
|
69
|
+
readonly href: string;
|
|
70
|
+
}
|
|
71
|
+
interface TanStackRouterNavigationLike {
|
|
72
|
+
readonly state?: {
|
|
73
|
+
readonly location?: TanStackRouterLocationLike;
|
|
74
|
+
};
|
|
75
|
+
navigate(options: TanStackRouterNavigateOptions): Promise<unknown> | unknown;
|
|
307
76
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
* required. The full TanStack Router context has many more fields; this
|
|
313
|
-
* interface lets the helper stay structurally compatible without importing
|
|
314
|
-
* the full framework type.
|
|
315
|
-
*/
|
|
316
|
-
interface SecureBeforeLoadContext {
|
|
317
|
-
/** URL location of the target route. */
|
|
318
|
-
location: TanStackRouteLocation;
|
|
319
|
-
/**
|
|
320
|
-
* Matched route entries for the current navigation.
|
|
321
|
-
* Shape matches {@link TanStackRouteMatch}.
|
|
322
|
-
*/
|
|
323
|
-
matches: readonly TanStackRouteMatch[];
|
|
324
|
-
/** Navigation cause ("enter", "stay", "push", "replace", etc.). */
|
|
325
|
-
cause: string;
|
|
77
|
+
type TanStackRouterNavigateOptions = NavigateOptions<AnyRouter, string, string | undefined, string, "">;
|
|
78
|
+
interface CreateRouterForTanStackRouterOptions {
|
|
79
|
+
readonly router: TanStackRouterNavigationLike;
|
|
80
|
+
readonly currentUrl?: string | null;
|
|
326
81
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
interface CreateSecureBeforeLoadOptions extends TanStackRouteSecurityPolicyOptions {
|
|
331
|
-
/**
|
|
332
|
-
* Returns true if the given auth requirement is currently satisfied.
|
|
333
|
-
*
|
|
334
|
-
* This is the auth-state bridge: the adopter supplies a function that
|
|
335
|
-
* checks their auth store / context.
|
|
336
|
-
*/
|
|
337
|
-
checkAuthenticated: TanStackRouteAuthenticatedCheck;
|
|
338
|
-
/**
|
|
339
|
-
* TanStack Router's `redirect()` function.
|
|
340
|
-
*
|
|
341
|
-
* When a handler returns a string (redirect path), `createSecureBeforeLoad`
|
|
342
|
-
* throws `redirect({ to: path })` to trigger TanStack Router's redirect
|
|
343
|
-
* mechanism.
|
|
344
|
-
*
|
|
345
|
-
* Pass `redirect` from `@tanstack/react-router` here:
|
|
346
|
-
* ```ts
|
|
347
|
-
* import { redirect } from "@tanstack/react-router";
|
|
348
|
-
* createSecureBeforeLoad({ redirect, ... });
|
|
349
|
-
* ```
|
|
350
|
-
*
|
|
351
|
-
* If omitted, string actions cause a {@link RouteSecurityBlockedError}
|
|
352
|
-
* with the redirect path in the error message.
|
|
353
|
-
*/
|
|
354
|
-
redirect?: (opts: {
|
|
355
|
-
to: string;
|
|
356
|
-
}) => never;
|
|
82
|
+
interface ResolvedRouterForTanStackRouterCreateOptions {
|
|
83
|
+
readonly router: TanStackRouterNavigationLike;
|
|
84
|
+
readonly currentUrl: string | null;
|
|
357
85
|
}
|
|
358
|
-
|
|
359
|
-
* Create a `beforeLoad`-compatible function that enforces route-security
|
|
360
|
-
* requirements inside TanStack Router's execution semantics.
|
|
361
|
-
*
|
|
362
|
-
* **This is the canonical TanStack Router adopter-facing entry** — the
|
|
363
|
-
* equivalent of Angular's `secureRouteRoot()`.
|
|
364
|
-
*
|
|
365
|
-
* How it works:
|
|
366
|
-
* 1. Receives TanStack Router's `beforeLoad` context (including `matches`)
|
|
367
|
-
* 2. Extracts the full requirement chain with composition semantics
|
|
368
|
-
* 3. Finds the first unmet requirement
|
|
369
|
-
* 4. Calls the handler (kind handler → default → block)
|
|
370
|
-
* 5. If the handler returns a string path, throws `redirect({ to: path })`
|
|
371
|
-
* 6. If the handler returns `false`, throws {@link RouteSecurityBlockedError}
|
|
372
|
-
* 7. If all requirements are met, returns normally (navigation proceeds)
|
|
373
|
-
*
|
|
374
|
-
* @example
|
|
375
|
-
* ```ts
|
|
376
|
-
* import { redirect, createRoute } from "@tanstack/react-router";
|
|
377
|
-
* import {
|
|
378
|
-
* createSecureBeforeLoad,
|
|
379
|
-
* withTanStackRouteRequirements,
|
|
380
|
-
* } from "@securitydept/client-react/tanstack-router";
|
|
381
|
-
*
|
|
382
|
-
* // Root-level: non-serializable runtime policy
|
|
383
|
-
* const securedBeforeLoad = createSecureBeforeLoad({
|
|
384
|
-
* redirect,
|
|
385
|
-
* checkAuthenticated: (req) => authStore.isAuthenticated(req.kind),
|
|
386
|
-
* requirementHandlers: {
|
|
387
|
-
* frontend_oidc: (req) => "/login/oidc",
|
|
388
|
-
* session: () => "/login",
|
|
389
|
-
* },
|
|
390
|
-
* });
|
|
391
|
-
*
|
|
392
|
-
* // Root route — attach the beforeLoad
|
|
393
|
-
* const rootRoute = createRootRoute({
|
|
394
|
-
* beforeLoad: securedBeforeLoad,
|
|
395
|
-
* });
|
|
396
|
-
*
|
|
397
|
-
* // Child routes — serializable declaration only
|
|
398
|
-
* const dashboardRoute = createRoute({
|
|
399
|
-
* getParentRoute: () => rootRoute,
|
|
400
|
-
* path: "dashboard",
|
|
401
|
-
* staticData: withTanStackRouteRequirements([
|
|
402
|
-
* { id: "session", kind: "session" },
|
|
403
|
-
* ]),
|
|
404
|
-
* });
|
|
405
|
-
*
|
|
406
|
-
* const adminRoute = createRoute({
|
|
407
|
-
* getParentRoute: () => dashboardRoute,
|
|
408
|
-
* path: "admin",
|
|
409
|
-
* staticData: withTanStackRouteRequirements([
|
|
410
|
-
* { id: "admin-oidc", kind: "frontend_oidc" },
|
|
411
|
-
* ]),
|
|
412
|
-
* });
|
|
413
|
-
* ```
|
|
414
|
-
*/
|
|
415
|
-
declare function createSecureBeforeLoad(options: CreateSecureBeforeLoadOptions): (ctx: SecureBeforeLoadContext) => void | Promise<void>;
|
|
416
|
-
/**
|
|
417
|
-
* Build a route-security handler for full-page external redirects.
|
|
418
|
-
*
|
|
419
|
-
* The callback should start the browser navigation, typically by calling an
|
|
420
|
-
* auth client's `loginWithRedirect({ postAuthRedirectUri: context.attemptedUrl })`.
|
|
421
|
-
* After that navigation has been started, the returned guard result never
|
|
422
|
-
* settles so TanStack Router does not finalize an in-app blocked navigation
|
|
423
|
-
* while the page is leaving for an external IdP.
|
|
424
|
-
*/
|
|
425
|
-
declare function createExternalRedirectBeforeLoadHandler(startRedirect: (requirement: AuthRequirement, context: TanStackRouteUnauthenticatedContext) => void | Promise<void>): TanStackRouteUnauthenticatedHandler;
|
|
86
|
+
declare function createRouterForTanStackRouter(options: CreateRouterForTanStackRouterOptions & WithTraitInputValidator<Pick<EnvironmentValidators, "router">>): RouterTrait;
|
|
426
87
|
//#endregion
|
|
427
|
-
export {
|
|
88
|
+
export { CreateRouterForTanStackRouterOptions, CreateTanStackBeforeLoadOptions, CreateTanStackBeforeLoadWithBehaviourOptions, CreateTanStackBeforeLoadWithPlannerHostOptions, CreateTanStackRouteSecurityPatchOptions, CreateTanStackRouterContextOptions, ResolvedRouterForTanStackRouterCreateOptions, SecuritydeptTanStackRouterContext, TanStackBeforeLoadContextLike, TanStackRouteMatchLike, TanStackRouteRootSecurityPatch, TanStackRouteSecurityBlockedError, TanStackRouteSecurityOptions, TanStackRouteSecurityPatch, TanStackRouterLocationLike, TanStackRouterNavigateOptions, TanStackRouterNavigationLike, createRouterForTanStackRouter, createTanStackBeforeLoad, createTanStackRouterContext, projectTanStackRouteSegments, secureRoute, secureRouteRoot };
|
|
428
89
|
//# sourceMappingURL=index.d.mts.map
|