@verdaccio/auth 8.0.0-next-8.2 → 8.0.0-next-8.4
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 +28 -0
- package/build/auth.d.ts +3 -2
- package/build/auth.js +7 -7
- package/build/auth.js.map +1 -1
- package/package.json +10 -10
- package/src/auth.ts +9 -7
- package/test/auth-utils-middleware.spec.ts +260 -0
- package/test/auth-utils.spec.ts +18 -210
- package/test/auth.spec.ts +55 -54
- package/jest.config.js +0 -10
package/test/auth.spec.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import supertest from 'supertest';
|
|
4
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
4
5
|
|
|
5
6
|
import { Config as AppConfig, ROLES, createRemoteUser, getDefaultConfig } from '@verdaccio/config';
|
|
6
7
|
import {
|
|
@@ -27,9 +28,9 @@ import {
|
|
|
27
28
|
setup({});
|
|
28
29
|
|
|
29
30
|
// to avoid flaky test generate same ramdom key
|
|
30
|
-
|
|
31
|
+
vi.mock('@verdaccio/utils', async (importOriginal) => {
|
|
31
32
|
return {
|
|
32
|
-
...
|
|
33
|
+
...(await importOriginal<typeof import('@verdaccio/utils')>()),
|
|
33
34
|
// used by enhanced legacy aes signature (minimum 32 characters)
|
|
34
35
|
generateRandomSecretKey: () => 'GCYW/3IJzQI6GvPmy9sbMkFoiL7QLVw',
|
|
35
36
|
// used by legacy aes signature
|
|
@@ -44,7 +45,7 @@ describe('AuthTest', () => {
|
|
|
44
45
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
45
46
|
config.checkSecretKey('12345');
|
|
46
47
|
|
|
47
|
-
const auth: Auth = new Auth(config);
|
|
48
|
+
const auth: Auth = new Auth(config, logger);
|
|
48
49
|
await auth.init();
|
|
49
50
|
expect(auth).toBeDefined();
|
|
50
51
|
});
|
|
@@ -53,7 +54,7 @@ describe('AuthTest', () => {
|
|
|
53
54
|
const config: Config = new AppConfig({ ...authProfileConf, auth: undefined });
|
|
54
55
|
config.checkSecretKey('12345');
|
|
55
56
|
|
|
56
|
-
const auth: Auth = new Auth(config);
|
|
57
|
+
const auth: Auth = new Auth(config, logger);
|
|
57
58
|
await auth.init();
|
|
58
59
|
expect(auth).toBeDefined();
|
|
59
60
|
});
|
|
@@ -67,7 +68,7 @@ describe('AuthTest', () => {
|
|
|
67
68
|
});
|
|
68
69
|
config.checkSecretKey('12345');
|
|
69
70
|
|
|
70
|
-
const auth: Auth = new Auth(config);
|
|
71
|
+
const auth: Auth = new Auth(config, logger);
|
|
71
72
|
await auth.init();
|
|
72
73
|
expect(auth).toBeDefined();
|
|
73
74
|
});
|
|
@@ -78,11 +79,11 @@ describe('AuthTest', () => {
|
|
|
78
79
|
test('should be a success login', async () => {
|
|
79
80
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
80
81
|
config.checkSecretKey('12345');
|
|
81
|
-
const auth: Auth = new Auth(config);
|
|
82
|
+
const auth: Auth = new Auth(config, logger);
|
|
82
83
|
await auth.init();
|
|
83
84
|
expect(auth).toBeDefined();
|
|
84
85
|
|
|
85
|
-
const callback =
|
|
86
|
+
const callback = vi.fn();
|
|
86
87
|
const groups = ['test'];
|
|
87
88
|
|
|
88
89
|
auth.authenticate('foo', 'bar', callback);
|
|
@@ -105,11 +106,11 @@ describe('AuthTest', () => {
|
|
|
105
106
|
test('should be a fail on login', async () => {
|
|
106
107
|
const config: Config = new AppConfig(authPluginFailureConf);
|
|
107
108
|
config.checkSecretKey('12345');
|
|
108
|
-
const auth: Auth = new Auth(config);
|
|
109
|
+
const auth: Auth = new Auth(config, logger);
|
|
109
110
|
await auth.init();
|
|
110
111
|
expect(auth).toBeDefined();
|
|
111
112
|
|
|
112
|
-
const callback =
|
|
113
|
+
const callback = vi.fn();
|
|
113
114
|
|
|
114
115
|
auth.authenticate('foo', 'bar', callback);
|
|
115
116
|
expect(callback).toHaveBeenCalledTimes(1);
|
|
@@ -124,11 +125,11 @@ describe('AuthTest', () => {
|
|
|
124
125
|
test('should skip falsy values', async () => {
|
|
125
126
|
const config: Config = new AppConfig({ ...authPluginPassThrougConf });
|
|
126
127
|
config.checkSecretKey('12345');
|
|
127
|
-
const auth: Auth = new Auth(config);
|
|
128
|
+
const auth: Auth = new Auth(config, logger);
|
|
128
129
|
await auth.init();
|
|
129
130
|
expect(auth).toBeDefined();
|
|
130
131
|
|
|
131
|
-
const callback =
|
|
132
|
+
const callback = vi.fn();
|
|
132
133
|
let index = 0;
|
|
133
134
|
|
|
134
135
|
// as defined by https://developer.mozilla.org/en-US/docs/Glossary/Falsy
|
|
@@ -144,11 +145,11 @@ describe('AuthTest', () => {
|
|
|
144
145
|
test('should error truthy non-array', async () => {
|
|
145
146
|
const config: Config = new AppConfig({ ...authPluginPassThrougConf });
|
|
146
147
|
config.checkSecretKey('12345');
|
|
147
|
-
const auth: Auth = new Auth(config);
|
|
148
|
+
const auth: Auth = new Auth(config, logger);
|
|
148
149
|
await auth.init();
|
|
149
150
|
expect(auth).toBeDefined();
|
|
150
151
|
|
|
151
|
-
const callback =
|
|
152
|
+
const callback = vi.fn();
|
|
152
153
|
|
|
153
154
|
for (const value of [true, 1, 'test', {}]) {
|
|
154
155
|
expect(function () {
|
|
@@ -162,11 +163,11 @@ describe('AuthTest', () => {
|
|
|
162
163
|
test('should skip empty array', async () => {
|
|
163
164
|
const config: Config = new AppConfig({ ...authPluginPassThrougConf });
|
|
164
165
|
config.checkSecretKey('12345');
|
|
165
|
-
const auth: Auth = new Auth(config);
|
|
166
|
+
const auth: Auth = new Auth(config, logger);
|
|
166
167
|
await auth.init();
|
|
167
168
|
expect(auth).toBeDefined();
|
|
168
169
|
|
|
169
|
-
const callback =
|
|
170
|
+
const callback = vi.fn();
|
|
170
171
|
const value = [];
|
|
171
172
|
|
|
172
173
|
// @ts-ignore
|
|
@@ -179,11 +180,11 @@ describe('AuthTest', () => {
|
|
|
179
180
|
test('should accept valid array', async () => {
|
|
180
181
|
const config: Config = new AppConfig({ ...authPluginPassThrougConf });
|
|
181
182
|
config.checkSecretKey('12345');
|
|
182
|
-
const auth: Auth = new Auth(config);
|
|
183
|
+
const auth: Auth = new Auth(config, logger);
|
|
183
184
|
await auth.init();
|
|
184
185
|
expect(auth).toBeDefined();
|
|
185
186
|
|
|
186
|
-
const callback =
|
|
187
|
+
const callback = vi.fn();
|
|
187
188
|
let index = 0;
|
|
188
189
|
|
|
189
190
|
for (const value of [[''], ['1'], ['0'], ['000']]) {
|
|
@@ -207,7 +208,7 @@ describe('AuthTest', () => {
|
|
|
207
208
|
},
|
|
208
209
|
});
|
|
209
210
|
config.checkSecretKey('12345');
|
|
210
|
-
const auth: Auth = new Auth(config);
|
|
211
|
+
const auth: Auth = new Auth(config, logger);
|
|
211
212
|
await auth.init();
|
|
212
213
|
|
|
213
214
|
return new Promise((resolve) => {
|
|
@@ -228,10 +229,10 @@ describe('AuthTest', () => {
|
|
|
228
229
|
test('should fail if the plugin does not provide implementation', async () => {
|
|
229
230
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
230
231
|
config.checkSecretKey('12345');
|
|
231
|
-
const auth: Auth = new Auth(config);
|
|
232
|
+
const auth: Auth = new Auth(config, logger);
|
|
232
233
|
await auth.init();
|
|
233
234
|
expect(auth).toBeDefined();
|
|
234
|
-
const callback =
|
|
235
|
+
const callback = vi.fn();
|
|
235
236
|
|
|
236
237
|
auth.changePassword('foo', 'bar', 'newFoo', callback);
|
|
237
238
|
|
|
@@ -243,11 +244,11 @@ describe('AuthTest', () => {
|
|
|
243
244
|
test('should handle plugin does provide implementation', async () => {
|
|
244
245
|
const config: Config = new AppConfig({ ...authChangePasswordConf });
|
|
245
246
|
config.checkSecretKey('12345');
|
|
246
|
-
const auth: Auth = new Auth(config);
|
|
247
|
+
const auth: Auth = new Auth(config, logger);
|
|
247
248
|
await auth.init();
|
|
248
249
|
expect(auth).toBeDefined();
|
|
249
|
-
const callback =
|
|
250
|
-
auth.add_user('foo', 'bar',
|
|
250
|
+
const callback = vi.fn();
|
|
251
|
+
auth.add_user('foo', 'bar', vi.fn());
|
|
251
252
|
auth.changePassword('foo', 'bar', 'newFoo', callback);
|
|
252
253
|
expect(callback).toHaveBeenCalledTimes(1);
|
|
253
254
|
expect(callback).toHaveBeenCalledWith(null, true);
|
|
@@ -261,11 +262,11 @@ describe('AuthTest', () => {
|
|
|
261
262
|
test('should fails if groups do not match exactly', async () => {
|
|
262
263
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
263
264
|
config.checkSecretKey('12345');
|
|
264
|
-
const auth: Auth = new Auth(config);
|
|
265
|
+
const auth: Auth = new Auth(config, logger);
|
|
265
266
|
await auth.init();
|
|
266
267
|
expect(auth).toBeDefined();
|
|
267
268
|
|
|
268
|
-
const callback =
|
|
269
|
+
const callback = vi.fn();
|
|
269
270
|
const groups = ['test'];
|
|
270
271
|
|
|
271
272
|
auth.allow_access(
|
|
@@ -283,11 +284,11 @@ describe('AuthTest', () => {
|
|
|
283
284
|
test('should success if groups do not match exactly', async () => {
|
|
284
285
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
285
286
|
config.checkSecretKey('12345');
|
|
286
|
-
const auth: Auth = new Auth(config);
|
|
287
|
+
const auth: Auth = new Auth(config, logger);
|
|
287
288
|
await auth.init();
|
|
288
289
|
expect(auth).toBeDefined();
|
|
289
290
|
|
|
290
|
-
const callback =
|
|
291
|
+
const callback = vi.fn();
|
|
291
292
|
// $all comes from configuration file
|
|
292
293
|
const groups = [ROLES.$ALL];
|
|
293
294
|
|
|
@@ -310,11 +311,11 @@ describe('AuthTest', () => {
|
|
|
310
311
|
test('should fails if groups do not match exactly', async () => {
|
|
311
312
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
312
313
|
config.checkSecretKey('12345');
|
|
313
|
-
const auth: Auth = new Auth(config);
|
|
314
|
+
const auth: Auth = new Auth(config, logger);
|
|
314
315
|
await auth.init();
|
|
315
316
|
expect(auth).toBeDefined();
|
|
316
317
|
|
|
317
|
-
const callback =
|
|
318
|
+
const callback = vi.fn();
|
|
318
319
|
const groups = ['test'];
|
|
319
320
|
|
|
320
321
|
auth.allow_publish(
|
|
@@ -332,11 +333,11 @@ describe('AuthTest', () => {
|
|
|
332
333
|
test('should success if groups do match exactly', async () => {
|
|
333
334
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
334
335
|
config.checkSecretKey('12345');
|
|
335
|
-
const auth: Auth = new Auth(config);
|
|
336
|
+
const auth: Auth = new Auth(config, logger);
|
|
336
337
|
await auth.init();
|
|
337
338
|
expect(auth).toBeDefined();
|
|
338
339
|
|
|
339
|
-
const callback =
|
|
340
|
+
const callback = vi.fn();
|
|
340
341
|
// $all comes from configuration file
|
|
341
342
|
const groups = [ROLES.$AUTH];
|
|
342
343
|
|
|
@@ -357,11 +358,11 @@ describe('AuthTest', () => {
|
|
|
357
358
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
358
359
|
config.checkSecretKey('12345');
|
|
359
360
|
|
|
360
|
-
const auth: Auth = new Auth(config);
|
|
361
|
+
const auth: Auth = new Auth(config, logger);
|
|
361
362
|
await auth.init();
|
|
362
363
|
expect(auth).toBeDefined();
|
|
363
364
|
|
|
364
|
-
const callback =
|
|
365
|
+
const callback = vi.fn();
|
|
365
366
|
const groups = ['test'];
|
|
366
367
|
|
|
367
368
|
auth.allow_unpublish(
|
|
@@ -391,11 +392,11 @@ describe('AuthTest', () => {
|
|
|
391
392
|
},
|
|
392
393
|
});
|
|
393
394
|
config.checkSecretKey('12345');
|
|
394
|
-
const auth: Auth = new Auth(config);
|
|
395
|
+
const auth: Auth = new Auth(config, logger);
|
|
395
396
|
await auth.init();
|
|
396
397
|
expect(auth).toBeDefined();
|
|
397
398
|
|
|
398
|
-
const callback =
|
|
399
|
+
const callback = vi.fn();
|
|
399
400
|
const groups = ['test'];
|
|
400
401
|
|
|
401
402
|
auth.allow_unpublish(
|
|
@@ -414,11 +415,11 @@ describe('AuthTest', () => {
|
|
|
414
415
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
415
416
|
|
|
416
417
|
config.checkSecretKey('12345');
|
|
417
|
-
const auth: Auth = new Auth(config);
|
|
418
|
+
const auth: Auth = new Auth(config, logger);
|
|
418
419
|
await auth.init();
|
|
419
420
|
expect(auth).toBeDefined();
|
|
420
421
|
|
|
421
|
-
const callback =
|
|
422
|
+
const callback = vi.fn();
|
|
422
423
|
// $all comes from configuration file
|
|
423
424
|
const groups = [ROLES.$AUTH];
|
|
424
425
|
|
|
@@ -441,11 +442,11 @@ describe('AuthTest', () => {
|
|
|
441
442
|
test('should fails with bad password if adduser is not implemented', async () => {
|
|
442
443
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
443
444
|
config.checkSecretKey('12345');
|
|
444
|
-
const auth: Auth = new Auth(config);
|
|
445
|
+
const auth: Auth = new Auth(config, logger);
|
|
445
446
|
await auth.init();
|
|
446
447
|
expect(auth).toBeDefined();
|
|
447
448
|
|
|
448
|
-
const callback =
|
|
449
|
+
const callback = vi.fn();
|
|
449
450
|
|
|
450
451
|
auth.add_user('juan', 'password', callback);
|
|
451
452
|
|
|
@@ -464,11 +465,11 @@ describe('AuthTest', () => {
|
|
|
464
465
|
},
|
|
465
466
|
});
|
|
466
467
|
config.checkSecretKey('12345');
|
|
467
|
-
const auth: Auth = new Auth(config);
|
|
468
|
+
const auth: Auth = new Auth(config, logger);
|
|
468
469
|
await auth.init();
|
|
469
470
|
expect(auth).toBeDefined();
|
|
470
471
|
|
|
471
|
-
const callback =
|
|
472
|
+
const callback = vi.fn();
|
|
472
473
|
|
|
473
474
|
// note: fail uas username make plugin fails
|
|
474
475
|
auth.add_user('fail', 'password', callback);
|
|
@@ -488,11 +489,11 @@ describe('AuthTest', () => {
|
|
|
488
489
|
},
|
|
489
490
|
});
|
|
490
491
|
config.checkSecretKey('12345');
|
|
491
|
-
const auth: Auth = new Auth(config);
|
|
492
|
+
const auth: Auth = new Auth(config, logger);
|
|
492
493
|
await auth.init();
|
|
493
494
|
expect(auth).toBeDefined();
|
|
494
495
|
|
|
495
|
-
const callback =
|
|
496
|
+
const callback = vi.fn();
|
|
496
497
|
|
|
497
498
|
// note: fail uas username make plugin fails
|
|
498
499
|
auth.add_user('skip', 'password', callback);
|
|
@@ -512,11 +513,11 @@ describe('AuthTest', () => {
|
|
|
512
513
|
},
|
|
513
514
|
});
|
|
514
515
|
config.checkSecretKey('12345');
|
|
515
|
-
const auth: Auth = new Auth(config);
|
|
516
|
+
const auth: Auth = new Auth(config, logger);
|
|
516
517
|
await auth.init();
|
|
517
518
|
expect(auth).toBeDefined();
|
|
518
519
|
|
|
519
|
-
const callback =
|
|
520
|
+
const callback = vi.fn();
|
|
520
521
|
|
|
521
522
|
auth.add_user('something', 'password', callback);
|
|
522
523
|
|
|
@@ -536,11 +537,11 @@ describe('AuthTest', () => {
|
|
|
536
537
|
},
|
|
537
538
|
});
|
|
538
539
|
config.checkSecretKey('12345');
|
|
539
|
-
const auth: Auth = new Auth(config);
|
|
540
|
+
const auth: Auth = new Auth(config, logger);
|
|
540
541
|
await auth.init();
|
|
541
542
|
expect(auth).toBeDefined();
|
|
542
543
|
|
|
543
|
-
const callback =
|
|
544
|
+
const callback = vi.fn();
|
|
544
545
|
|
|
545
546
|
auth.add_user('something', 'password', callback);
|
|
546
547
|
|
|
@@ -582,7 +583,7 @@ describe('AuthTest', () => {
|
|
|
582
583
|
test('should handle invalid auth token', async () => {
|
|
583
584
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
584
585
|
config.checkSecretKey(secret);
|
|
585
|
-
const auth = new Auth(config);
|
|
586
|
+
const auth = new Auth(config, logger);
|
|
586
587
|
await auth.init();
|
|
587
588
|
const app = await getServer(auth);
|
|
588
589
|
return supertest(app)
|
|
@@ -594,7 +595,7 @@ describe('AuthTest', () => {
|
|
|
594
595
|
test('should handle missing auth header', async () => {
|
|
595
596
|
const config: Config = new AppConfig({ ...authProfileConf });
|
|
596
597
|
config.checkSecretKey(secret);
|
|
597
|
-
const auth = new Auth(config);
|
|
598
|
+
const auth = new Auth(config, logger);
|
|
598
599
|
await auth.init();
|
|
599
600
|
const app = await getServer(auth);
|
|
600
601
|
return supertest(app).get(`/`).expect(HTTP_STATUS.OK);
|
|
@@ -609,7 +610,7 @@ describe('AuthTest', () => {
|
|
|
609
610
|
// intended to force key generator (associated with mocks above)
|
|
610
611
|
// 64 characters secret long
|
|
611
612
|
config.checkSecretKey('35fabdd29b820d39125e76e6d85cc294');
|
|
612
|
-
const auth = new Auth(config);
|
|
613
|
+
const auth = new Auth(config, logger);
|
|
613
614
|
await auth.init();
|
|
614
615
|
const token = auth.aesEncrypt(payload) as string;
|
|
615
616
|
const app = await getServer(auth);
|
|
@@ -625,7 +626,7 @@ describe('AuthTest', () => {
|
|
|
625
626
|
const config: Config = new AppConfig({ ...authPluginFailureConf });
|
|
626
627
|
// intended to force key generator (associated with mocks above)
|
|
627
628
|
config.checkSecretKey(undefined);
|
|
628
|
-
const auth = new Auth(config);
|
|
629
|
+
const auth = new Auth(config, logger);
|
|
629
630
|
await auth.init();
|
|
630
631
|
const token = auth.aesEncrypt(payload) as string;
|
|
631
632
|
const app = await getServer(auth);
|
|
@@ -645,7 +646,7 @@ describe('AuthTest', () => {
|
|
|
645
646
|
...{ security: { api: { jwt: { sign: { expiresIn: '29d' } } } } },
|
|
646
647
|
});
|
|
647
648
|
config.checkSecretKey(secret);
|
|
648
|
-
const auth = new Auth(config);
|
|
649
|
+
const auth = new Auth(config, logger);
|
|
649
650
|
await auth.init();
|
|
650
651
|
const app = await getServer(auth);
|
|
651
652
|
const res = await supertest(app)
|
|
@@ -667,7 +668,7 @@ describe('AuthTest', () => {
|
|
|
667
668
|
...{ security: { api: { jwt: { sign: { expiresIn: '29d' } } } } },
|
|
668
669
|
});
|
|
669
670
|
config.checkSecretKey(secret);
|
|
670
|
-
const auth = new Auth(config);
|
|
671
|
+
const auth = new Auth(config, logger);
|
|
671
672
|
await auth.init();
|
|
672
673
|
const app = await getServer(auth);
|
|
673
674
|
const res = await supertest(app).get(`/`).expect(HTTP_STATUS.OK);
|
|
@@ -690,7 +691,7 @@ describe('AuthTest', () => {
|
|
|
690
691
|
);
|
|
691
692
|
// intended to force key generator (associated with mocks above)
|
|
692
693
|
config.checkSecretKey(undefined);
|
|
693
|
-
const auth = new Auth(config);
|
|
694
|
+
const auth = new Auth(config, logger);
|
|
694
695
|
await auth.init();
|
|
695
696
|
const token = (await auth.jwtEncrypt(
|
|
696
697
|
createRemoteUser('jwt_user', [ROLES.ALL]),
|