serverless-ircd 0.1.0 → 0.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/.github/workflows/ci.yml +96 -2
- package/.github/workflows/deploy-aws.yml +129 -0
- package/.github/workflows/deploy-cf.yml +0 -2
- package/.gitmodules +3 -0
- package/CHANGELOG.md +436 -0
- package/README.md +127 -84
- package/apps/aws-stack/README.md +73 -0
- package/apps/aws-stack/bin/aws.ts +49 -0
- package/apps/aws-stack/cdk.json +10 -0
- package/apps/aws-stack/package.json +41 -0
- package/apps/aws-stack/scripts/smoke-helpers.d.mts +22 -0
- package/apps/aws-stack/scripts/smoke-helpers.mjs +89 -0
- package/apps/aws-stack/scripts/smoke.mjs +142 -0
- package/apps/aws-stack/src/aws-stack.ts +263 -0
- package/apps/aws-stack/src/tables.ts +10 -0
- package/apps/aws-stack/tests/localstack.test.ts +46 -0
- package/apps/aws-stack/tests/smoke-helpers.test.ts +98 -0
- package/apps/aws-stack/tests/stack.test.ts +464 -0
- package/apps/aws-stack/tsconfig.build.json +11 -0
- package/apps/aws-stack/tsconfig.test.json +8 -0
- package/apps/aws-stack/vitest.config.ts +20 -0
- package/apps/cf-worker/package.json +1 -1
- package/apps/cf-worker/scripts/smoke.mjs +0 -0
- package/apps/cf-worker/src/worker.ts +8 -2
- package/apps/cf-worker/tests/smoke.test.ts +1 -0
- package/apps/cf-worker/wrangler.test.toml +5 -1
- package/apps/cf-worker/wrangler.toml +66 -17
- package/apps/local-cli/package.json +1 -1
- package/apps/local-cli/src/config-loader.ts +57 -0
- package/apps/local-cli/src/main.ts +1 -1
- package/apps/local-cli/src/server.ts +267 -32
- package/apps/local-cli/tests/config-loader.test.ts +107 -0
- package/apps/local-cli/tests/e2e.test.ts +126 -0
- package/apps/local-cli/tests/security-e2e.test.ts +239 -0
- package/biome.json +3 -1
- package/docs/ADR-001-pure-reducers-and-effect-system.md +74 -0
- package/docs/ADR-002-location-of-authority.md +82 -0
- package/docs/ADR-003-durable-object-sharding.md +93 -0
- package/docs/ADR-004-dynamodb-schema.md +96 -0
- package/docs/ADR-005-wss-only-transport-v1.md +83 -0
- package/docs/ADR-006-sasl-mechanism-scope.md +86 -0
- package/docs/ADR-007-deterministic-ports.md +82 -0
- package/docs/ADR-008-monorepo-tooling.md +60 -0
- package/docs/AWS-Adapter-Architecture.md +496 -0
- package/docs/AWS-Deployment.md +1186 -0
- package/docs/Cloudflare-Deployment-Guide.md +660 -0
- package/docs/Home.md +11 -0
- package/docs/Observability.md +87 -0
- package/docs/PlanIRCv3Websocket.md +489 -0
- package/docs/PlanWebClient.md +451 -0
- package/docs/Release-Process.md +443 -0
- package/package.json +19 -14
- package/packages/aws-adapter/README.md +35 -0
- package/packages/aws-adapter/package.json +52 -0
- package/packages/aws-adapter/src/account-store.ts +121 -0
- package/packages/aws-adapter/src/aws-runtime.ts +871 -0
- package/packages/aws-adapter/src/cdk-table-defs.ts +73 -0
- package/packages/aws-adapter/src/config-loader.ts +126 -0
- package/packages/aws-adapter/src/dynamo-account-store.ts +156 -0
- package/packages/aws-adapter/src/dynamo.ts +61 -0
- package/packages/aws-adapter/src/handlers/connect.ts +44 -0
- package/packages/aws-adapter/src/handlers/default.ts +330 -0
- package/packages/aws-adapter/src/handlers/disconnect.ts +48 -0
- package/packages/aws-adapter/src/handlers/index.ts +293 -0
- package/packages/aws-adapter/src/handlers/ping-checker.ts +217 -0
- package/packages/aws-adapter/src/handlers/state.ts +13 -0
- package/packages/aws-adapter/src/handlers/sweeper.ts +84 -0
- package/packages/aws-adapter/src/index.ts +74 -0
- package/packages/aws-adapter/src/message-store.ts +34 -0
- package/packages/aws-adapter/src/serialize.ts +283 -0
- package/packages/aws-adapter/src/tables.ts +53 -0
- package/packages/aws-adapter/tests/account-store-dynamo.test.ts +171 -0
- package/packages/aws-adapter/tests/account-store.test.ts +280 -0
- package/packages/aws-adapter/tests/aws-harness.ts +408 -0
- package/packages/aws-adapter/tests/aws-integration.test.ts +17 -0
- package/packages/aws-adapter/tests/aws-runtime.test.ts +654 -0
- package/packages/aws-adapter/tests/config-loader.test.ts +213 -0
- package/packages/aws-adapter/tests/disconnect-fanout.test.ts +336 -0
- package/packages/aws-adapter/tests/dynamo.test.ts +57 -0
- package/packages/aws-adapter/tests/global-setup.ts +301 -0
- package/packages/aws-adapter/tests/gone-exception.test.ts +271 -0
- package/packages/aws-adapter/tests/handlers.test.ts +473 -0
- package/packages/aws-adapter/tests/message-store.test.ts +55 -0
- package/packages/aws-adapter/tests/ping-checker.test.ts +571 -0
- package/packages/aws-adapter/tests/serialize.test.ts +249 -0
- package/packages/aws-adapter/tests/smoke.test.ts +48 -0
- package/packages/aws-adapter/tests/sweeper.test.ts +420 -0
- package/packages/aws-adapter/tests/tables.test.ts +74 -0
- package/packages/aws-adapter/tests/transactions.test.ts +446 -0
- package/packages/aws-adapter/tsconfig.build.json +16 -0
- package/packages/aws-adapter/tsconfig.test.json +14 -0
- package/packages/aws-adapter/vitest.config.ts +23 -0
- package/packages/cf-adapter/package.json +2 -1
- package/packages/cf-adapter/src/cf-runtime.ts +42 -22
- package/packages/cf-adapter/src/channel-do.ts +40 -1
- package/packages/cf-adapter/src/channel-registry-do.ts +58 -0
- package/packages/cf-adapter/src/config-loader.ts +135 -0
- package/packages/cf-adapter/src/connection-do.ts +119 -0
- package/packages/cf-adapter/src/env.ts +27 -1
- package/packages/cf-adapter/src/index.ts +2 -1
- package/packages/cf-adapter/tests/cf-harness.ts +2 -2
- package/packages/cf-adapter/tests/cf-integration.test.ts +2 -2
- package/packages/cf-adapter/tests/cf-runtime.test.ts +91 -0
- package/packages/cf-adapter/tests/config-loader.test.ts +149 -0
- package/packages/cf-adapter/tests/connection-do.test.ts +82 -0
- package/packages/cf-adapter/tests/worker/main.ts +2 -1
- package/packages/cf-adapter/tests/worker/stubs/channel-stub.ts +7 -1
- package/packages/cf-adapter/wrangler.test.toml +10 -1
- package/packages/in-memory-runtime/package.json +1 -1
- package/packages/in-memory-runtime/src/in-memory-runtime.ts +107 -16
- package/packages/in-memory-runtime/src/index.ts +1 -1
- package/packages/in-memory-runtime/tests/in-memory-runtime.test.ts +134 -0
- package/packages/irc-core/package.json +13 -2
- package/packages/irc-core/src/admission.ts +216 -0
- package/packages/irc-core/src/caps/capabilities.ts +1 -0
- package/packages/irc-core/src/case-fold.ts +64 -0
- package/packages/irc-core/src/cloak.ts +81 -0
- package/packages/irc-core/src/commands/cap.ts +1 -2
- package/packages/irc-core/src/commands/chathistory.ts +305 -0
- package/packages/irc-core/src/commands/index.ts +9 -0
- package/packages/irc-core/src/commands/invite.ts +6 -9
- package/packages/irc-core/src/commands/isupport.ts +1 -1
- package/packages/irc-core/src/commands/join.ts +63 -10
- package/packages/irc-core/src/commands/kick.ts +4 -11
- package/packages/irc-core/src/commands/list.ts +5 -4
- package/packages/irc-core/src/commands/mode.ts +5 -9
- package/packages/irc-core/src/commands/motd-lines.ts +127 -0
- package/packages/irc-core/src/commands/motd.ts +6 -110
- package/packages/irc-core/src/commands/oper.ts +151 -0
- package/packages/irc-core/src/commands/privmsg.ts +24 -0
- package/packages/irc-core/src/commands/registration.ts +79 -21
- package/packages/irc-core/src/commands/sasl.ts +251 -0
- package/packages/irc-core/src/commands/tagmsg.ts +205 -0
- package/packages/irc-core/src/config.ts +270 -0
- package/packages/irc-core/src/flood-control.ts +175 -0
- package/packages/irc-core/src/index.ts +7 -0
- package/packages/irc-core/src/ports.ts +719 -0
- package/packages/irc-core/src/protocol/base64.ts +16 -0
- package/packages/irc-core/src/protocol/index.ts +2 -1
- package/packages/irc-core/src/protocol/numerics.ts +11 -0
- package/packages/irc-core/src/protocol/parser.ts +27 -2
- package/packages/irc-core/src/state/connection.ts +41 -0
- package/packages/irc-core/src/types.ts +88 -2
- package/packages/irc-core/stryker.commands.conf.json +41 -0
- package/packages/irc-core/stryker.protocol.conf.json +26 -0
- package/packages/irc-core/tests/account-store.test.ts +88 -0
- package/packages/irc-core/tests/admission.test.ts +229 -0
- package/packages/irc-core/tests/caps/capabilities.test.ts +22 -0
- package/packages/irc-core/tests/case-fold.test.ts +80 -0
- package/packages/irc-core/tests/cloak.test.ts +78 -0
- package/packages/irc-core/tests/commands/chathistory.test.ts +996 -0
- package/packages/irc-core/tests/commands/join.test.ts +246 -2
- package/packages/irc-core/tests/commands/kick.test.ts +15 -0
- package/packages/irc-core/tests/commands/oper.test.ts +257 -0
- package/packages/irc-core/tests/commands/privmsg.test.ts +146 -2
- package/packages/irc-core/tests/commands/registration.test.ts +380 -20
- package/packages/irc-core/tests/commands/sasl.test.ts +536 -0
- package/packages/irc-core/tests/commands/tagmsg.test.ts +688 -0
- package/packages/irc-core/tests/commands/who.test.ts +22 -4
- package/packages/irc-core/tests/commands/whois.test.ts +8 -1
- package/packages/irc-core/tests/config.test.ts +721 -0
- package/packages/irc-core/tests/flood-control.test.ts +394 -0
- package/packages/irc-core/tests/message-store.test.ts +530 -0
- package/packages/irc-core/tests/parser.test.ts +44 -1
- package/packages/irc-core/tests/ports.test.ts +263 -0
- package/packages/irc-server/package.json +1 -1
- package/packages/irc-server/src/actor.ts +186 -44
- package/packages/irc-server/src/dispatch.ts +89 -5
- package/packages/irc-server/src/index.ts +2 -0
- package/packages/irc-server/src/routing.ts +160 -0
- package/packages/irc-server/tests/actor.test.ts +690 -15
- package/packages/irc-server/tests/dispatch.test.ts +84 -0
- package/packages/irc-server/tests/routing.test.ts +204 -0
- package/packages/irc-test-support/README.md +32 -0
- package/packages/irc-test-support/package.json +37 -0
- package/packages/{cf-adapter/tests/integration → irc-test-support/src}/in-memory-harness.ts +6 -5
- package/packages/irc-test-support/src/index.ts +24 -0
- package/packages/{cf-adapter/tests/integration/harness.test.ts → irc-test-support/tests/in-memory-harness.test.ts} +1 -1
- package/packages/{cf-adapter/tests/integration/scenarios.test.ts → irc-test-support/tests/in-memory-scenarios.test.ts} +1 -2
- package/packages/irc-test-support/tests/smoke.test.ts +11 -0
- package/packages/irc-test-support/tsconfig.build.json +16 -0
- package/packages/irc-test-support/tsconfig.test.json +14 -0
- package/packages/irc-test-support/vitest.config.ts +20 -0
- package/pnpm-workspace.yaml +1 -0
- package/tools/ci-hardening/package.json +30 -0
- package/tools/ci-hardening/src/index.ts +6 -0
- package/tools/ci-hardening/src/validate.ts +103 -0
- package/tools/ci-hardening/tests/__no_thresholds__.txt +11 -0
- package/tools/ci-hardening/tests/__partial_thresholds__.txt +16 -0
- package/tools/ci-hardening/tests/__stryker_bad__.json +4 -0
- package/tools/ci-hardening/tests/validate.test.ts +177 -0
- package/tools/ci-hardening/tsconfig.build.json +12 -0
- package/tools/ci-hardening/tsconfig.test.json +10 -0
- package/tools/ci-hardening/vitest.config.ts +21 -0
- package/tools/seed-aws-accounts.ts +80 -0
- package/tools/tcp-ws-forwarder/package.json +1 -1
- package/tools/tcp-ws-forwarder/src/forwarder.ts +34 -23
- package/tools/tcp-ws-forwarder/src/logger.ts +155 -0
- package/tools/tcp-ws-forwarder/src/main.ts +33 -14
- package/tools/tcp-ws-forwarder/tests/forwarder.test.ts +86 -0
- package/tools/tcp-ws-forwarder/tests/logger.test.ts +136 -0
- package/packages/cf-adapter/tests/integration/index.ts +0 -17
- /package/packages/{cf-adapter/tests/integration → irc-test-support/src}/harness.ts +0 -0
- /package/packages/{cf-adapter/tests/integration → irc-test-support/src}/scenarios.ts +0 -0
|
@@ -18,6 +18,7 @@ describe('SUPPORTED_CAPABILITIES', () => {
|
|
|
18
18
|
'away-notify',
|
|
19
19
|
'batch',
|
|
20
20
|
'chghost',
|
|
21
|
+
'draft/chathistory',
|
|
21
22
|
'echo-message',
|
|
22
23
|
'extended-join',
|
|
23
24
|
'invite-notify',
|
|
@@ -73,6 +74,10 @@ describe('isSupportedCap', () => {
|
|
|
73
74
|
expect(isSupportedCap('safelist')).toBe(true);
|
|
74
75
|
});
|
|
75
76
|
|
|
77
|
+
it('returns true for draft/chathistory (bare name, no value)', () => {
|
|
78
|
+
expect(isSupportedCap('draft/chathistory')).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
|
|
76
81
|
it('returns false for an unknown cap name', () => {
|
|
77
82
|
expect(isSupportedCap('does-not-exist')).toBe(false);
|
|
78
83
|
});
|
|
@@ -111,6 +116,23 @@ describe('getLsString', () => {
|
|
|
111
116
|
});
|
|
112
117
|
});
|
|
113
118
|
|
|
119
|
+
describe('draft/chathistory advertisement', () => {
|
|
120
|
+
it('is advertised as a bare name (no value parameter)', () => {
|
|
121
|
+
const cap = SUPPORTED_CAPABILITIES.find((c) => c.name === 'draft/chathistory');
|
|
122
|
+
expect(cap).toBeDefined();
|
|
123
|
+
expect(cap?.value).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('appears in CAP LS output as the bare token', () => {
|
|
127
|
+
expect(getLsString()).toContain('draft/chathistory');
|
|
128
|
+
expect(getLsString()).not.toContain('draft/chathistory=');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('is ACKable via SUPPORTED_CAP_NAMES membership (CAP REQ round-trip)', () => {
|
|
132
|
+
expect(SUPPORTED_CAP_NAMES.has('draft/chathistory')).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
114
136
|
describe('splitCapsForWire', () => {
|
|
115
137
|
it('returns a single chunk when everything fits', () => {
|
|
116
138
|
const tokens = ['a', 'b', 'c'];
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import fc from 'fast-check';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { type CaseMapping, caseFold } from '../src/case-fold';
|
|
4
|
+
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// caseFold — rfc1459 special-character folding
|
|
7
|
+
// ============================================================================
|
|
8
|
+
|
|
9
|
+
describe('caseFold — rfc1459', () => {
|
|
10
|
+
it('folds [Foo] to {foo}', () => {
|
|
11
|
+
expect(caseFold('rfc1459', '[Foo]')).toBe('{foo}');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('folds uppercase A–Z to a–z', () => {
|
|
15
|
+
expect(caseFold('rfc1459', 'ABCXYZ')).toBe('abcxyz');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('folds the four rfc1459 specials [ \\ ] ^ to { | } ~', () => {
|
|
19
|
+
expect(caseFold('rfc1459', '[\\]^')).toBe('{|}~');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('does not fold { | } ~ any further', () => {
|
|
23
|
+
expect(caseFold('rfc1459', '{|}~')).toBe('{|}~');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('leaves non-folding characters unchanged', () => {
|
|
27
|
+
expect(caseFold('rfc1459', 'a1_-.#@')).toBe('a1_-.#@');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('returns the empty string unchanged', () => {
|
|
31
|
+
expect(caseFold('rfc1459', '')).toBe('');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// caseFold — ascii mapping (strict subset of rfc1459)
|
|
37
|
+
// ============================================================================
|
|
38
|
+
|
|
39
|
+
describe('caseFold — ascii', () => {
|
|
40
|
+
it('folds uppercase A–Z to a–z', () => {
|
|
41
|
+
expect(caseFold('ascii', 'ABCXYZ')).toBe('abcxyz');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('does NOT fold the rfc1459 specials [ \\ ] ^', () => {
|
|
45
|
+
expect(caseFold('ascii', '[Foo]')).toBe('[foo]');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('leaves non-folding characters unchanged', () => {
|
|
49
|
+
expect(caseFold('ascii', 'a1_-.#[]')).toBe('a1_-.#[]');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// caseFold — idempotency (property test)
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
describe('caseFold — idempotency', () => {
|
|
58
|
+
const mappings: CaseMapping[] = ['rfc1459', 'ascii'];
|
|
59
|
+
|
|
60
|
+
for (const mapping of mappings) {
|
|
61
|
+
it(`fold(fold(s)) === fold(s) under ${mapping}`, () => {
|
|
62
|
+
const nickish = fc.stringMatching(/[\x21-\x7e]{0,16}/u);
|
|
63
|
+
fc.assert(
|
|
64
|
+
fc.property(nickish, (s) => {
|
|
65
|
+
const once = caseFold(mapping, s);
|
|
66
|
+
expect(caseFold(mapping, once)).toBe(once);
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
it('rfc1459 and ascii agree on pure A–Z / a–z input', () => {
|
|
73
|
+
const alpha = fc.stringMatching(/^[A-Za-z]{1,16}$/u);
|
|
74
|
+
fc.assert(
|
|
75
|
+
fc.property(alpha, (s) => {
|
|
76
|
+
expect(caseFold('rfc1459', s)).toBe(caseFold('ascii', s));
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { cloakHost } from '../src/cloak';
|
|
3
|
+
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// cloakHost — basic deterministic cloaking
|
|
6
|
+
// ============================================================================
|
|
7
|
+
|
|
8
|
+
describe('cloakHost — determinism', () => {
|
|
9
|
+
it('returns the same cloak for the same IP + secret', () => {
|
|
10
|
+
const a = cloakHost('203.0.113.5', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
11
|
+
const b = cloakHost('203.0.113.5', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
12
|
+
expect(a).toBe(b);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns different cloaks for different IPs with the same secret', () => {
|
|
16
|
+
const a = cloakHost('203.0.113.5', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
17
|
+
const b = cloakHost('198.51.100.7', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
18
|
+
expect(a).not.toBe(b);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('returns different cloaks for the same IP with different secrets', () => {
|
|
22
|
+
const a = cloakHost('203.0.113.5', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
23
|
+
const b = cloakHost('203.0.113.5', { enabled: true, secret: 'other' }, 'irc.example.com');
|
|
24
|
+
expect(a).not.toBe(b);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// cloakHost — format
|
|
30
|
+
// ============================================================================
|
|
31
|
+
|
|
32
|
+
describe('cloakHost — format', () => {
|
|
33
|
+
it('produces a cloak ending in the configured suffix', () => {
|
|
34
|
+
const cloak = cloakHost('203.0.113.5', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
35
|
+
expect(cloak.endsWith('.irc.example.com')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('produces a cloak whose leading segment is a stable hex-encoded hash', () => {
|
|
39
|
+
const cloak = cloakHost('203.0.113.5', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
40
|
+
// Strip the suffix, leaving just the hash segment.
|
|
41
|
+
const segment = cloak.slice(0, cloak.indexOf('.'));
|
|
42
|
+
expect(segment).toMatch(/^[a-z0-9]+$/u);
|
|
43
|
+
expect(segment.length).toBeGreaterThanOrEqual(8);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('produces a cloak no longer than 63 bytes per label (DNS limit)', () => {
|
|
47
|
+
const cloak = cloakHost('203.0.113.5', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
48
|
+
for (const label of cloak.split('.')) {
|
|
49
|
+
expect(label.length).toBeLessThanOrEqual(63);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// cloakHost — disabled
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
describe('cloakHost — disabled', () => {
|
|
59
|
+
it('returns the original host when cloaking is disabled', () => {
|
|
60
|
+
const cloak = cloakHost('203.0.113.5', { enabled: false, secret: 's3cret' }, 'irc.example.com');
|
|
61
|
+
expect(cloak).toBe('203.0.113.5');
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// cloakHost — IPv6
|
|
67
|
+
// ============================================================================
|
|
68
|
+
|
|
69
|
+
describe('cloakHost — IPv6', () => {
|
|
70
|
+
it('cloaks an IPv6 address the same way as an IPv4 address', () => {
|
|
71
|
+
const cloak = cloakHost('2001:db8::1', { enabled: true, secret: 's3cret' }, 'irc.example.com');
|
|
72
|
+
expect(cloak.endsWith('.irc.example.com')).toBe(true);
|
|
73
|
+
// Re-cloaking deterministically yields the same value.
|
|
74
|
+
expect(cloakHost('2001:db8::1', { enabled: true, secret: 's3cret' }, 'irc.example.com')).toBe(
|
|
75
|
+
cloak,
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
});
|