@gjsify/tls 0.3.20 → 0.4.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/src/index.spec.ts CHANGED
@@ -1,6 +1,8 @@
1
+ // SPDX-License-Identifier: MIT
1
2
  // Ported from refs/node-test/parallel/test-tls-check-server-identity.js,
2
- // test-tls-basic-validations.js, refs/bun/test/js/node/tls/
3
- // Original: MIT license, Node.js contributors
3
+ // test-tls-basic-validations.js, refs/bun/test/js/node/tls/.
4
+ // Original: Copyright (c) Node.js contributors. MIT.
5
+ // Rewritten for @gjsify/unit — behavior preserved, assertion dialect adapted.
4
6
 
5
7
  import { describe, it, expect } from '@gjsify/unit';
6
8
  import tls, {
@@ -15,9 +17,30 @@ import tls, {
15
17
  DEFAULT_MAX_VERSION,
16
18
  DEFAULT_CIPHERS,
17
19
  } from 'node:tls';
18
-
19
- // Our implementation exports TLSServer, Node.js exports Server
20
- const TLSServer = (tls as any).TLSServer || (tls as any).Server;
20
+ import type { PeerCertificate } from 'node:tls';
21
+
22
+ // Build a fake PeerCertificate from minimal fields. Lets us drive
23
+ // `checkServerIdentity` from tests without crafting a real DER cert.
24
+ // `@types/node`'s PeerCertificate has many more fields than we expose; the
25
+ // `as unknown as PeerCertificate` keeps the test free of `as any`.
26
+ function fakeCert(parts: Record<string, unknown>): PeerCertificate {
27
+ return parts as unknown as PeerCertificate;
28
+ }
29
+
30
+ // Our implementation also exports TLSServer; Node only exports Server.
31
+ const tlsRecord = tls as unknown as Record<string, unknown>;
32
+ const TLSServer = (tlsRecord.TLSServer ?? tlsRecord.Server) as new (
33
+ options?: unknown,
34
+ secureConnectionListener?: unknown,
35
+ ) => {
36
+ on: (ev: string, cb: (...a: unknown[]) => void) => unknown;
37
+ emit: (ev: string, ...a: unknown[]) => boolean;
38
+ once: (ev: string, cb: (...a: unknown[]) => void) => unknown;
39
+ addContext: (host: string, ctx: unknown) => void;
40
+ listen: (...a: unknown[]) => unknown;
41
+ close: (cb?: () => void) => unknown;
42
+ address: () => unknown;
43
+ };
21
44
 
22
45
  export default async () => {
23
46
  await describe('tls', async () => {
@@ -93,77 +116,77 @@ export default async () => {
93
116
  // ===================== TLSSocket =====================
94
117
  await describe('TLSSocket', async () => {
95
118
  await it('should be constructable', async () => {
96
- const socket = new TLSSocket(undefined as any);
119
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
97
120
  expect(socket).toBeDefined();
98
121
  });
99
122
 
100
123
  await it('should have encrypted property set to true', async () => {
101
- const socket = new TLSSocket(undefined as any);
124
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
102
125
  expect(socket.encrypted).toBe(true);
103
126
  });
104
127
 
105
128
  await it('should have authorized property as boolean', async () => {
106
- const socket = new TLSSocket(undefined as any);
129
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
107
130
  expect(typeof socket.authorized).toBe('boolean');
108
131
  });
109
132
 
110
133
  await it('authorized should default to false', async () => {
111
- const socket = new TLSSocket(undefined as any);
134
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
112
135
  expect(socket.authorized).toBe(false);
113
136
  });
114
137
 
115
138
  await it('should have getPeerCertificate method', async () => {
116
- const socket = new TLSSocket(undefined as any);
139
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
117
140
  expect(typeof socket.getPeerCertificate).toBe('function');
118
141
  });
119
142
 
120
143
  await it('should have getProtocol method', async () => {
121
- const socket = new TLSSocket(undefined as any);
144
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
122
145
  expect(typeof socket.getProtocol).toBe('function');
123
146
  });
124
147
 
125
148
  await it('should have getCipher method', async () => {
126
- const socket = new TLSSocket(undefined as any);
149
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
127
150
  expect(typeof socket.getCipher).toBe('function');
128
151
  });
129
152
 
130
153
  await it('should have alpnProtocol property', async () => {
131
- const socket = new TLSSocket(undefined as any);
154
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
132
155
  // Node.js: alpnProtocol is a property (null or string), our impl: false or string
133
- const val = (socket as any).alpnProtocol;
156
+ const val = socket.alpnProtocol;
134
157
  expect(val === false || val === null || typeof val === 'string').toBe(true);
135
158
  });
136
159
 
137
160
  await it('getPeerCertificate should return object when not connected', async () => {
138
- const socket = new TLSSocket(undefined as any);
161
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
139
162
  const cert = socket.getPeerCertificate();
140
163
  expect(typeof cert).toBe('object');
141
164
  });
142
165
 
143
166
  await it('getProtocol should return null when not connected', async () => {
144
- const socket = new TLSSocket(undefined as any);
167
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
145
168
  const proto = socket.getProtocol();
146
169
  expect(proto === null || typeof proto === 'string').toBe(true);
147
170
  });
148
171
 
149
172
  await it('getCipher should return null when not connected', async () => {
150
- const socket = new TLSSocket(undefined as any);
173
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
151
174
  const cipher = socket.getCipher();
152
175
  expect(cipher === null || cipher === undefined || typeof cipher === 'object').toBe(true);
153
176
  });
154
177
 
155
178
  await it('alpnProtocol should default to false', async () => {
156
- const socket = new TLSSocket(undefined as any);
157
- expect((socket as any).alpnProtocol === false || (socket as any).alpnProtocol === null).toBe(true);
179
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
180
+ expect(socket.alpnProtocol === false || socket.alpnProtocol === null).toBe(true);
158
181
  });
159
182
 
160
183
  await it('authorizationError should be undefined initially', async () => {
161
- const socket = new TLSSocket(undefined as any);
184
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
162
185
  expect(socket.authorizationError === undefined || socket.authorizationError === null).toBe(true);
163
186
  });
164
187
 
165
188
  await it('should extend Socket (EventEmitter)', async () => {
166
- const socket = new TLSSocket(undefined as any);
189
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
167
190
  expect(typeof socket.on).toBe('function');
168
191
  expect(typeof socket.emit).toBe('function');
169
192
  expect(typeof socket.once).toBe('function');
@@ -171,17 +194,17 @@ export default async () => {
171
194
  });
172
195
 
173
196
  await it('should have destroy method', async () => {
174
- const socket = new TLSSocket(undefined as any);
197
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
175
198
  expect(typeof socket.destroy).toBe('function');
176
199
  });
177
200
 
178
201
  await it('should have write method', async () => {
179
- const socket = new TLSSocket(undefined as any);
202
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
180
203
  expect(typeof socket.write).toBe('function');
181
204
  });
182
205
 
183
206
  await it('should have end method', async () => {
184
- const socket = new TLSSocket(undefined as any);
207
+ const socket = new TLSSocket(undefined as unknown as import("net").Socket);
185
208
  expect(typeof socket.end).toBe('function');
186
209
  });
187
210
  });
@@ -259,7 +282,7 @@ export default async () => {
259
282
 
260
283
  await it('should have context property', async () => {
261
284
  const ctx = createSecureContext();
262
- expect(ctx.context !== undefined).toBe(true);
285
+ expect((ctx as { context?: unknown }).context !== undefined).toBe(true);
263
286
  });
264
287
 
265
288
  await it('should return same type for repeated calls', async () => {
@@ -330,53 +353,53 @@ export default async () => {
330
353
  // --- CN matching ---
331
354
  await describe('CN matching', async () => {
332
355
  await it('should return undefined for exact CN match', async () => {
333
- const result = checkServerIdentity('a.com', { subject: { CN: 'a.com' } } as any);
356
+ const result = checkServerIdentity('a.com', fakeCert({ subject: { CN: 'a.com' } }));
334
357
  expect(result).toBeUndefined();
335
358
  });
336
359
 
337
360
  await it('should match CN case-insensitively', async () => {
338
- const result = checkServerIdentity('a.com', { subject: { CN: 'A.COM' } } as any);
361
+ const result = checkServerIdentity('a.com', fakeCert({ subject: { CN: 'A.COM' } }));
339
362
  expect(result).toBeUndefined();
340
363
  });
341
364
 
342
365
  await it('should return error for non-matching CN', async () => {
343
- const err = checkServerIdentity('a.com', { subject: { CN: 'b.com' } } as any);
366
+ const err = checkServerIdentity('a.com', fakeCert({ subject: { CN: 'b.com' } }));
344
367
  expect(err instanceof Error).toBe(true);
345
368
  });
346
369
 
347
370
  await it('should handle trailing-dot FQDN in hostname', async () => {
348
- const result = checkServerIdentity('a.com.', { subject: { CN: 'a.com' } } as any);
371
+ const result = checkServerIdentity('a.com.', fakeCert({ subject: { CN: 'a.com' } }));
349
372
  expect(result).toBeUndefined();
350
373
  });
351
374
 
352
375
  await it('should handle trailing-dot FQDN in CN', async () => {
353
- const result = checkServerIdentity('a.com', { subject: { CN: 'a.com.' } } as any);
376
+ const result = checkServerIdentity('a.com', fakeCert({ subject: { CN: 'a.com.' } }));
354
377
  expect(result).toBeUndefined();
355
378
  });
356
379
 
357
380
  await it('should handle trailing dots on both sides', async () => {
358
- const result = checkServerIdentity('a.com.', { subject: { CN: 'a.com.' } } as any);
381
+ const result = checkServerIdentity('a.com.', fakeCert({ subject: { CN: 'a.com.' } }));
359
382
  expect(result).toBeUndefined();
360
383
  });
361
384
 
362
385
  await it('should match array CN values', async () => {
363
- const result = checkServerIdentity('b.com', {
386
+ const result = checkServerIdentity('b.com', fakeCert({
364
387
  subject: { CN: ['a.com', 'b.com'] },
365
- } as any);
388
+ }));
366
389
  expect(result).toBeUndefined();
367
390
  });
368
391
 
369
392
  await it('should fail when hostname not in CN array', async () => {
370
- const err = checkServerIdentity('c.com', {
393
+ const err = checkServerIdentity('c.com', fakeCert({
371
394
  subject: { CN: ['a.com', 'b.com'] },
372
- } as any);
395
+ }));
373
396
  expect(err instanceof Error).toBe(true);
374
397
  });
375
398
 
376
399
  await it('should handle single-label hostname with single-label CN', async () => {
377
- const result = checkServerIdentity('localhost', {
400
+ const result = checkServerIdentity('localhost', fakeCert({
378
401
  subject: { CN: 'localhost' },
379
- } as any);
402
+ }));
380
403
  expect(result).toBeUndefined();
381
404
  });
382
405
  });
@@ -384,54 +407,54 @@ export default async () => {
384
407
  // --- Wildcard matching ---
385
408
  await describe('wildcard matching', async () => {
386
409
  await it('should match *.example.com against sub.example.com', async () => {
387
- const result = checkServerIdentity('sub.example.com', {
410
+ const result = checkServerIdentity('sub.example.com', fakeCert({
388
411
  subject: {},
389
412
  subjectaltname: 'DNS:*.example.com',
390
- } as any);
413
+ }));
391
414
  expect(result).toBeUndefined();
392
415
  });
393
416
 
394
417
  await it('should NOT match *.example.com against nested.sub.example.com', async () => {
395
- const err = checkServerIdentity('nested.sub.example.com', {
418
+ const err = checkServerIdentity('nested.sub.example.com', fakeCert({
396
419
  subject: {},
397
420
  subjectaltname: 'DNS:*.example.com',
398
- } as any);
421
+ }));
399
422
  expect(err instanceof Error).toBe(true);
400
423
  });
401
424
 
402
425
  await it('should NOT match *.example.com against example.com itself', async () => {
403
- const err = checkServerIdentity('example.com', {
426
+ const err = checkServerIdentity('example.com', fakeCert({
404
427
  subject: {},
405
428
  subjectaltname: 'DNS:*.example.com',
406
- } as any);
429
+ }));
407
430
  expect(err instanceof Error).toBe(true);
408
431
  });
409
432
 
410
433
  await it('should match wildcard CN when no SANs present', async () => {
411
- const result = checkServerIdentity('foo.example.com', {
434
+ const result = checkServerIdentity('foo.example.com', fakeCert({
412
435
  subject: { CN: '*.example.com' },
413
- } as any);
436
+ }));
414
437
  expect(result).toBeUndefined();
415
438
  });
416
439
 
417
440
  await it('wildcard CN should NOT match two-level deep', async () => {
418
- const err = checkServerIdentity('a.b.example.com', {
441
+ const err = checkServerIdentity('a.b.example.com', fakeCert({
419
442
  subject: { CN: '*.example.com' },
420
- } as any);
443
+ }));
421
444
  expect(err instanceof Error).toBe(true);
422
445
  });
423
446
 
424
447
  await it('should match wildcard with different subdomains', async () => {
425
- const result1 = checkServerIdentity('foo.example.com', {
448
+ const result1 = checkServerIdentity('foo.example.com', fakeCert({
426
449
  subject: {},
427
450
  subjectaltname: 'DNS:*.example.com',
428
- } as any);
451
+ }));
429
452
  expect(result1).toBeUndefined();
430
453
 
431
- const result2 = checkServerIdentity('bar.example.com', {
454
+ const result2 = checkServerIdentity('bar.example.com', fakeCert({
432
455
  subject: {},
433
456
  subjectaltname: 'DNS:*.example.com',
434
- } as any);
457
+ }));
435
458
  expect(result2).toBeUndefined();
436
459
  });
437
460
  });
@@ -439,59 +462,59 @@ export default async () => {
439
462
  // --- DNS SAN matching ---
440
463
  await describe('DNS SAN matching', async () => {
441
464
  await it('should match hostname in DNS SAN', async () => {
442
- const result = checkServerIdentity('foo.example.com', {
465
+ const result = checkServerIdentity('foo.example.com', fakeCert({
443
466
  subject: { CN: 'wrong.com' },
444
467
  subjectaltname: 'DNS:foo.example.com',
445
- } as any);
468
+ }));
446
469
  expect(result).toBeUndefined();
447
470
  });
448
471
 
449
472
  await it('SAN takes precedence over CN', async () => {
450
473
  // When SANs are present, CN should be ignored
451
- const err = checkServerIdentity('wrong.com', {
474
+ const err = checkServerIdentity('wrong.com', fakeCert({
452
475
  subject: { CN: 'wrong.com' },
453
476
  subjectaltname: 'DNS:right.com',
454
- } as any);
477
+ }));
455
478
  expect(err instanceof Error).toBe(true);
456
479
  });
457
480
 
458
481
  await it('should handle multiple DNS SANs', async () => {
459
- const result = checkServerIdentity('b.com', {
482
+ const result = checkServerIdentity('b.com', fakeCert({
460
483
  subject: { CN: 'a.com' },
461
484
  subjectaltname: 'DNS:a.com, DNS:b.com',
462
- } as any);
485
+ }));
463
486
  expect(result).toBeUndefined();
464
487
  });
465
488
 
466
489
  await it('should fail when hostname not in any DNS SAN', async () => {
467
- const err = checkServerIdentity('c.com', {
490
+ const err = checkServerIdentity('c.com', fakeCert({
468
491
  subject: { CN: 'c.com' },
469
492
  subjectaltname: 'DNS:a.com, DNS:b.com',
470
- } as any);
493
+ }));
471
494
  expect(err instanceof Error).toBe(true);
472
495
  });
473
496
 
474
497
  await it('should match wildcard DNS SAN', async () => {
475
- const result = checkServerIdentity('bar.example.com', {
498
+ const result = checkServerIdentity('bar.example.com', fakeCert({
476
499
  subject: { CN: 'wrong.com' },
477
500
  subjectaltname: 'DNS:*.example.com',
478
- } as any);
501
+ }));
479
502
  expect(result).toBeUndefined();
480
503
  });
481
504
 
482
505
  await it('should handle mixed DNS and IP SANs', async () => {
483
- const result = checkServerIdentity('example.com', {
506
+ const result = checkServerIdentity('example.com', fakeCert({
484
507
  subject: {},
485
508
  subjectaltname: 'DNS:example.com, IP Address:1.2.3.4',
486
- } as any);
509
+ }));
487
510
  expect(result).toBeUndefined();
488
511
  });
489
512
 
490
513
  await it('should handle DNS SAN with trailing whitespace', async () => {
491
- const result = checkServerIdentity('example.com', {
514
+ const result = checkServerIdentity('example.com', fakeCert({
492
515
  subject: {},
493
516
  subjectaltname: 'DNS:example.com ',
494
- } as any);
517
+ }));
495
518
  // May or may not match depending on trimming
496
519
  expect(result === undefined || result instanceof Error).toBe(true);
497
520
  });
@@ -500,57 +523,57 @@ export default async () => {
500
523
  // --- IP address matching ---
501
524
  await describe('IP address matching', async () => {
502
525
  await it('should match IPv4 in IP Address SAN', async () => {
503
- const result = checkServerIdentity('8.8.8.8', {
526
+ const result = checkServerIdentity('8.8.8.8', fakeCert({
504
527
  subject: { CN: '8.8.8.8' },
505
528
  subjectaltname: 'IP Address:8.8.8.8',
506
- } as any);
529
+ }));
507
530
  expect(result).toBeUndefined();
508
531
  });
509
532
 
510
533
  await it('should fail IPv4 not in IP Address SAN', async () => {
511
- const err = checkServerIdentity('8.8.4.4', {
534
+ const err = checkServerIdentity('8.8.4.4', fakeCert({
512
535
  subject: { CN: '8.8.4.4' },
513
536
  subjectaltname: 'IP Address:8.8.8.8',
514
- } as any);
537
+ }));
515
538
  expect(err instanceof Error).toBe(true);
516
539
  });
517
540
 
518
541
  await it('should fail IPv4 with only CN (no SAN IP entry)', async () => {
519
- const err = checkServerIdentity('8.8.8.8', {
542
+ const err = checkServerIdentity('8.8.8.8', fakeCert({
520
543
  subject: { CN: '8.8.8.8' },
521
- } as any);
544
+ }));
522
545
  expect(err instanceof Error).toBe(true);
523
546
  });
524
547
 
525
548
  await it('should match multiple IP addresses in SAN', async () => {
526
- const result = checkServerIdentity('1.2.3.4', {
549
+ const result = checkServerIdentity('1.2.3.4', fakeCert({
527
550
  subject: {},
528
551
  subjectaltname: 'IP Address:1.2.3.4, IP Address:5.6.7.8',
529
- } as any);
552
+ }));
530
553
  expect(result).toBeUndefined();
531
554
  });
532
555
 
533
556
  await it('should match second IP in SAN', async () => {
534
- const result = checkServerIdentity('5.6.7.8', {
557
+ const result = checkServerIdentity('5.6.7.8', fakeCert({
535
558
  subject: {},
536
559
  subjectaltname: 'IP Address:1.2.3.4, IP Address:5.6.7.8',
537
- } as any);
560
+ }));
538
561
  expect(result).toBeUndefined();
539
562
  });
540
563
 
541
564
  await it('should handle IPv6 in IP Address SAN', async () => {
542
- const result = checkServerIdentity('::1', {
565
+ const result = checkServerIdentity('::1', fakeCert({
543
566
  subject: {},
544
567
  subjectaltname: 'IP Address:::1',
545
- } as any);
568
+ }));
546
569
  expect(result).toBeUndefined();
547
570
  });
548
571
 
549
572
  await it('should fail IPv4 in DNS SAN (IP should use IP Address SAN)', async () => {
550
- const err = checkServerIdentity('1.2.3.4', {
573
+ const err = checkServerIdentity('1.2.3.4', fakeCert({
551
574
  subject: {},
552
575
  subjectaltname: 'DNS:1.2.3.4',
553
- } as any);
576
+ }));
554
577
  expect(err instanceof Error).toBe(true);
555
578
  });
556
579
  });
@@ -558,33 +581,33 @@ export default async () => {
558
581
  // --- Error object properties ---
559
582
  await describe('error properties', async () => {
560
583
  await it('should have reason property on error', async () => {
561
- const err = checkServerIdentity('a.com', { subject: { CN: 'b.com' } } as any) as any;
584
+ const err = checkServerIdentity('a.com', fakeCert({ subject: { CN: 'b.com' } }));
562
585
  expect(err instanceof Error).toBe(true);
563
- expect(typeof err.reason).toBe('string');
586
+ expect(typeof (err as { reason?: string }).reason).toBe('string');
564
587
  });
565
588
 
566
589
  await it('should have host property on error', async () => {
567
- const err = checkServerIdentity('a.com', { subject: { CN: 'b.com' } } as any) as any;
568
- expect(err.host).toBe('a.com');
590
+ const err = checkServerIdentity('a.com', fakeCert({ subject: { CN: 'b.com' } }));
591
+ expect((err as { host?: string }).host).toBe('a.com');
569
592
  });
570
593
 
571
594
  await it('should have cert property on error', async () => {
572
- const cert = { subject: { CN: 'b.com' } } as any;
573
- const err = checkServerIdentity('a.com', cert) as any;
574
- expect(err.cert).toBe(cert);
595
+ const cert = fakeCert({ subject: { CN: 'b.com' } });
596
+ const err = checkServerIdentity('a.com', cert);
597
+ expect((err as { cert?: unknown } | undefined)?.cert).toBe(cert);
575
598
  });
576
599
 
577
600
  await it('error message should contain hostname for CN mismatch', async () => {
578
- const err = checkServerIdentity('a.com', { subject: { CN: 'b.com' } } as any);
601
+ const err = checkServerIdentity('a.com', fakeCert({ subject: { CN: 'b.com' } }));
579
602
  expect(err instanceof Error).toBe(true);
580
603
  expect((err as Error).message).toContain('a.com');
581
604
  });
582
605
 
583
606
  await it('error message should contain IP for IP mismatch', async () => {
584
- const err = checkServerIdentity('8.8.8.8', {
607
+ const err = checkServerIdentity('8.8.8.8', fakeCert({
585
608
  subject: {},
586
609
  subjectaltname: 'IP Address:1.2.3.4',
587
- } as any);
610
+ }));
588
611
  expect(err instanceof Error).toBe(true);
589
612
  expect((err as Error).message).toContain('8.8.8.8');
590
613
  });
@@ -593,64 +616,64 @@ export default async () => {
593
616
  // --- Edge cases ---
594
617
  await describe('edge cases', async () => {
595
618
  await it('should return error when cert has no subject and no altnames', async () => {
596
- const err = checkServerIdentity('a.com', {} as any);
619
+ const err = checkServerIdentity('a.com', fakeCert({}));
597
620
  expect(err instanceof Error).toBe(true);
598
621
  expect((err as Error).message).toContain('DNS');
599
622
  });
600
623
 
601
624
  await it('should handle false-y host values', async () => {
602
- const err = checkServerIdentity(false as unknown as string, {
625
+ const err = checkServerIdentity(false as unknown as string, fakeCert({
603
626
  subject: { CN: 'a.com' },
604
- } as any);
627
+ }));
605
628
  expect(err instanceof Error).toBe(true);
606
629
  });
607
630
 
608
631
  await it('should handle empty string hostname', async () => {
609
- const err = checkServerIdentity('', { subject: { CN: 'a.com' } } as any);
632
+ const err = checkServerIdentity('', fakeCert({ subject: { CN: 'a.com' } }));
610
633
  expect(err instanceof Error).toBe(true);
611
634
  });
612
635
 
613
636
  await it('should handle empty CN', async () => {
614
- const err = checkServerIdentity('a.com', { subject: { CN: '' } } as any);
637
+ const err = checkServerIdentity('a.com', fakeCert({ subject: { CN: '' } }));
615
638
  expect(err instanceof Error).toBe(true);
616
639
  });
617
640
 
618
641
  await it('should handle undefined CN', async () => {
619
- const err = checkServerIdentity('a.com', { subject: {} } as any);
642
+ const err = checkServerIdentity('a.com', fakeCert({ subject: {} }));
620
643
  expect(err instanceof Error).toBe(true);
621
644
  });
622
645
 
623
646
  await it('should handle empty subjectaltname string', async () => {
624
- const err = checkServerIdentity('a.com', {
647
+ const err = checkServerIdentity('a.com', fakeCert({
625
648
  subject: { CN: 'a.com' },
626
649
  subjectaltname: '',
627
- } as any);
650
+ }));
628
651
  // Empty altname means CN fallback
629
652
  expect(err === undefined || err instanceof Error).toBe(true);
630
653
  });
631
654
 
632
655
  await it('should handle numeric hostname as string', async () => {
633
- const result = checkServerIdentity('127.0.0.1', {
656
+ const result = checkServerIdentity('127.0.0.1', fakeCert({
634
657
  subject: {},
635
658
  subjectaltname: 'IP Address:127.0.0.1',
636
- } as any);
659
+ }));
637
660
  expect(result).toBeUndefined();
638
661
  });
639
662
 
640
663
  await it('should handle cert with only URI SAN (no DNS, no IP)', async () => {
641
- const err = checkServerIdentity('a.com', {
664
+ const err = checkServerIdentity('a.com', fakeCert({
642
665
  subject: {},
643
666
  subjectaltname: 'URI:https://a.com',
644
- } as any);
667
+ }));
645
668
  // URI SANs don't count for hostname verification
646
669
  expect(err instanceof Error).toBe(true);
647
670
  });
648
671
 
649
672
  await it('should handle cert with email SAN only', async () => {
650
- const err = checkServerIdentity('a.com', {
673
+ const err = checkServerIdentity('a.com', fakeCert({
651
674
  subject: {},
652
675
  subjectaltname: 'email:admin@a.com',
653
- } as any);
676
+ }));
654
677
  expect(err instanceof Error).toBe(true);
655
678
  });
656
679
  });