@nathapp/nestjs-csrf 3.3.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/.eslintrc.js +8 -0
- package/.nax/features/nestjs-csrf/.nax-acceptance.test.ts +785 -0
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +15 -0
- package/README.md +29 -0
- package/dist/constant/csrf.constants.d.ts +2 -0
- package/dist/constant/csrf.constants.js +6 -0
- package/dist/constant/csrf.constants.js.map +1 -0
- package/dist/constant/index.d.ts +1 -0
- package/dist/constant/index.js +7 -0
- package/dist/constant/index.js.map +1 -0
- package/dist/decorator/index.d.ts +1 -0
- package/dist/decorator/index.js +6 -0
- package/dist/decorator/index.js.map +1 -0
- package/dist/decorator/skip-csrf.decorator.d.ts +1 -0
- package/dist/decorator/skip-csrf.decorator.js +9 -0
- package/dist/decorator/skip-csrf.decorator.js.map +1 -0
- package/dist/guard/csrf.guard.d.ts +13 -0
- package/dist/guard/csrf.guard.js +85 -0
- package/dist/guard/csrf.guard.js.map +1 -0
- package/dist/guard/index.d.ts +1 -0
- package/dist/guard/index.js +6 -0
- package/dist/guard/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/interface/csrf-options.interface.d.ts +27 -0
- package/dist/interface/csrf-options.interface.js +3 -0
- package/dist/interface/csrf-options.interface.js.map +1 -0
- package/dist/interface/index.d.ts +1 -0
- package/dist/interface/index.js +3 -0
- package/dist/interface/index.js.map +1 -0
- package/dist/module/csrf.module.d.ts +15 -0
- package/dist/module/csrf.module.js +64 -0
- package/dist/module/csrf.module.js.map +1 -0
- package/dist/module/index.d.ts +1 -0
- package/dist/module/index.js +6 -0
- package/dist/module/index.js.map +1 -0
- package/dist/service/csrf-token.service.d.ts +4 -0
- package/dist/service/csrf-token.service.js +47 -0
- package/dist/service/csrf-token.service.js.map +1 -0
- package/dist/service/index.d.ts +2 -0
- package/dist/service/index.js +8 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/resolve-options.d.ts +2 -0
- package/dist/service/resolve-options.js +37 -0
- package/dist/service/resolve-options.js.map +1 -0
- package/lib/constant/csrf.constants.ts +3 -0
- package/lib/constant/index.ts +1 -0
- package/lib/decorator/index.ts +1 -0
- package/lib/decorator/skip-csrf.decorator.ts +6 -0
- package/lib/guard/csrf.guard.ts +98 -0
- package/lib/guard/index.ts +1 -0
- package/lib/index.ts +12 -0
- package/lib/interface/csrf-options.interface.ts +31 -0
- package/lib/interface/index.ts +7 -0
- package/lib/module/csrf.module.ts +74 -0
- package/lib/module/index.ts +1 -0
- package/lib/service/csrf-token.service.ts +34 -0
- package/lib/service/index.ts +2 -0
- package/lib/service/resolve-options.ts +47 -0
- package/package.json +55 -0
- package/test/csrf-token.service.behavior.spec.ts +110 -0
- package/test/csrf-token.service.spec.ts +18 -0
- package/test/csrf.constants.spec.ts +11 -0
- package/test/csrf.module.spec.ts +267 -0
- package/test/guard/csrf.guard.spec.ts +347 -0
- package/test/jest-nax.json +27 -0
- package/test/jest-test.json +28 -0
- package/test/resolve-csrf-options.spec.ts +128 -0
- package/test/skip-csrf.decorator.spec.ts +77 -0
- package/tsconfig.json +9 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @nathapp/nestjs-csrf
|
|
2
|
+
|
|
3
|
+
## 3.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a27440f: 3.3.0 milestone release. The `@nathapp/nestjs-*` packages now version and publish in lockstep at a unified version.
|
|
8
|
+
|
|
9
|
+
- **nestjs-csrf**: first public release — stateless double-submit-cookie CSRF guard (zero-dep HMAC, Express + Fastify, Bearer coexist skip, `@SkipCsrf()`, auto-binds `APP_GUARD`).
|
|
10
|
+
- **nestjs-health**: first public release — terminus aggregator over cache/prisma/queue with k8s liveness/readiness probes via a dynamic controller factory.
|
|
11
|
+
- **nestjs-idempotency**: first public release — `@Idempotent()` interceptor (zero-dep sha256 fingerprint, Express + Fastify, 409-in-flight, 2xx replay, fingerprint mismatch 422, fail-closed on store error).
|
|
12
|
+
- **nestjs-observability**: first public release — Prometheus RED metrics + OpenTelemetry tracing joined to the logging ALS; `initTracing()` pre-bootstrap hook.
|
|
13
|
+
- **nestjs-outbox**: first public release — transactional outbox relay (at-least-once via `ITransactionManager`, lease-claim + backoff, dead-letter).
|
|
14
|
+
- **nestjs-storage**: migrated from aws-sdk v2 to v3 (zero runtime dep via `import type` + lazy `loadPackage`); NFSStorage stub replaced with an S3-style HTTP file-service client.
|
|
15
|
+
- **nestjs-cache**: `delByPattern` now routes through Redis SCAN instead of an O(n) key sweep, with glob-detection and multi-tier iterator support.
|
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @nathapp/nestjs-csrf
|
|
2
|
+
|
|
3
|
+
Stateless double-submit-cookie CSRF protection for NestJS, working on both the
|
|
4
|
+
Express and Fastify adapters, with **zero runtime dependencies** (Node `crypto` only).
|
|
5
|
+
|
|
6
|
+
## Design
|
|
7
|
+
|
|
8
|
+
- **Double-submit cookie (stateless)** — no server-side session store. The guard
|
|
9
|
+
auto-issues an HMAC-signed token as a cookie on safe (GET/HEAD/OPTIONS) responses;
|
|
10
|
+
the client echoes it in the `x-csrf-token` header on mutating requests, and the
|
|
11
|
+
guard verifies the two match.
|
|
12
|
+
- **Guard-only** — `DefaultCsrfGuard` performs both auto-issue and verification;
|
|
13
|
+
`CsrfTokenService` is the pure stdlib-HMAC mint/verify core.
|
|
14
|
+
- **Coexists with bearer auth** — routes carrying `Authorization: Bearer …` are
|
|
15
|
+
skipped by default (a browser cannot silently attach that header cross-site).
|
|
16
|
+
- **Disable-able** — globally via the module `enabled` flag, and per-route via the
|
|
17
|
+
`@SkipCsrf()` decorator.
|
|
18
|
+
|
|
19
|
+
## Assumed peer setup
|
|
20
|
+
|
|
21
|
+
The host app **must enable cookie parsing** so `req.cookies` is populated:
|
|
22
|
+
|
|
23
|
+
- Express: `app.use(cookieParser())` (`cookie-parser`)
|
|
24
|
+
- Fastify: `app.register(require('@fastify/cookie'))` (`@fastify/cookie`)
|
|
25
|
+
|
|
26
|
+
These are not auto-wired. If cookie parsing is not enabled, mutating requests fail
|
|
27
|
+
closed (403).
|
|
28
|
+
|
|
29
|
+
See `docs/superpowers/specs/2026-07-08-nestjs-csrf-design.md`.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SKIP_CSRF_METADATA_KEY = exports.CSRF_MODULE_OPTIONS = void 0;
|
|
4
|
+
exports.CSRF_MODULE_OPTIONS = Symbol.for('@nathapp/nestjs-csrf/options');
|
|
5
|
+
exports.SKIP_CSRF_METADATA_KEY = Symbol.for('@nathapp/nestjs-csrf/skip');
|
|
6
|
+
//# sourceMappingURL=csrf.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf.constants.js","sourceRoot":"","sources":["../../lib/constant/csrf.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAEjE,QAAA,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CSRF_MODULE_OPTIONS, SKIP_CSRF_METADATA_KEY } from './csrf.constants';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SKIP_CSRF_METADATA_KEY = exports.CSRF_MODULE_OPTIONS = void 0;
|
|
4
|
+
var csrf_constants_1 = require("./csrf.constants");
|
|
5
|
+
Object.defineProperty(exports, "CSRF_MODULE_OPTIONS", { enumerable: true, get: function () { return csrf_constants_1.CSRF_MODULE_OPTIONS; } });
|
|
6
|
+
Object.defineProperty(exports, "SKIP_CSRF_METADATA_KEY", { enumerable: true, get: function () { return csrf_constants_1.SKIP_CSRF_METADATA_KEY; } });
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/constant/index.ts"],"names":[],"mappings":";;;AAAA,mDAA+E;AAAtE,qHAAA,mBAAmB,OAAA;AAAE,wHAAA,sBAAsB,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SkipCsrf } from './skip-csrf.decorator';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SkipCsrf = void 0;
|
|
4
|
+
var skip_csrf_decorator_1 = require("./skip-csrf.decorator");
|
|
5
|
+
Object.defineProperty(exports, "SkipCsrf", { enumerable: true, get: function () { return skip_csrf_decorator_1.SkipCsrf; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/decorator/index.ts"],"names":[],"mappings":";;;AAAA,6DAAiD;AAAxC,+GAAA,QAAQ,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function SkipCsrf(): MethodDecorator & ClassDecorator;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SkipCsrf = SkipCsrf;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const csrf_constants_1 = require("../constant/csrf.constants");
|
|
6
|
+
function SkipCsrf() {
|
|
7
|
+
return (0, common_1.SetMetadata)(csrf_constants_1.SKIP_CSRF_METADATA_KEY, true);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=skip-csrf.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skip-csrf.decorator.js","sourceRoot":"","sources":["../../lib/decorator/skip-csrf.decorator.ts"],"names":[],"mappings":";;AAGA,4BAEC;AALD,2CAA6C;AAC7C,+DAAoE;AAEpE,SAAgB,QAAQ;IACtB,OAAO,IAAA,oBAAW,EAAC,uCAAsB,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { CsrfOptions } from '../interface/csrf-options.interface';
|
|
4
|
+
import { CsrfTokenService } from '../service/csrf-token.service';
|
|
5
|
+
export declare class DefaultCsrfGuard implements CanActivate {
|
|
6
|
+
private readonly tokens;
|
|
7
|
+
private readonly reflector;
|
|
8
|
+
private readonly logger;
|
|
9
|
+
private readonly options;
|
|
10
|
+
constructor(rawOptions: CsrfOptions, tokens: CsrfTokenService, reflector: Reflector);
|
|
11
|
+
canActivate(context: ExecutionContext): boolean;
|
|
12
|
+
private issue;
|
|
13
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var DefaultCsrfGuard_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.DefaultCsrfGuard = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const core_1 = require("@nestjs/core");
|
|
19
|
+
const nestjs_common_1 = require("@nathapp/nestjs-common");
|
|
20
|
+
const csrf_constants_1 = require("../constant/csrf.constants");
|
|
21
|
+
const csrf_token_service_1 = require("../service/csrf-token.service");
|
|
22
|
+
const resolve_options_1 = require("../service/resolve-options");
|
|
23
|
+
let DefaultCsrfGuard = DefaultCsrfGuard_1 = class DefaultCsrfGuard {
|
|
24
|
+
constructor(rawOptions, tokens, reflector) {
|
|
25
|
+
this.tokens = tokens;
|
|
26
|
+
this.reflector = reflector;
|
|
27
|
+
this.logger = new common_1.Logger(DefaultCsrfGuard_1.name);
|
|
28
|
+
this.options = (0, resolve_options_1.resolveCsrfOptions)(rawOptions);
|
|
29
|
+
}
|
|
30
|
+
canActivate(context) {
|
|
31
|
+
var _a, _b, _c, _d, _e;
|
|
32
|
+
if (this.options.enabled === false)
|
|
33
|
+
return true;
|
|
34
|
+
const http = context.switchToHttp();
|
|
35
|
+
const req = http.getRequest();
|
|
36
|
+
const res = http.getResponse();
|
|
37
|
+
if (this.options.ignoreMethods.includes(((_a = req.method) !== null && _a !== void 0 ? _a : '').toUpperCase())) {
|
|
38
|
+
const existingCookie = (_b = req.cookies) === null || _b === void 0 ? void 0 : _b[this.options.cookie.name];
|
|
39
|
+
if (!existingCookie) {
|
|
40
|
+
this.issue(res);
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const reflectionTargets = [context.getHandler(), context.getClass()];
|
|
45
|
+
const validTargets = reflectionTargets.filter((t) => t != null);
|
|
46
|
+
if (validTargets.length > 0 &&
|
|
47
|
+
this.reflector.getAllAndOverride(csrf_constants_1.SKIP_CSRF_METADATA_KEY, validTargets)) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if (this.options.skipWhenBearer &&
|
|
51
|
+
typeof ((_c = req.headers) === null || _c === void 0 ? void 0 : _c['authorization']) === 'string' &&
|
|
52
|
+
/^Bearer\s/i.test(req.headers['authorization'])) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
const cookie = (_d = req.cookies) === null || _d === void 0 ? void 0 : _d[this.options.cookie.name];
|
|
56
|
+
const headerValue = (_e = req.headers) === null || _e === void 0 ? void 0 : _e[this.options.headerName];
|
|
57
|
+
const header = Array.isArray(headerValue) ? headerValue[0] : headerValue;
|
|
58
|
+
if (!this.tokens.verify(this.options.secret, cookie, header)) {
|
|
59
|
+
throw new nestjs_common_1.ForbiddenAppException({ reason: 'csrf_token_invalid' });
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
issue(res) {
|
|
64
|
+
const token = this.tokens.mint(this.options.secret);
|
|
65
|
+
const { name, ...opts } = this.options.cookie;
|
|
66
|
+
if (typeof res.setCookie === 'function') {
|
|
67
|
+
res.setCookie(name, token, opts);
|
|
68
|
+
}
|
|
69
|
+
else if (typeof res.cookie === 'function') {
|
|
70
|
+
res.cookie(name, token, opts);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this.logger.warn('Unable to issue CSRF cookie: response object exposes neither setCookie nor cookie. ' +
|
|
74
|
+
'Ensure cookie-parser (Express) or @fastify/cookie (Fastify) is registered.');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
exports.DefaultCsrfGuard = DefaultCsrfGuard;
|
|
79
|
+
exports.DefaultCsrfGuard = DefaultCsrfGuard = DefaultCsrfGuard_1 = __decorate([
|
|
80
|
+
(0, common_1.Injectable)(),
|
|
81
|
+
__param(0, (0, common_1.Inject)(csrf_constants_1.CSRF_MODULE_OPTIONS)),
|
|
82
|
+
__metadata("design:paramtypes", [Object, csrf_token_service_1.CsrfTokenService,
|
|
83
|
+
core_1.Reflector])
|
|
84
|
+
], DefaultCsrfGuard);
|
|
85
|
+
//# sourceMappingURL=csrf.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf.guard.js","sourceRoot":"","sources":["../../lib/guard/csrf.guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DefaultCsrfGuard } from './csrf.guard';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultCsrfGuard = void 0;
|
|
4
|
+
var csrf_guard_1 = require("./csrf.guard");
|
|
5
|
+
Object.defineProperty(exports, "DefaultCsrfGuard", { enumerable: true, get: function () { return csrf_guard_1.DefaultCsrfGuard; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/guard/index.ts"],"names":[],"mappings":";;;AAAA,2CAAgD;AAAvC,8GAAA,gBAAgB,OAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { CSRF_MODULE_OPTIONS, SKIP_CSRF_METADATA_KEY } from './constant';
|
|
2
|
+
export { CsrfAsyncModuleOptions, CsrfModule } from './module';
|
|
3
|
+
export { CsrfTokenService, resolveCsrfOptions } from './service';
|
|
4
|
+
export { DefaultCsrfGuard } from './guard';
|
|
5
|
+
export { SkipCsrf } from './decorator';
|
|
6
|
+
export { CsrfCookieOptions, CsrfModuleOptionsFactory, CsrfOptions, CsrfSameSite, ResolvedCsrfOptions, } from './interface';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SkipCsrf = exports.DefaultCsrfGuard = exports.resolveCsrfOptions = exports.CsrfTokenService = exports.CsrfModule = exports.SKIP_CSRF_METADATA_KEY = exports.CSRF_MODULE_OPTIONS = void 0;
|
|
4
|
+
var constant_1 = require("./constant");
|
|
5
|
+
Object.defineProperty(exports, "CSRF_MODULE_OPTIONS", { enumerable: true, get: function () { return constant_1.CSRF_MODULE_OPTIONS; } });
|
|
6
|
+
Object.defineProperty(exports, "SKIP_CSRF_METADATA_KEY", { enumerable: true, get: function () { return constant_1.SKIP_CSRF_METADATA_KEY; } });
|
|
7
|
+
var module_1 = require("./module");
|
|
8
|
+
Object.defineProperty(exports, "CsrfModule", { enumerable: true, get: function () { return module_1.CsrfModule; } });
|
|
9
|
+
var service_1 = require("./service");
|
|
10
|
+
Object.defineProperty(exports, "CsrfTokenService", { enumerable: true, get: function () { return service_1.CsrfTokenService; } });
|
|
11
|
+
Object.defineProperty(exports, "resolveCsrfOptions", { enumerable: true, get: function () { return service_1.resolveCsrfOptions; } });
|
|
12
|
+
var guard_1 = require("./guard");
|
|
13
|
+
Object.defineProperty(exports, "DefaultCsrfGuard", { enumerable: true, get: function () { return guard_1.DefaultCsrfGuard; } });
|
|
14
|
+
var decorator_1 = require("./decorator");
|
|
15
|
+
Object.defineProperty(exports, "SkipCsrf", { enumerable: true, get: function () { return decorator_1.SkipCsrf; } });
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;AAAA,uCAAyE;AAAhE,+GAAA,mBAAmB,OAAA;AAAE,kHAAA,sBAAsB,OAAA;AACpD,mCAA8D;AAA7B,oGAAA,UAAU,OAAA;AAC3C,qCAAiE;AAAxD,2GAAA,gBAAgB,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAC7C,iCAA2C;AAAlC,yGAAA,gBAAgB,OAAA;AACzB,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type CsrfSameSite = 'lax' | 'strict' | 'none';
|
|
2
|
+
export interface CsrfCookieOptions {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
httpOnly: boolean;
|
|
6
|
+
secure: boolean;
|
|
7
|
+
sameSite: CsrfSameSite;
|
|
8
|
+
}
|
|
9
|
+
export interface CsrfOptions {
|
|
10
|
+
secret: string;
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
headerName?: string;
|
|
13
|
+
ignoreMethods?: string[];
|
|
14
|
+
skipWhenBearer?: boolean;
|
|
15
|
+
cookie?: Partial<CsrfCookieOptions>;
|
|
16
|
+
}
|
|
17
|
+
export interface ResolvedCsrfOptions {
|
|
18
|
+
secret: string;
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
headerName: string;
|
|
21
|
+
ignoreMethods: string[];
|
|
22
|
+
skipWhenBearer: boolean;
|
|
23
|
+
cookie: CsrfCookieOptions;
|
|
24
|
+
}
|
|
25
|
+
export interface CsrfModuleOptionsFactory {
|
|
26
|
+
createOptions(): Promise<CsrfOptions> | CsrfOptions;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf-options.interface.js","sourceRoot":"","sources":["../../lib/interface/csrf-options.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CsrfCookieOptions, CsrfModuleOptionsFactory, CsrfOptions, CsrfSameSite, ResolvedCsrfOptions, } from './csrf-options.interface';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/interface/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DynamicModule, ModuleMetadata, Type } from '@nestjs/common';
|
|
2
|
+
import { CsrfModuleOptionsFactory, CsrfOptions } from '../interface/csrf-options.interface';
|
|
3
|
+
export type CsrfAsyncModuleOptions = Pick<ModuleMetadata, 'imports'> & {
|
|
4
|
+
useExisting?: Type<CsrfModuleOptionsFactory>;
|
|
5
|
+
useClass?: Type<CsrfModuleOptionsFactory>;
|
|
6
|
+
useFactory?: (...args: any[]) => Promise<CsrfOptions> | CsrfOptions;
|
|
7
|
+
inject?: any[];
|
|
8
|
+
};
|
|
9
|
+
declare const CsrfModule_base: import("@nathapp/nestjs-common").ConfigurableModuleCls<CsrfOptions, "register", "createOptions", {}>;
|
|
10
|
+
export declare class CsrfModule extends CsrfModule_base {
|
|
11
|
+
static register(options: CsrfOptions): DynamicModule;
|
|
12
|
+
static registerAsync(options: CsrfAsyncModuleOptions): DynamicModule;
|
|
13
|
+
private static withCsrfProviders;
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var CsrfModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CsrfModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const core_1 = require("@nestjs/core");
|
|
13
|
+
const nestjs_common_1 = require("@nathapp/nestjs-common");
|
|
14
|
+
const csrf_constants_1 = require("../constant/csrf.constants");
|
|
15
|
+
const csrf_token_service_1 = require("../service/csrf-token.service");
|
|
16
|
+
const resolve_options_1 = require("../service/resolve-options");
|
|
17
|
+
const csrf_guard_1 = require("../guard/csrf.guard");
|
|
18
|
+
let CsrfModule = CsrfModule_1 = class CsrfModule extends (0, nestjs_common_1.ConfigurableModuleClass)(csrf_constants_1.CSRF_MODULE_OPTIONS) {
|
|
19
|
+
static register(options) {
|
|
20
|
+
(0, resolve_options_1.resolveCsrfOptions)(options);
|
|
21
|
+
const base = super.register(options);
|
|
22
|
+
return CsrfModule_1.withCsrfProviders(base);
|
|
23
|
+
}
|
|
24
|
+
static registerAsync(options) {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
const wrappedAsyncOptions = typeof options.useFactory === 'function'
|
|
27
|
+
? {
|
|
28
|
+
...options,
|
|
29
|
+
useFactory: async (...args) => {
|
|
30
|
+
const resolved = await options.useFactory(...args);
|
|
31
|
+
(0, resolve_options_1.resolveCsrfOptions)(resolved);
|
|
32
|
+
return resolved;
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
: options;
|
|
36
|
+
const base = super.registerAsync(wrappedAsyncOptions);
|
|
37
|
+
return CsrfModule_1.withCsrfProviders(base, {
|
|
38
|
+
imports: (_a = options.imports) !== null && _a !== void 0 ? _a : ((_b = base.imports) !== null && _b !== void 0 ? _b : []),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
static withCsrfProviders(base, overrides = {}) {
|
|
42
|
+
var _a;
|
|
43
|
+
const baseProviders = ((_a = base.providers) !== null && _a !== void 0 ? _a : []);
|
|
44
|
+
return {
|
|
45
|
+
...base,
|
|
46
|
+
module: CsrfModule_1,
|
|
47
|
+
global: true,
|
|
48
|
+
...overrides,
|
|
49
|
+
providers: [
|
|
50
|
+
...baseProviders,
|
|
51
|
+
csrf_token_service_1.CsrfTokenService,
|
|
52
|
+
core_1.Reflector,
|
|
53
|
+
csrf_guard_1.DefaultCsrfGuard,
|
|
54
|
+
{ provide: core_1.APP_GUARD, useExisting: csrf_guard_1.DefaultCsrfGuard },
|
|
55
|
+
],
|
|
56
|
+
exports: [csrf_token_service_1.CsrfTokenService],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
exports.CsrfModule = CsrfModule;
|
|
61
|
+
exports.CsrfModule = CsrfModule = CsrfModule_1 = __decorate([
|
|
62
|
+
(0, common_1.Module)({})
|
|
63
|
+
], CsrfModule);
|
|
64
|
+
//# sourceMappingURL=csrf.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf.module.js","sourceRoot":"","sources":["../../lib/module/csrf.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAMwB;AACxB,uCAAoD;AACpD,0DAAiE;AACjE,+DAAiE;AAEjE,sEAAiE;AACjE,gEAAgE;AAChE,oDAAuD;AAUhD,IAAM,UAAU,kBAAhB,MAAM,UAAW,SAAQ,IAAA,uCAAuB,EACrD,oCAAmB,CACpB;IACC,MAAM,CAAC,QAAQ,CAAC,OAAoB;QAClC,IAAA,oCAAkB,EAAC,OAAO,CAAC,CAAC;QAE5B,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO,YAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,OAA+B;;QAClD,MAAM,mBAAmB,GACvB,OAAO,OAAO,CAAC,UAAU,KAAK,UAAU;YACtC,CAAC,CAAC;gBACE,GAAG,OAAO;gBACV,UAAU,EAAE,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;oBACnC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,UAAW,CAAC,GAAG,IAAI,CAAC,CAAC;oBACpD,IAAA,oCAAkB,EAAC,QAAQ,CAAC,CAAC;oBAC7B,OAAO,QAAQ,CAAC;gBAClB,CAAC;aACF;YACH,CAAC,CAAC,OAAO,CAAC;QAEd,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;QACtD,OAAO,YAAU,CAAC,iBAAiB,CAAC,IAAI,EAAE;YACxC,OAAO,EAAE,MAAA,OAAO,CAAC,OAAO,mCAAI,CAAC,MAAA,IAAI,CAAC,OAAO,mCAAI,EAAE,CAAC;SACjD,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAC9B,IAAmB,EACnB,YAAoC,EAAE;;QAEtC,MAAM,aAAa,GAAG,CAAC,MAAA,IAAI,CAAC,SAAS,mCAAI,EAAE,CAAe,CAAC;QAE3D,OAAO;YACL,GAAG,IAAI;YACP,MAAM,EAAE,YAAU;YAClB,MAAM,EAAE,IAAI;YACZ,GAAG,SAAS;YACZ,SAAS,EAAE;gBACT,GAAG,aAAa;gBAChB,qCAAgB;gBAChB,gBAAS;gBACT,6BAAgB;gBAChB,EAAE,OAAO,EAAE,gBAAS,EAAE,WAAW,EAAE,6BAAgB,EAAE;aACtD;YACD,OAAO,EAAE,CAAC,qCAAgB,CAAC;SAC5B,CAAC;IACJ,CAAC;CACF,CAAA;AAlDY,gCAAU;qBAAV,UAAU;IADtB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,UAAU,CAkDtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CsrfAsyncModuleOptions, CsrfModule } from './csrf.module';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CsrfModule = void 0;
|
|
4
|
+
var csrf_module_1 = require("./csrf.module");
|
|
5
|
+
Object.defineProperty(exports, "CsrfModule", { enumerable: true, get: function () { return csrf_module_1.CsrfModule; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/module/index.ts"],"names":[],"mappings":";;;AAAA,6CAAmE;AAAlC,yGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CsrfTokenService = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const crypto_1 = require("crypto");
|
|
12
|
+
function timingSafeStrEqual(a, b) {
|
|
13
|
+
if (typeof a !== 'string' || typeof b !== 'string')
|
|
14
|
+
return false;
|
|
15
|
+
const aBuf = Buffer.from(a, 'utf8');
|
|
16
|
+
const bBuf = Buffer.from(b, 'utf8');
|
|
17
|
+
if (aBuf.length !== bBuf.length)
|
|
18
|
+
return false;
|
|
19
|
+
return (0, crypto_1.timingSafeEqual)(aBuf, bBuf);
|
|
20
|
+
}
|
|
21
|
+
let CsrfTokenService = class CsrfTokenService {
|
|
22
|
+
mint(secret) {
|
|
23
|
+
const value = (0, crypto_1.randomBytes)(32).toString('hex');
|
|
24
|
+
const sig = (0, crypto_1.createHmac)('sha256', secret).update(value).digest('hex');
|
|
25
|
+
return `${value}.${sig}`;
|
|
26
|
+
}
|
|
27
|
+
verify(secret, cookieValue, headerValue) {
|
|
28
|
+
if (!cookieValue || !headerValue)
|
|
29
|
+
return false;
|
|
30
|
+
if (!timingSafeStrEqual(cookieValue, headerValue))
|
|
31
|
+
return false;
|
|
32
|
+
const dotIndex = cookieValue.indexOf('.');
|
|
33
|
+
if (dotIndex < 0)
|
|
34
|
+
return false;
|
|
35
|
+
const value = cookieValue.slice(0, dotIndex);
|
|
36
|
+
const sig = cookieValue.slice(dotIndex + 1);
|
|
37
|
+
if (!value || !sig)
|
|
38
|
+
return false;
|
|
39
|
+
const expected = (0, crypto_1.createHmac)('sha256', secret).update(value).digest('hex');
|
|
40
|
+
return timingSafeStrEqual(sig, expected);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
exports.CsrfTokenService = CsrfTokenService;
|
|
44
|
+
exports.CsrfTokenService = CsrfTokenService = __decorate([
|
|
45
|
+
(0, common_1.Injectable)()
|
|
46
|
+
], CsrfTokenService);
|
|
47
|
+
//# sourceMappingURL=csrf-token.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf-token.service.js","sourceRoot":"","sources":["../../lib/service/csrf-token.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAC5C,mCAAkE;AAElE,SAAS,kBAAkB,CAAC,CAAS,EAAE,CAAS;IAC9C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACjE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,IAAA,wBAAe,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC;AAGM,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAC3B,IAAI,CAAC,MAAc;QACjB,MAAM,KAAK,GAAG,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrE,OAAO,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,MAAc,EAAE,WAAoB,EAAE,WAAoB;QAC/D,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAC/C,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC;YAAE,OAAO,KAAK,CAAC;QAEhE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,QAAQ,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAE/B,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QAEjC,MAAM,QAAQ,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1E,OAAO,kBAAkB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AArBY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;GACA,gBAAgB,CAqB5B"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveCsrfOptions = exports.CsrfTokenService = void 0;
|
|
4
|
+
var csrf_token_service_1 = require("./csrf-token.service");
|
|
5
|
+
Object.defineProperty(exports, "CsrfTokenService", { enumerable: true, get: function () { return csrf_token_service_1.CsrfTokenService; } });
|
|
6
|
+
var resolve_options_1 = require("./resolve-options");
|
|
7
|
+
Object.defineProperty(exports, "resolveCsrfOptions", { enumerable: true, get: function () { return resolve_options_1.resolveCsrfOptions; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/service/index.ts"],"names":[],"mappings":";;;AAAA,2DAAwD;AAA/C,sHAAA,gBAAgB,OAAA;AACzB,qDAAuD;AAA9C,qHAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveCsrfOptions = resolveCsrfOptions;
|
|
4
|
+
const DEFAULT_COOKIE_NAME = 'csrf-token';
|
|
5
|
+
const DEFAULT_HEADER_NAME = 'x-csrf-token';
|
|
6
|
+
const DEFAULT_IGNORE_METHODS = ['GET', 'HEAD', 'OPTIONS'];
|
|
7
|
+
const DEFAULT_COOKIE_PATH = '/';
|
|
8
|
+
const DEFAULT_COOKIE_HTTP_ONLY = false;
|
|
9
|
+
const DEFAULT_COOKIE_SECURE = true;
|
|
10
|
+
const DEFAULT_COOKIE_SAME_SITE = 'lax';
|
|
11
|
+
function resolveCsrfOptions(options) {
|
|
12
|
+
var _a, _b, _c, _d, _e;
|
|
13
|
+
const { secret, enabled = true, headerName: headerNameOverride = DEFAULT_HEADER_NAME, ignoreMethods: ignoreMethodsOverride, skipWhenBearer = true, cookie: cookieOverrides, } = options;
|
|
14
|
+
if (typeof secret !== 'string' || secret.length === 0) {
|
|
15
|
+
throw new Error('CsrfOptions.secret must be a non-empty string');
|
|
16
|
+
}
|
|
17
|
+
const headerName = headerNameOverride.toLowerCase();
|
|
18
|
+
const ignoreMethods = ignoreMethodsOverride
|
|
19
|
+
? [...ignoreMethodsOverride]
|
|
20
|
+
: [...DEFAULT_IGNORE_METHODS];
|
|
21
|
+
const cookie = {
|
|
22
|
+
name: (_a = cookieOverrides === null || cookieOverrides === void 0 ? void 0 : cookieOverrides.name) !== null && _a !== void 0 ? _a : DEFAULT_COOKIE_NAME,
|
|
23
|
+
path: (_b = cookieOverrides === null || cookieOverrides === void 0 ? void 0 : cookieOverrides.path) !== null && _b !== void 0 ? _b : DEFAULT_COOKIE_PATH,
|
|
24
|
+
httpOnly: (_c = cookieOverrides === null || cookieOverrides === void 0 ? void 0 : cookieOverrides.httpOnly) !== null && _c !== void 0 ? _c : DEFAULT_COOKIE_HTTP_ONLY,
|
|
25
|
+
secure: (_d = cookieOverrides === null || cookieOverrides === void 0 ? void 0 : cookieOverrides.secure) !== null && _d !== void 0 ? _d : DEFAULT_COOKIE_SECURE,
|
|
26
|
+
sameSite: (_e = cookieOverrides === null || cookieOverrides === void 0 ? void 0 : cookieOverrides.sameSite) !== null && _e !== void 0 ? _e : DEFAULT_COOKIE_SAME_SITE,
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
secret,
|
|
30
|
+
enabled,
|
|
31
|
+
headerName,
|
|
32
|
+
ignoreMethods,
|
|
33
|
+
skipWhenBearer,
|
|
34
|
+
cookie,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=resolve-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-options.js","sourceRoot":"","sources":["../../lib/service/resolve-options.ts"],"names":[],"mappings":";;AAUA,gDAoCC;AA5CD,MAAM,mBAAmB,GAAG,YAAY,CAAC;AACzC,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAC3C,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAC1D,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AACvC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AACnC,MAAM,wBAAwB,GAAkC,KAAK,CAAC;AAEtE,SAAgB,kBAAkB,CAAC,OAAoB;;IACrD,MAAM,EACJ,MAAM,EACN,OAAO,GAAG,IAAI,EACd,UAAU,EAAE,kBAAkB,GAAG,mBAAmB,EACpD,aAAa,EAAE,qBAAqB,EACpC,cAAc,GAAG,IAAI,EACrB,MAAM,EAAE,eAAe,GACxB,GAAG,OAAO,CAAC;IAEZ,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,UAAU,GAAG,kBAAkB,CAAC,WAAW,EAAE,CAAC;IAEpD,MAAM,aAAa,GAAG,qBAAqB;QACzC,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC;QAC5B,CAAC,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAsB;QAChC,IAAI,EAAE,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,IAAI,mCAAI,mBAAmB;QAClD,IAAI,EAAE,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,IAAI,mCAAI,mBAAmB;QAClD,QAAQ,EAAE,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,QAAQ,mCAAI,wBAAwB;QAC/D,MAAM,EAAE,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,MAAM,mCAAI,qBAAqB;QACxD,QAAQ,EAAE,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,QAAQ,mCAAI,wBAAwB;KAChE,CAAC;IAEF,OAAO;QACL,MAAM;QACN,OAAO;QACP,UAAU;QACV,aAAa;QACb,cAAc;QACd,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CSRF_MODULE_OPTIONS, SKIP_CSRF_METADATA_KEY } from './csrf.constants';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SkipCsrf } from './skip-csrf.decorator';
|