@nathapp/nestjs-csrf 3.3.0 → 4.0.1

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.
@@ -1,128 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-var-requires */
2
- describe('resolveCsrfOptions defaults', () => {
3
- const resolve = (options: unknown) => {
4
- const mod = require('../lib');
5
- expect(typeof mod.resolveCsrfOptions).toBe('function');
6
- return mod.resolveCsrfOptions(options);
7
- };
8
-
9
- it('AC8: cookie.name defaults to "csrf-token"', () => {
10
- const resolved = resolve({ secret: 's' });
11
- expect(resolved.cookie.name).toBe('csrf-token');
12
- });
13
-
14
- it('AC9: headerName defaults to "x-csrf-token"', () => {
15
- const resolved = resolve({ secret: 's' });
16
- expect(resolved.headerName).toBe('x-csrf-token');
17
- });
18
-
19
- it('AC10: ignoreMethods defaults to ["GET", "HEAD", "OPTIONS"]', () => {
20
- const resolved = resolve({ secret: 's' });
21
- expect(resolved.ignoreMethods).toEqual(['GET', 'HEAD', 'OPTIONS']);
22
- });
23
-
24
- it('AC11: cookie.sameSite defaults to "lax"', () => {
25
- const resolved = resolve({ secret: 's' });
26
- expect(resolved.cookie.sameSite).toBe('lax');
27
- });
28
-
29
- it('AC12: skipWhenBearer defaults to true', () => {
30
- const resolved = resolve({ secret: 's' });
31
- expect(resolved.skipWhenBearer).toBe(true);
32
- });
33
-
34
- it('AC13: enabled defaults to true', () => {
35
- const resolved = resolve({ secret: 's' });
36
- expect(resolved.enabled).toBe(true);
37
- });
38
-
39
- it('cookie.path defaults to "/" when no cookie overrides are provided', () => {
40
- const resolved = resolve({ secret: 's' });
41
- expect(resolved.cookie.path).toBe('/');
42
- });
43
-
44
- it('cookie.httpOnly defaults to false when no cookie overrides are provided', () => {
45
- const resolved = resolve({ secret: 's' });
46
- expect(resolved.cookie.httpOnly).toBe(false);
47
- });
48
-
49
- it('cookie.secure defaults to true when no cookie overrides are provided', () => {
50
- const resolved = resolve({ secret: 's' });
51
- expect(resolved.cookie.secure).toBe(true);
52
- });
53
-
54
- it('headerName override is applied', () => {
55
- const resolved = resolve({ secret: 's', headerName: 'x-custom-csrf' });
56
- expect(resolved.headerName).toBe('x-custom-csrf');
57
- });
58
-
59
- it('ignoreMethods override replaces the default list', () => {
60
- const resolved = resolve({ secret: 's', ignoreMethods: ['POST'] });
61
- expect(resolved.ignoreMethods).toEqual(['POST']);
62
- });
63
-
64
- it('ignoreMethods override produces a fresh array (no shared mutation with caller input)', () => {
65
- const callerInput = ['POST', 'PUT'];
66
- const resolved = resolve({ secret: 's', ignoreMethods: callerInput });
67
- callerInput.push('DELETE');
68
- expect(resolved.ignoreMethods).toEqual(['POST', 'PUT']);
69
- });
70
-
71
- it('enabled: false override is applied', () => {
72
- const resolved = resolve({ secret: 's', enabled: false });
73
- expect(resolved.enabled).toBe(false);
74
- });
75
-
76
- it('skipWhenBearer: false override is applied', () => {
77
- const resolved = resolve({ secret: 's', skipWhenBearer: false });
78
- expect(resolved.skipWhenBearer).toBe(false);
79
- });
80
-
81
- it('partial cookie overrides merge with defaults', () => {
82
- const resolved = resolve({
83
- secret: 's',
84
- cookie: { name: 'my-csrf', sameSite: 'strict' },
85
- });
86
- expect(resolved.cookie.name).toBe('my-csrf');
87
- expect(resolved.cookie.sameSite).toBe('strict');
88
- expect(resolved.cookie.path).toBe('/');
89
- expect(resolved.cookie.httpOnly).toBe(false);
90
- expect(resolved.cookie.secure).toBe(true);
91
- });
92
-
93
- it('empty cookie override object keeps all cookie defaults', () => {
94
- const resolved = resolve({ secret: 's', cookie: {} });
95
- expect(resolved.cookie).toEqual({
96
- name: 'csrf-token',
97
- path: '/',
98
- httpOnly: false,
99
- secure: true,
100
- sameSite: 'lax',
101
- });
102
- });
103
-
104
- it('full cookie override replaces every cookie field', () => {
105
- const resolved = resolve({
106
- secret: 's',
107
- cookie: {
108
- name: 'my-csrf',
109
- path: '/api',
110
- httpOnly: false,
111
- secure: false,
112
- sameSite: 'none',
113
- },
114
- });
115
- expect(resolved.cookie).toEqual({
116
- name: 'my-csrf',
117
- path: '/api',
118
- httpOnly: false,
119
- secure: false,
120
- sameSite: 'none',
121
- });
122
- });
123
-
124
- it('secret is passed through unchanged', () => {
125
- const resolved = resolve({ secret: 'my-very-secret-key' });
126
- expect(resolved.secret).toBe('my-very-secret-key');
127
- });
128
- });
@@ -1,77 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-var-requires */
2
- describe('@SkipCsrf() decorator', () => {
3
- const loadDeps = () => {
4
- const mod = require('../lib');
5
- const { Reflector } = require('@nestjs/core');
6
- return { mod, Reflector };
7
- };
8
-
9
- it('AC15: sets SKIP_CSRF_METADATA_KEY to true on a decorated method handler', () => {
10
- const { mod, Reflector } = loadDeps();
11
- const { SKIP_CSRF_METADATA_KEY, SkipCsrf } = mod;
12
-
13
- expect(typeof SkipCsrf).toBe('function');
14
- expect(SKIP_CSRF_METADATA_KEY).toBeDefined();
15
-
16
- class ProbeController {
17
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
18
- handler(_req: unknown): void {
19
- return;
20
- }
21
- }
22
- const descriptor = Object.getOwnPropertyDescriptor(ProbeController.prototype, 'handler')!;
23
- SkipCsrf()(ProbeController.prototype, 'handler', descriptor);
24
-
25
- const reflector = new Reflector();
26
- const metadata = reflector.get(SKIP_CSRF_METADATA_KEY, ProbeController.prototype.handler);
27
- expect(metadata).toBe(true);
28
- });
29
-
30
- it('AC15 (boundary): does NOT set metadata on handlers that are not decorated', () => {
31
- const { mod, Reflector } = loadDeps();
32
- const { SKIP_CSRF_METADATA_KEY } = mod;
33
-
34
- expect(SKIP_CSRF_METADATA_KEY).toBeDefined();
35
-
36
- class ProbeController {
37
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
38
- undecorated(_req: unknown): void {
39
- return;
40
- }
41
- }
42
-
43
- const reflector = new Reflector();
44
- const metadata = reflector.get(SKIP_CSRF_METADATA_KEY, ProbeController.prototype.undecorated);
45
- expect(metadata).toBeUndefined();
46
- });
47
-
48
- it('AC15 (boundary): SkipCsrf() returns a callable decorator', () => {
49
- const { mod } = loadDeps();
50
- const { SkipCsrf } = mod;
51
-
52
- expect(typeof SkipCsrf).toBe('function');
53
-
54
- const decorator = SkipCsrf();
55
- expect(typeof decorator).toBe('function');
56
- });
57
-
58
- it('AC15 (boundary): SkipCsrf() can be applied at the class level', () => {
59
- const { mod, Reflector } = loadDeps();
60
- const { SKIP_CSRF_METADATA_KEY, SkipCsrf } = mod;
61
-
62
- expect(typeof SkipCsrf).toBe('function');
63
- expect(SKIP_CSRF_METADATA_KEY).toBeDefined();
64
-
65
- class ClassDecoratedController {
66
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
- handler(_req: unknown): void {
68
- return;
69
- }
70
- }
71
- SkipCsrf()(ClassDecoratedController);
72
-
73
- const reflector = new Reflector();
74
- const metadata = reflector.get(SKIP_CSRF_METADATA_KEY, ClassDecoratedController);
75
- expect(metadata).toBe(true);
76
- });
77
- });
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "@nathapp/typescript-config/base.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./lib"
6
- },
7
- "include": ["lib/**/*", "../index.ts", "../test/**/*"],
8
- "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
9
- }