@dudousxd/nestjs-inertia 1.0.0
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/CHANGELOG.md +139 -0
- package/LICENSE +21 -0
- package/README.md +317 -0
- package/dist/index.cjs +2314 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +461 -0
- package/dist/index.js +2265 -0
- package/dist/index.js.map +1 -0
- package/package.json +120 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler, NestMiddleware, ForbiddenException, NestModule, OnApplicationBootstrap, OnApplicationShutdown, DynamicModule, MiddlewareConsumer, CanActivate } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { Request, Response, NextFunction } from 'express';
|
|
4
|
+
import { Reflector, HttpAdapterHost } from '@nestjs/core';
|
|
5
|
+
|
|
6
|
+
interface InertiaRequest {
|
|
7
|
+
method: string;
|
|
8
|
+
originalUrl: string;
|
|
9
|
+
url: string;
|
|
10
|
+
header(name: string): string | undefined;
|
|
11
|
+
body?: unknown;
|
|
12
|
+
query?: Record<string, unknown>;
|
|
13
|
+
raw: unknown;
|
|
14
|
+
}
|
|
15
|
+
interface InertiaResponse {
|
|
16
|
+
statusCode: number;
|
|
17
|
+
headersSent: boolean;
|
|
18
|
+
status(code: number): InertiaResponse;
|
|
19
|
+
setHeader(name: string, value: string): InertiaResponse;
|
|
20
|
+
getHeader(name: string): string | string[] | number | undefined;
|
|
21
|
+
json(body: unknown): void;
|
|
22
|
+
html(body: string): void;
|
|
23
|
+
end(): void;
|
|
24
|
+
raw: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ManifestEntry {
|
|
28
|
+
file: string;
|
|
29
|
+
css?: string[];
|
|
30
|
+
imports?: string[];
|
|
31
|
+
}
|
|
32
|
+
type Manifest = Record<string, ManifestEntry>;
|
|
33
|
+
|
|
34
|
+
type FlashErrors = Record<string, string | Record<string, string>>;
|
|
35
|
+
interface FlashStore {
|
|
36
|
+
read(req: unknown): FlashErrors | Promise<FlashErrors>;
|
|
37
|
+
write?(req: unknown, errors: FlashErrors): void | Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const INERTIA_MODULE_OPTIONS: unique symbol;
|
|
41
|
+
declare const INERTIA_FEATURE_OPTIONS: unique symbol;
|
|
42
|
+
declare const INERTIA_MANIFEST: unique symbol;
|
|
43
|
+
declare const INERTIA_ASSET_VERSION: unique symbol;
|
|
44
|
+
declare const INERTIA_DEFAULT_SCOPE = "default";
|
|
45
|
+
type InertiaScope = string;
|
|
46
|
+
declare function featureToken(kind: 'OPTIONS' | 'MANIFEST' | 'ASSET_VERSION' | 'SHELL_RENDERER' | 'SSR_LOADER', scope: string, rootId?: string): symbol;
|
|
47
|
+
|
|
48
|
+
interface PageObject {
|
|
49
|
+
component: string;
|
|
50
|
+
props: Record<string, unknown>;
|
|
51
|
+
url: string;
|
|
52
|
+
version: string;
|
|
53
|
+
encryptHistory?: boolean;
|
|
54
|
+
clearHistory?: boolean;
|
|
55
|
+
deferredProps?: Record<string, string[]>;
|
|
56
|
+
mergeProps?: string[];
|
|
57
|
+
deepMergeProps?: string[];
|
|
58
|
+
matchPropsOn?: Record<string, string>;
|
|
59
|
+
}
|
|
60
|
+
interface SsrResult {
|
|
61
|
+
head: string[];
|
|
62
|
+
body: string;
|
|
63
|
+
}
|
|
64
|
+
type Props = Record<string, unknown>;
|
|
65
|
+
type SharedFactory = (req: unknown) => Props | Promise<Props>;
|
|
66
|
+
type SharedInput = Props | SharedFactory;
|
|
67
|
+
interface ShellRenderCtx {
|
|
68
|
+
page: PageObject;
|
|
69
|
+
ssr: SsrResult | null;
|
|
70
|
+
manifest: unknown;
|
|
71
|
+
assetVersion: string;
|
|
72
|
+
ctx: {
|
|
73
|
+
req: unknown;
|
|
74
|
+
res: unknown;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
type RootViewFn = (ctx: ShellRenderCtx) => string | Promise<string>;
|
|
78
|
+
type RootView = string | RootViewFn;
|
|
79
|
+
interface ViteOptions {
|
|
80
|
+
entry: string;
|
|
81
|
+
manifestPath?: string;
|
|
82
|
+
hmrPort?: number;
|
|
83
|
+
}
|
|
84
|
+
interface SsrOptions {
|
|
85
|
+
enabled?: boolean;
|
|
86
|
+
bundlePath?: string;
|
|
87
|
+
devMode?: 'off' | 'vite';
|
|
88
|
+
throwOnError?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Options controlling the auto-bootstrap of the `@dudousxd/nestjs-inertia-codegen` file watcher
|
|
92
|
+
* that is started automatically inside `InertiaModule.onApplicationBootstrap` in dev mode.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* // Disable auto-watch entirely (e.g. in CI or when running the CLI watcher manually):
|
|
96
|
+
* InertiaModule.forRoot({ codegen: { enabled: false } })
|
|
97
|
+
*/
|
|
98
|
+
interface CodegenOptions {
|
|
99
|
+
/**
|
|
100
|
+
* Whether to auto-start the codegen watcher when the application bootstraps.
|
|
101
|
+
*
|
|
102
|
+
* - `'auto'` (default) — start when `NODE_ENV !== 'production'` AND the
|
|
103
|
+
* `@dudousxd/nestjs-inertia-codegen` package is installed AND a
|
|
104
|
+
* `nestjs-inertia.config.ts` config file is present.
|
|
105
|
+
* - `true` — same as `'auto'`.
|
|
106
|
+
* - `false` — never auto-start; useful when running the CLI watcher (`nestjs-inertia codegen --watch`)
|
|
107
|
+
* in a separate terminal or when you want to disable codegen entirely.
|
|
108
|
+
*/
|
|
109
|
+
enabled?: boolean | 'auto';
|
|
110
|
+
}
|
|
111
|
+
interface InertiaModuleOptions {
|
|
112
|
+
rootView?: RootView;
|
|
113
|
+
vite?: ViteOptions;
|
|
114
|
+
ssr?: SsrOptions;
|
|
115
|
+
share?: SharedInput;
|
|
116
|
+
version?: string | (() => string | Promise<string>);
|
|
117
|
+
historyEncryption?: {
|
|
118
|
+
default?: boolean;
|
|
119
|
+
};
|
|
120
|
+
autoUpgrade303?: boolean;
|
|
121
|
+
methodSpoofing?: boolean;
|
|
122
|
+
codegen?: CodegenOptions;
|
|
123
|
+
flashStore?: FlashStore;
|
|
124
|
+
}
|
|
125
|
+
interface InertiaFeatureOptions extends InertiaModuleOptions {
|
|
126
|
+
scope: InertiaScope;
|
|
127
|
+
}
|
|
128
|
+
interface InertiaOptionsFactory {
|
|
129
|
+
createInertiaOptions(): Promise<InertiaModuleOptions> | InertiaModuleOptions;
|
|
130
|
+
}
|
|
131
|
+
interface InertiaFeatureAsyncOptions {
|
|
132
|
+
scope: string;
|
|
133
|
+
imports?: unknown[];
|
|
134
|
+
inject?: unknown[];
|
|
135
|
+
useExisting?: new (...args: unknown[]) => InertiaOptionsFactory;
|
|
136
|
+
useClass?: new (...args: unknown[]) => InertiaOptionsFactory;
|
|
137
|
+
useFactory?: (...args: unknown[]) => Promise<InertiaModuleOptions> | InertiaModuleOptions;
|
|
138
|
+
}
|
|
139
|
+
interface InertiaModuleAsyncOptions {
|
|
140
|
+
imports?: unknown[];
|
|
141
|
+
inject?: unknown[];
|
|
142
|
+
useExisting?: new (...args: unknown[]) => InertiaOptionsFactory;
|
|
143
|
+
useClass?: new (...args: unknown[]) => InertiaOptionsFactory;
|
|
144
|
+
useFactory?: (...args: unknown[]) => Promise<InertiaModuleOptions> | InertiaModuleOptions;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
interface SsrModule {
|
|
148
|
+
render(page: PageObject): Promise<{
|
|
149
|
+
head: string[];
|
|
150
|
+
body: string;
|
|
151
|
+
}>;
|
|
152
|
+
}
|
|
153
|
+
interface SsrLoader {
|
|
154
|
+
load(): Promise<SsrModule | null>;
|
|
155
|
+
}
|
|
156
|
+
interface InertiaServiceDeps {
|
|
157
|
+
assetVersion: string;
|
|
158
|
+
manifest: Manifest | null;
|
|
159
|
+
ssrLoader: SsrLoader;
|
|
160
|
+
rootViewRender: (ctx: ShellRenderCtx) => Promise<string>;
|
|
161
|
+
moduleShare: SharedInput | undefined;
|
|
162
|
+
featureShare: SharedInput | undefined;
|
|
163
|
+
historyEncryptionDefault?: boolean;
|
|
164
|
+
flashStore: FlashStore | undefined;
|
|
165
|
+
}
|
|
166
|
+
declare class InertiaService {
|
|
167
|
+
private readonly req;
|
|
168
|
+
private readonly res;
|
|
169
|
+
private readonly deps;
|
|
170
|
+
private readonly logger;
|
|
171
|
+
private shared;
|
|
172
|
+
private encryptHistoryFlag;
|
|
173
|
+
private clearHistoryFlag;
|
|
174
|
+
constructor(req: InertiaRequest, res: InertiaResponse, deps: InertiaServiceDeps);
|
|
175
|
+
share(input: SharedInput): this;
|
|
176
|
+
/**
|
|
177
|
+
* Perform an Inertia redirect. For Inertia XHR requests, issues a 409 with
|
|
178
|
+
* `X-Inertia-Location`; for plain browser visits, issues a 302 redirect.
|
|
179
|
+
*
|
|
180
|
+
* Only relative URLs (starting with `/`) or same-origin absolute URLs are
|
|
181
|
+
* accepted. Absolute URLs pointing to a different host are rejected to prevent
|
|
182
|
+
* open-redirect vulnerabilities.
|
|
183
|
+
*
|
|
184
|
+
* @param url Relative path (e.g. `/dashboard`) or same-origin absolute URL.
|
|
185
|
+
* @throws Error when `url` is an absolute URL pointing to a different origin.
|
|
186
|
+
*/
|
|
187
|
+
location(url: string): void;
|
|
188
|
+
encryptHistory(value?: boolean): this;
|
|
189
|
+
clearHistory(): this;
|
|
190
|
+
private resolveShared;
|
|
191
|
+
render(component: string, props?: Props): Promise<void>;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
declare class ErrorBagInterceptor implements NestInterceptor {
|
|
195
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare class RedirectInterceptor implements NestInterceptor {
|
|
199
|
+
private readonly options;
|
|
200
|
+
constructor(options: InertiaModuleOptions);
|
|
201
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
declare class MethodSpoofMiddleware implements NestMiddleware {
|
|
205
|
+
private readonly options;
|
|
206
|
+
constructor(options: InertiaModuleOptions);
|
|
207
|
+
use(req: Request & {
|
|
208
|
+
body?: Record<string, unknown>;
|
|
209
|
+
}, _res: Response, next: NextFunction): void;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
declare class InvalidInertiaConfigException extends Error {
|
|
213
|
+
constructor(message: string);
|
|
214
|
+
}
|
|
215
|
+
declare class InertiaServiceNotAvailableException extends Error {
|
|
216
|
+
constructor();
|
|
217
|
+
}
|
|
218
|
+
declare class UnsupportedRootViewExtensionException extends Error {
|
|
219
|
+
constructor(extension: string);
|
|
220
|
+
}
|
|
221
|
+
declare class MissingTemplateEngineDepException extends Error {
|
|
222
|
+
constructor(engine: string, packageName: string);
|
|
223
|
+
}
|
|
224
|
+
declare class MissingCookieDepException extends Error {
|
|
225
|
+
constructor(platform: 'express' | 'fastify');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
declare class InvalidCsrfTokenException extends ForbiddenException {
|
|
229
|
+
constructor();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
declare const MARKER: unique symbol;
|
|
233
|
+
type MarkerKind = 'always' | 'optional' | 'defer' | 'merge' | 'once';
|
|
234
|
+
interface Marker<T = unknown> {
|
|
235
|
+
[MARKER]: true;
|
|
236
|
+
kind: MarkerKind;
|
|
237
|
+
value: () => T | Promise<T>;
|
|
238
|
+
meta: Record<string, unknown>;
|
|
239
|
+
}
|
|
240
|
+
declare function inertiaDecorator(component: string): MethodDecorator;
|
|
241
|
+
declare function always<T>(fn: () => T | Promise<T>): Marker<T>;
|
|
242
|
+
declare function optional<T>(fn: () => T | Promise<T>): Marker<T>;
|
|
243
|
+
/**
|
|
244
|
+
* @deprecated Use `Inertia.optional()` instead. `Inertia.lazy()` is a deprecated alias
|
|
245
|
+
* kept for v1/v2 backward compatibility and will be removed in a future major version.
|
|
246
|
+
*/
|
|
247
|
+
declare function lazy<T>(fn: () => T | Promise<T>): Marker<T>;
|
|
248
|
+
declare function defer<T>(fn: () => T | Promise<T>, group?: string): Marker<T>;
|
|
249
|
+
declare function once<T>(fn: () => T | Promise<T>): Marker<T>;
|
|
250
|
+
declare function merge<T>(fn: () => T | Promise<T>, opts?: {
|
|
251
|
+
matchOn?: string;
|
|
252
|
+
deep?: boolean;
|
|
253
|
+
}): Marker<T>;
|
|
254
|
+
type InertiaFn = typeof inertiaDecorator & {
|
|
255
|
+
always: typeof always;
|
|
256
|
+
optional: typeof optional;
|
|
257
|
+
lazy: typeof lazy;
|
|
258
|
+
defer: typeof defer;
|
|
259
|
+
once: typeof once;
|
|
260
|
+
merge: typeof merge;
|
|
261
|
+
};
|
|
262
|
+
declare const Inertia: InertiaFn;
|
|
263
|
+
|
|
264
|
+
declare const INERTIA_USE_SCOPE = "INERTIA_USE_SCOPE";
|
|
265
|
+
declare function UseInertia(scope: string): ClassDecorator & MethodDecorator;
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Empty interface for module augmentation by codegen consumers.
|
|
269
|
+
* Augment this interface (e.g. via `nestjs-inertia.d.ts` emitted by `nestjs-inertia init`)
|
|
270
|
+
* to register typed `pages` / `shared` / `routes` maps.
|
|
271
|
+
*
|
|
272
|
+
* MUST remain an `interface` (not a `type` alias) — `declare module ... { interface ... }`
|
|
273
|
+
* augmentation only works on interfaces. Converting to `type X = {}` silently breaks the
|
|
274
|
+
* Link component's `routeParams` typing in every consumer app.
|
|
275
|
+
*/
|
|
276
|
+
interface InertiaRegistry {
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Resolves to the augmented routes map when `InertiaRegistry` has been extended
|
|
280
|
+
* with a `routes` key (via `nestjs-inertia.d.ts`), otherwise falls back to
|
|
281
|
+
* `Record<string, unknown>` so client code compiles without codegen.
|
|
282
|
+
*/
|
|
283
|
+
type RegistryRoutes = InertiaRegistry extends {
|
|
284
|
+
routes: infer R;
|
|
285
|
+
} ? R : Record<string, unknown>;
|
|
286
|
+
|
|
287
|
+
declare const INERTIA_RENDER_COMPONENT: unique symbol;
|
|
288
|
+
|
|
289
|
+
declare class InertiaRenderInterceptor implements NestInterceptor {
|
|
290
|
+
private readonly reflector;
|
|
291
|
+
constructor(reflector: Reflector);
|
|
292
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
interface ShellRenderer {
|
|
296
|
+
render(ctx: ShellRenderCtx): Promise<string>;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/** Minimal interface matching `Watcher` from `@dudousxd/nestjs-inertia-codegen`. */
|
|
300
|
+
interface CodegenWatcher {
|
|
301
|
+
close(): Promise<void>;
|
|
302
|
+
}
|
|
303
|
+
/** Minimal interface matching the codegen module's public API used here. */
|
|
304
|
+
interface CodegenModule {
|
|
305
|
+
loadConfig(cwd?: string): Promise<unknown>;
|
|
306
|
+
watch(config: unknown): Promise<CodegenWatcher>;
|
|
307
|
+
}
|
|
308
|
+
declare class InertiaModule implements NestModule, OnApplicationBootstrap, OnApplicationShutdown {
|
|
309
|
+
private readonly httpAdapterHost;
|
|
310
|
+
private readonly options;
|
|
311
|
+
private readonly assetVersion;
|
|
312
|
+
private readonly manifest;
|
|
313
|
+
private readonly shellRenderer;
|
|
314
|
+
private readonly ssrLoader;
|
|
315
|
+
/**
|
|
316
|
+
* Shared provider set for both `forRoot` and `forRootAsync`.
|
|
317
|
+
* Does NOT include the options provider(s) — callers prepend those themselves.
|
|
318
|
+
*/
|
|
319
|
+
private static buildModuleProviders;
|
|
320
|
+
private static readonly moduleExports;
|
|
321
|
+
static forRoot(options?: InertiaModuleOptions): DynamicModule;
|
|
322
|
+
static forRootAsync(asyncOptions: InertiaModuleAsyncOptions): DynamicModule;
|
|
323
|
+
static forFeature(options: InertiaFeatureOptions): DynamicModule;
|
|
324
|
+
static forFeatureAsync(asyncOptions: InertiaFeatureAsyncOptions): DynamicModule;
|
|
325
|
+
private static createFeatureProviders;
|
|
326
|
+
private static validateAsyncOptions;
|
|
327
|
+
private static createAsyncOptionsProviders;
|
|
328
|
+
private readonly logger;
|
|
329
|
+
private codegenWatcher;
|
|
330
|
+
constructor(httpAdapterHost: HttpAdapterHost, options: InertiaModuleOptions, assetVersion: string, manifest: Manifest | null, shellRenderer: ShellRenderer, ssrLoader: {
|
|
331
|
+
load: () => Promise<never>;
|
|
332
|
+
});
|
|
333
|
+
/**
|
|
334
|
+
* Test seam: override in a subclass or via `Object.defineProperty` to inject a stub
|
|
335
|
+
* codegen module without touching NestJS DI. Production callers never touch this.
|
|
336
|
+
*
|
|
337
|
+
* @internal
|
|
338
|
+
*/
|
|
339
|
+
protected _resolveCodegenModule(): Promise<CodegenModule>;
|
|
340
|
+
onApplicationBootstrap(): Promise<void>;
|
|
341
|
+
/**
|
|
342
|
+
* Auto-starts the codegen file watcher in dev mode.
|
|
343
|
+
*
|
|
344
|
+
* Rules (all must pass for the watcher to start):
|
|
345
|
+
* 1. `process.env.NODE_ENV !== 'production'`
|
|
346
|
+
* 2. `options.codegen?.enabled !== false`
|
|
347
|
+
* 3. `@dudousxd/nestjs-inertia-codegen` is resolvable (peer-optional)
|
|
348
|
+
* 4. A `nestjs-inertia.config.ts` (or equivalent) is present in `process.cwd()`
|
|
349
|
+
*
|
|
350
|
+
* If the CLI watcher already holds the lock file, the codegen package returns a
|
|
351
|
+
* no-op watcher — no conflict occurs.
|
|
352
|
+
*
|
|
353
|
+
* This method NEVER throws; any unexpected error is logged as a warning.
|
|
354
|
+
*/
|
|
355
|
+
private _startCodegenWatcher;
|
|
356
|
+
onApplicationShutdown(): Promise<void>;
|
|
357
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
type CookieResponse = {
|
|
361
|
+
cookie?: (name: string, value: string, opts?: unknown) => unknown;
|
|
362
|
+
setCookie?: (name: string, value: string, opts?: unknown) => unknown;
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* Force-issue a new CSRF token on the next response, discarding the existing
|
|
366
|
+
* one. Call this when the session principal changes (e.g. after issuing a new
|
|
367
|
+
* session) to prevent token fixation attacks.
|
|
368
|
+
*
|
|
369
|
+
* If you need to invalidate prior tokens (e.g., after session principal change),
|
|
370
|
+
* configure `tokenContext` to return a session-bound value (session ID, nonce) —
|
|
371
|
+
* old tokens fail verification when that value changes.
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```ts
|
|
375
|
+
* rotateCsrfToken(res, { secret: this.csrfSecret });
|
|
376
|
+
* ```
|
|
377
|
+
*/
|
|
378
|
+
declare function rotateCsrfToken(res: CookieResponse, options: Pick<CsrfCookieOptions, 'secret' | 'cookieName' | 'httpOnly' | 'sameSite' | 'secure'>, context?: string): void;
|
|
379
|
+
interface CsrfCookieOptions {
|
|
380
|
+
secret: string;
|
|
381
|
+
cookieName?: string;
|
|
382
|
+
headerName?: string;
|
|
383
|
+
sameSite?: 'lax' | 'strict' | 'none';
|
|
384
|
+
httpOnly?: boolean;
|
|
385
|
+
secure?: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* Optional function to extract a session-bound context value from the request.
|
|
388
|
+
* When provided, the HMAC payload includes this value so that tokens become
|
|
389
|
+
* invalid when the context changes (e.g. after a session principal change).
|
|
390
|
+
* Typical values: session ID, session nonce.
|
|
391
|
+
*
|
|
392
|
+
* @example
|
|
393
|
+
* ```ts
|
|
394
|
+
* tokenContext: (req) => req.session?.id ?? ''
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
397
|
+
tokenContext?: (req: unknown) => string;
|
|
398
|
+
}
|
|
399
|
+
declare class CsrfCookieInterceptor implements NestInterceptor {
|
|
400
|
+
private readonly options;
|
|
401
|
+
private readonly cookieName;
|
|
402
|
+
constructor(options: CsrfCookieOptions);
|
|
403
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface CsrfGuardOptions {
|
|
407
|
+
secret: string;
|
|
408
|
+
cookieName?: string;
|
|
409
|
+
headerName?: string;
|
|
410
|
+
/**
|
|
411
|
+
* Optional function to extract a session-bound context value from the request.
|
|
412
|
+
* Must match the `tokenContext` used in `CsrfCookieInterceptor` for the same app.
|
|
413
|
+
*/
|
|
414
|
+
tokenContext?: (req: unknown) => string;
|
|
415
|
+
}
|
|
416
|
+
declare class CsrfGuard implements CanActivate {
|
|
417
|
+
private readonly options;
|
|
418
|
+
private readonly cookieName;
|
|
419
|
+
private readonly headerName;
|
|
420
|
+
constructor(options: CsrfGuardOptions);
|
|
421
|
+
canActivate(ctx: ExecutionContext): boolean;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Generates a CSRF token.
|
|
426
|
+
*
|
|
427
|
+
* @param secret The HMAC secret.
|
|
428
|
+
* @param context Optional session-bound context value (e.g. session ID or nonce).
|
|
429
|
+
* When provided, the context is included in the HMAC payload so that
|
|
430
|
+
* tokens become invalid when the context changes (e.g. after a session
|
|
431
|
+
* principal change). Token format: `<raw>.<context-hex>.<sig>`
|
|
432
|
+
* Without context, format is: `<raw>.<sig>`
|
|
433
|
+
*/
|
|
434
|
+
declare function generateCsrfToken(secret: string, context?: string): string;
|
|
435
|
+
/**
|
|
436
|
+
* Constant-time buffer comparison that returns `false` for length mismatches
|
|
437
|
+
* rather than throwing, avoiding a timing oracle on length.
|
|
438
|
+
*/
|
|
439
|
+
declare function timingSafeEqualSafe(a: Buffer, b: Buffer): boolean;
|
|
440
|
+
/**
|
|
441
|
+
* Verifies a CSRF token.
|
|
442
|
+
*
|
|
443
|
+
* @param token The token string (from cookie or header).
|
|
444
|
+
* @param secret The HMAC secret.
|
|
445
|
+
* @param context Optional session-bound context value. Must match the context
|
|
446
|
+
* used when the token was generated. If the context has changed
|
|
447
|
+
* (e.g. new session), the old token will fail verification.
|
|
448
|
+
*/
|
|
449
|
+
declare function verifyCsrfToken(token: string, secret: string, context?: string): boolean;
|
|
450
|
+
|
|
451
|
+
declare const VERSION = "1.0.0";
|
|
452
|
+
|
|
453
|
+
declare global {
|
|
454
|
+
namespace Express {
|
|
455
|
+
interface Request {
|
|
456
|
+
inertia: InertiaService;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export { type CodegenOptions, CsrfCookieInterceptor, type CsrfCookieOptions, CsrfGuard, type CsrfGuardOptions, ErrorBagInterceptor, type FlashErrors, type FlashStore, INERTIA_ASSET_VERSION, INERTIA_DEFAULT_SCOPE, INERTIA_FEATURE_OPTIONS, INERTIA_MANIFEST, INERTIA_MODULE_OPTIONS, INERTIA_RENDER_COMPONENT, INERTIA_USE_SCOPE, Inertia, type InertiaFeatureAsyncOptions, type InertiaFeatureOptions, InertiaModule, type InertiaModuleAsyncOptions, type InertiaModuleOptions, type InertiaOptionsFactory, type InertiaRegistry, InertiaRenderInterceptor, InertiaService, InertiaServiceNotAvailableException, InvalidCsrfTokenException, InvalidInertiaConfigException, MethodSpoofMiddleware, MissingCookieDepException, MissingTemplateEngineDepException, type PageObject, type Props, RedirectInterceptor, type RegistryRoutes, type RootView, type RootViewFn, type SharedFactory, type SharedInput, type ShellRenderCtx, type ShellRenderer, type SsrOptions, type SsrResult, UnsupportedRootViewExtensionException, UseInertia, VERSION, type ViteOptions, featureToken, generateCsrfToken, rotateCsrfToken, timingSafeEqualSafe, verifyCsrfToken };
|