@heavybit/shared-lib 2.1.0 → 2.7.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/README.md +163 -2
- package/dist/cjs/access/index.js +9 -1
- package/dist/cjs/access/index.js.map +1 -1
- package/dist/cjs/approvals/index.js +137 -0
- package/dist/cjs/approvals/index.js.map +1 -0
- package/dist/cjs/audit/index.js +74 -0
- package/dist/cjs/audit/index.js.map +1 -0
- package/dist/cjs/cache/index.js +90 -16
- package/dist/cjs/cache/index.js.map +1 -1
- package/dist/cjs/cache/keyspace.js +101 -0
- package/dist/cjs/cache/keyspace.js.map +1 -0
- package/dist/cjs/common/circuit-breaker.js +74 -0
- package/dist/cjs/common/circuit-breaker.js.map +1 -0
- package/dist/cjs/common/index.js +4 -0
- package/dist/cjs/common/index.js.map +1 -1
- package/dist/cjs/common/internal-client.js +177 -0
- package/dist/cjs/common/internal-client.js.map +1 -0
- package/dist/cjs/common/internal-constants.js +12 -0
- package/dist/cjs/common/internal-constants.js.map +1 -0
- package/dist/cjs/common/internal-service-auth.js +160 -0
- package/dist/cjs/common/internal-service-auth.js.map +1 -0
- package/dist/cjs/common/money.js +215 -0
- package/dist/cjs/common/money.js.map +1 -0
- package/dist/cjs/common/phone.js +41 -22
- package/dist/cjs/common/phone.js.map +1 -1
- package/dist/cjs/common/time.js +28 -2
- package/dist/cjs/common/time.js.map +1 -1
- package/dist/cjs/config/index.js +139 -19
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/contracts/notification-dispatch.js +1 -1
- package/dist/cjs/database/db.js +37 -0
- package/dist/cjs/database/db.js.map +1 -0
- package/dist/cjs/database/index.js +22 -51
- package/dist/cjs/database/index.js.map +1 -1
- package/dist/cjs/database/pagination.js +88 -0
- package/dist/cjs/database/pagination.js.map +1 -0
- package/dist/cjs/database/pool.js +60 -0
- package/dist/cjs/database/pool.js.map +1 -0
- package/dist/cjs/database/scoped-repository.js +132 -0
- package/dist/cjs/database/scoped-repository.js.map +1 -0
- package/dist/cjs/database/scopes.js +166 -0
- package/dist/cjs/database/scopes.js.map +1 -0
- package/dist/cjs/database/table-names.js +14 -0
- package/dist/cjs/database/table-names.js.map +1 -0
- package/dist/cjs/database/tables.js +71 -0
- package/dist/cjs/database/tables.js.map +1 -0
- package/dist/cjs/express/auth.js +64 -50
- package/dist/cjs/express/auth.js.map +1 -1
- package/dist/cjs/express/index.js +2 -0
- package/dist/cjs/express/index.js.map +1 -1
- package/dist/cjs/express/internal-caller.js +52 -0
- package/dist/cjs/express/internal-caller.js.map +1 -0
- package/dist/cjs/express/step-up.js +41 -0
- package/dist/cjs/express/step-up.js.map +1 -0
- package/dist/cjs/http/index.js +3 -71
- package/dist/cjs/http/index.js.map +1 -1
- package/dist/cjs/identity/index.js +269 -67
- package/dist/cjs/identity/index.js.map +1 -1
- package/dist/cjs/identity/step-up.js +52 -0
- package/dist/cjs/identity/step-up.js.map +1 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/knex/columns.js +36 -0
- package/dist/cjs/knex/columns.js.map +1 -0
- package/dist/cjs/knex/index.js +26 -43
- package/dist/cjs/knex/index.js.map +1 -1
- package/dist/cjs/knex/migration-helpers.js +57 -0
- package/dist/cjs/knex/migration-helpers.js.map +1 -0
- package/dist/cjs/logging/redact.js +6 -11
- package/dist/cjs/logging/redact.js.map +1 -1
- package/dist/cjs/messaging/base-consumer.js +36 -0
- package/dist/cjs/messaging/base-consumer.js.map +1 -0
- package/dist/cjs/messaging/consumer.js +142 -73
- package/dist/cjs/messaging/consumer.js.map +1 -1
- package/dist/cjs/messaging/envelope.js +53 -10
- package/dist/cjs/messaging/envelope.js.map +1 -1
- package/dist/cjs/messaging/idempotency.js +95 -8
- package/dist/cjs/messaging/idempotency.js.map +1 -1
- package/dist/cjs/messaging/index.js +2 -1
- package/dist/cjs/messaging/index.js.map +1 -1
- package/dist/cjs/messaging/outbox.js +97 -55
- package/dist/cjs/messaging/outbox.js.map +1 -1
- package/dist/cjs/messaging/publisher.js +86 -38
- package/dist/cjs/messaging/publisher.js.map +1 -1
- package/dist/cjs/messaging/staff-notifier.js +4 -4
- package/dist/cjs/messaging/staff-notifier.js.map +1 -1
- package/dist/cjs/messaging/topology.js +41 -5
- package/dist/cjs/messaging/topology.js.map +1 -1
- package/dist/cjs/rate-limit/index.js +57 -6
- package/dist/cjs/rate-limit/index.js.map +1 -1
- package/dist/cjs/rate-limit/keys.js +47 -0
- package/dist/cjs/rate-limit/keys.js.map +1 -0
- package/dist/cjs/socket/index.js +127 -16
- package/dist/cjs/socket/index.js.map +1 -1
- package/dist/cjs/socket/ticket.js +124 -0
- package/dist/cjs/socket/ticket.js.map +1 -0
- package/dist/cjs/testing/index.js +23 -14
- package/dist/cjs/testing/index.js.map +1 -1
- package/dist/esm/access/index.js +9 -1
- package/dist/esm/access/index.js.map +1 -1
- package/dist/esm/approvals/index.js +127 -0
- package/dist/esm/approvals/index.js.map +1 -0
- package/dist/esm/audit/index.js +70 -0
- package/dist/esm/audit/index.js.map +1 -0
- package/dist/esm/cache/index.js +70 -13
- package/dist/esm/cache/index.js.map +1 -1
- package/dist/esm/cache/keyspace.js +95 -0
- package/dist/esm/cache/keyspace.js.map +1 -0
- package/dist/esm/common/circuit-breaker.js +70 -0
- package/dist/esm/common/circuit-breaker.js.map +1 -0
- package/dist/esm/common/index.js +4 -0
- package/dist/esm/common/index.js.map +1 -1
- package/dist/esm/common/internal-client.js +173 -0
- package/dist/esm/common/internal-client.js.map +1 -0
- package/dist/esm/common/internal-constants.js +9 -0
- package/dist/esm/common/internal-constants.js.map +1 -0
- package/dist/esm/common/internal-service-auth.js +150 -0
- package/dist/esm/common/internal-service-auth.js.map +1 -0
- package/dist/esm/common/money.js +207 -0
- package/dist/esm/common/money.js.map +1 -0
- package/dist/esm/common/phone.js +41 -22
- package/dist/esm/common/phone.js.map +1 -1
- package/dist/esm/common/time.js +27 -2
- package/dist/esm/common/time.js.map +1 -1
- package/dist/esm/config/index.js +135 -18
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/contracts/notification-dispatch.js +1 -1
- package/dist/esm/database/db.js +32 -0
- package/dist/esm/database/db.js.map +1 -0
- package/dist/esm/database/index.js +9 -45
- package/dist/esm/database/index.js.map +1 -1
- package/dist/esm/database/pagination.js +81 -0
- package/dist/esm/database/pagination.js.map +1 -0
- package/dist/esm/database/pool.js +51 -0
- package/dist/esm/database/pool.js.map +1 -0
- package/dist/esm/database/scoped-repository.js +128 -0
- package/dist/esm/database/scoped-repository.js.map +1 -0
- package/dist/esm/database/scopes.js +157 -0
- package/dist/esm/database/scopes.js.map +1 -0
- package/dist/esm/database/table-names.js +11 -0
- package/dist/esm/database/table-names.js.map +1 -0
- package/dist/esm/database/tables.js +61 -0
- package/dist/esm/database/tables.js.map +1 -0
- package/dist/esm/express/auth.js +62 -48
- package/dist/esm/express/auth.js.map +1 -1
- package/dist/esm/express/index.js +2 -0
- package/dist/esm/express/index.js.map +1 -1
- package/dist/esm/express/internal-caller.js +49 -0
- package/dist/esm/express/internal-caller.js.map +1 -0
- package/dist/esm/express/step-up.js +38 -0
- package/dist/esm/express/step-up.js.map +1 -0
- package/dist/esm/http/index.js +3 -70
- package/dist/esm/http/index.js.map +1 -1
- package/dist/esm/identity/index.js +246 -64
- package/dist/esm/identity/index.js.map +1 -1
- package/dist/esm/identity/step-up.js +47 -0
- package/dist/esm/identity/step-up.js.map +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/knex/columns.js +28 -0
- package/dist/esm/knex/columns.js.map +1 -0
- package/dist/esm/knex/index.js +8 -34
- package/dist/esm/knex/index.js.map +1 -1
- package/dist/esm/knex/migration-helpers.js +51 -0
- package/dist/esm/knex/migration-helpers.js.map +1 -0
- package/dist/esm/logging/redact.js +3 -7
- package/dist/esm/logging/redact.js.map +1 -1
- package/dist/esm/messaging/base-consumer.js +32 -0
- package/dist/esm/messaging/base-consumer.js.map +1 -0
- package/dist/esm/messaging/consumer.js +139 -71
- package/dist/esm/messaging/consumer.js.map +1 -1
- package/dist/esm/messaging/envelope.js +50 -10
- package/dist/esm/messaging/envelope.js.map +1 -1
- package/dist/esm/messaging/idempotency.js +91 -7
- package/dist/esm/messaging/idempotency.js.map +1 -1
- package/dist/esm/messaging/index.js +2 -1
- package/dist/esm/messaging/index.js.map +1 -1
- package/dist/esm/messaging/outbox.js +97 -54
- package/dist/esm/messaging/outbox.js.map +1 -1
- package/dist/esm/messaging/publisher.js +86 -38
- package/dist/esm/messaging/publisher.js.map +1 -1
- package/dist/esm/messaging/staff-notifier.js +4 -4
- package/dist/esm/messaging/staff-notifier.js.map +1 -1
- package/dist/esm/messaging/topology.js +39 -4
- package/dist/esm/messaging/topology.js.map +1 -1
- package/dist/esm/rate-limit/index.js +41 -6
- package/dist/esm/rate-limit/index.js.map +1 -1
- package/dist/esm/rate-limit/keys.js +43 -0
- package/dist/esm/rate-limit/keys.js.map +1 -0
- package/dist/esm/socket/index.js +112 -17
- package/dist/esm/socket/index.js.map +1 -1
- package/dist/esm/socket/ticket.js +117 -0
- package/dist/esm/socket/ticket.js.map +1 -0
- package/dist/esm/testing/index.js +24 -15
- package/dist/esm/testing/index.js.map +1 -1
- package/dist/types/access/index.d.ts +9 -3
- package/dist/types/access/index.d.ts.map +1 -1
- package/dist/types/approvals/index.d.ts +99 -0
- package/dist/types/approvals/index.d.ts.map +1 -0
- package/dist/types/audit/index.d.ts +82 -0
- package/dist/types/audit/index.d.ts.map +1 -0
- package/dist/types/cache/index.d.ts +64 -14
- package/dist/types/cache/index.d.ts.map +1 -1
- package/dist/types/cache/keyspace.d.ts +84 -0
- package/dist/types/cache/keyspace.d.ts.map +1 -0
- package/dist/types/common/circuit-breaker.d.ts +51 -0
- package/dist/types/common/circuit-breaker.d.ts.map +1 -0
- package/dist/types/common/index.d.ts +4 -0
- package/dist/types/common/index.d.ts.map +1 -1
- package/dist/types/common/internal-client.d.ts +116 -0
- package/dist/types/common/internal-client.d.ts.map +1 -0
- package/dist/types/common/internal-constants.d.ts +9 -0
- package/dist/types/common/internal-constants.d.ts.map +1 -0
- package/dist/types/common/internal-service-auth.d.ts +102 -0
- package/dist/types/common/internal-service-auth.d.ts.map +1 -0
- package/dist/types/common/money.d.ts +104 -0
- package/dist/types/common/money.d.ts.map +1 -0
- package/dist/types/common/phone.d.ts +25 -15
- package/dist/types/common/phone.d.ts.map +1 -1
- package/dist/types/common/time.d.ts +20 -2
- package/dist/types/common/time.d.ts.map +1 -1
- package/dist/types/config/index.d.ts +251 -27
- package/dist/types/config/index.d.ts.map +1 -1
- package/dist/types/contracts/notification-dispatch.d.ts +13 -13
- package/dist/types/database/db.d.ts +46 -0
- package/dist/types/database/db.d.ts.map +1 -0
- package/dist/types/database/index.d.ts +9 -22
- package/dist/types/database/index.d.ts.map +1 -1
- package/dist/types/database/pagination.d.ts +68 -0
- package/dist/types/database/pagination.d.ts.map +1 -0
- package/dist/types/database/pool.d.ts +39 -0
- package/dist/types/database/pool.d.ts.map +1 -0
- package/dist/types/database/scoped-repository.d.ts +92 -0
- package/dist/types/database/scoped-repository.d.ts.map +1 -0
- package/dist/types/database/scopes.d.ts +159 -0
- package/dist/types/database/scopes.d.ts.map +1 -0
- package/dist/types/database/table-names.d.ts +13 -0
- package/dist/types/database/table-names.d.ts.map +1 -0
- package/dist/types/database/tables.d.ts +748 -0
- package/dist/types/database/tables.d.ts.map +1 -0
- package/dist/types/express/auth.d.ts +40 -24
- package/dist/types/express/auth.d.ts.map +1 -1
- package/dist/types/express/index.d.ts +2 -0
- package/dist/types/express/index.d.ts.map +1 -1
- package/dist/types/express/internal-caller.d.ts +53 -0
- package/dist/types/express/internal-caller.d.ts.map +1 -0
- package/dist/types/express/step-up.d.ts +38 -0
- package/dist/types/express/step-up.d.ts.map +1 -0
- package/dist/types/http/index.d.ts +3 -31
- package/dist/types/http/index.d.ts.map +1 -1
- package/dist/types/identity/index.d.ts +159 -21
- package/dist/types/identity/index.d.ts.map +1 -1
- package/dist/types/identity/step-up.d.ts +41 -0
- package/dist/types/identity/step-up.d.ts.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/knex/columns.d.ts +15 -0
- package/dist/types/knex/columns.d.ts.map +1 -0
- package/dist/types/knex/index.d.ts +3 -11
- package/dist/types/knex/index.d.ts.map +1 -1
- package/dist/types/knex/migration-helpers.d.ts +28 -0
- package/dist/types/knex/migration-helpers.d.ts.map +1 -0
- package/dist/types/logging/redact.d.ts +2 -2
- package/dist/types/logging/redact.d.ts.map +1 -1
- package/dist/types/messaging/base-consumer.d.ts +33 -0
- package/dist/types/messaging/base-consumer.d.ts.map +1 -0
- package/dist/types/messaging/consumer.d.ts +59 -21
- package/dist/types/messaging/consumer.d.ts.map +1 -1
- package/dist/types/messaging/envelope.d.ts +50 -11
- package/dist/types/messaging/envelope.d.ts.map +1 -1
- package/dist/types/messaging/idempotency.d.ts +60 -3
- package/dist/types/messaging/idempotency.d.ts.map +1 -1
- package/dist/types/messaging/index.d.ts +7 -0
- package/dist/types/messaging/index.d.ts.map +1 -1
- package/dist/types/messaging/outbox.d.ts +62 -22
- package/dist/types/messaging/outbox.d.ts.map +1 -1
- package/dist/types/messaging/publisher.d.ts +54 -21
- package/dist/types/messaging/publisher.d.ts.map +1 -1
- package/dist/types/messaging/staff-notifier.d.ts +9 -9
- package/dist/types/messaging/staff-notifier.d.ts.map +1 -1
- package/dist/types/messaging/staff-recipients.d.ts +1 -1
- package/dist/types/messaging/topology.d.ts +40 -8
- package/dist/types/messaging/topology.d.ts.map +1 -1
- package/dist/types/rate-limit/index.d.ts +40 -4
- package/dist/types/rate-limit/index.d.ts.map +1 -1
- package/dist/types/rate-limit/keys.d.ts +52 -0
- package/dist/types/rate-limit/keys.d.ts.map +1 -0
- package/dist/types/socket/index.d.ts +86 -2
- package/dist/types/socket/index.d.ts.map +1 -1
- package/dist/types/socket/ticket.d.ts +90 -0
- package/dist/types/socket/ticket.d.ts.map +1 -0
- package/dist/types/testing/index.d.ts +31 -10
- package/dist/types/testing/index.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +26 -14
- package/dist/types/types/index.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../../src/messaging/publisher.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../../src/messaging/publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,9 +18,9 @@ const index_js_1 = require("../logging/index.js");
|
|
|
18
18
|
* @typeParam C The app's dispatch categories.
|
|
19
19
|
* @typeParam Ch The app's dispatch channels.
|
|
20
20
|
* @example
|
|
21
|
-
* const notifier = new StaffNotifier(outbox, new ConfiguredStaffRecipients({ '
|
|
21
|
+
* const notifier = new StaffNotifier(outbox, new ConfiguredStaffRecipients({ 'jobs.manage': config.opsEmails }),
|
|
22
22
|
* { category: 'staff', defaultChannels: ['email'], logger });
|
|
23
|
-
* await notifier.alert(tx, { template: '
|
|
23
|
+
* await notifier.alert(tx, { template: 'job-failed', permission: 'jobs.manage', data: { reference } }, { correlationId });
|
|
24
24
|
*/
|
|
25
25
|
class StaffNotifier {
|
|
26
26
|
outbox;
|
|
@@ -42,7 +42,7 @@ class StaffNotifier {
|
|
|
42
42
|
*
|
|
43
43
|
* @param executor The caller's open transaction; the commands commit or roll back with it.
|
|
44
44
|
* @param alert Template, permission, variables and optional channels.
|
|
45
|
-
* @param meta Correlation id
|
|
45
|
+
* @param meta Correlation id for tracing; the actor is always the system.
|
|
46
46
|
* @returns How many commands were staged (0 when nobody is configured).
|
|
47
47
|
*/
|
|
48
48
|
async alert(executor, alert, meta = {}) {
|
|
@@ -61,7 +61,7 @@ class StaffNotifier {
|
|
|
61
61
|
bypassPreferences: true,
|
|
62
62
|
targetPermission: alert.permission,
|
|
63
63
|
};
|
|
64
|
-
await this.outbox.command(executor, this.command, dispatch, { ...meta,
|
|
64
|
+
await this.outbox.command(executor, this.command, dispatch, { ...meta, actorUserId: null });
|
|
65
65
|
}
|
|
66
66
|
return targets.length;
|
|
67
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staff-notifier.js","sourceRoot":"","sources":["../../../src/messaging/staff-notifier.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,oFAI+C;AAC/C,kDAAmD;AAsDnD;;;;;;;;;;;;;GAaG;AACH,MAAa,aAAa;IAOL;IACA;IAPF,QAAQ,CAAI;IACZ,eAAe,CAAyB;IACxC,OAAO,CAAS;IAChB,MAAM,CAAS;IAEhC,YACmB,MAAwB,EACxB,UAAkC,EACnD,OAAoC;QAFnB,WAAM,GAAN,MAAM,CAAkB;QACxB,eAAU,GAAV,UAAU,CAAwB;QAGnD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gDAAqB,CAAC;QACxD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,uBAAY,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,KAAK,CAAC,QAAW,EAAE,KAAqB,EAAE,OAAuB,EAAE;QACvE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YACnI,OAAO,CAAC,CAAC;QACX,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAuC;gBACnD,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS;gBACT,QAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;gBACvD,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,gBAAgB,EAAE,KAAK,CAAC,UAAU;aACnC,CAAC;YACF,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"staff-notifier.js","sourceRoot":"","sources":["../../../src/messaging/staff-notifier.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,oFAI+C;AAC/C,kDAAmD;AAsDnD;;;;;;;;;;;;;GAaG;AACH,MAAa,aAAa;IAOL;IACA;IAPF,QAAQ,CAAI;IACZ,eAAe,CAAyB;IACxC,OAAO,CAAS;IAChB,MAAM,CAAS;IAEhC,YACmB,MAAwB,EACxB,UAAkC,EACnD,OAAoC;QAFnB,WAAM,GAAN,MAAM,CAAkB;QACxB,eAAU,GAAV,UAAU,CAAwB;QAGnD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gDAAqB,CAAC;QACxD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,uBAAY,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,KAAK,CAAC,QAAW,EAAE,KAAqB,EAAE,OAAuB,EAAE;QACvE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YACnI,OAAO,CAAC,CAAC;QACX,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAuC;gBACnD,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS;gBACT,QAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;gBACvD,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,iBAAiB,EAAE,IAAI;gBACvB,gBAAgB,EAAE,KAAK,CAAC,UAAU;aACnC,CAAC;YACF,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;CACF;AA7CD,sCA6CC"}
|
|
@@ -1,22 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deadLetterQueueName = exports.retryQueueName = void 0;
|
|
3
|
+
exports.MIN_DELAY_BUCKET_MS = exports.deadLetterQueueName = exports.retryQueueName = void 0;
|
|
4
4
|
exports.createTopology = createTopology;
|
|
5
|
+
exports.delayQueueName = delayQueueName;
|
|
6
|
+
const SEGMENT = /^[a-z0-9][a-z0-9_-]*$/;
|
|
7
|
+
const PURPOSE = /^[a-z0-9][a-z0-9._-]*$/;
|
|
8
|
+
function segment(label, value, pattern = SEGMENT) {
|
|
9
|
+
const v = value.trim();
|
|
10
|
+
if (!pattern.test(v))
|
|
11
|
+
throw new Error(`Topology ${label} must match ${pattern} (got "${value}")`);
|
|
12
|
+
return v;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Builds the naming scheme for one app and environment.
|
|
16
|
+
*
|
|
17
|
+
* @param options App slug and environment prefix.
|
|
18
|
+
* @returns The {@link Topology}.
|
|
19
|
+
* @throws Error when a segment is empty or has other characters.
|
|
20
|
+
* @example const topology = createTopology({ app: config.APP_SLUG, prefix: config.QUEUE_PREFIX });
|
|
21
|
+
*/
|
|
5
22
|
function createTopology(options) {
|
|
6
|
-
const app = options.app
|
|
7
|
-
const prefix = options.prefix
|
|
8
|
-
if (!app || !prefix)
|
|
9
|
-
throw new Error('Topology requires both app and prefix');
|
|
23
|
+
const app = segment('app', options.app);
|
|
24
|
+
const prefix = segment('prefix', options.prefix);
|
|
10
25
|
return {
|
|
11
26
|
app,
|
|
12
27
|
prefix,
|
|
13
28
|
eventsExchange: `${app}.${prefix}.events`,
|
|
14
29
|
commandsExchange: `${app}.${prefix}.commands`,
|
|
15
30
|
queue: (name) => (name.startsWith(`${prefix}.`) ? name : `${prefix}.${name}`),
|
|
31
|
+
queueName: (service, purpose) => `${prefix}.${segment('service', service)}.${segment('purpose', purpose, PURPOSE)}`,
|
|
32
|
+
deadLetterExchange: (service) => `${app}.${prefix}.${segment('service', service)}.dlx`,
|
|
16
33
|
};
|
|
17
34
|
}
|
|
35
|
+
/** Retry queue for one delay: a fixed TTL, dead-lettering back into `queue`. */
|
|
18
36
|
const retryQueueName = (queue, delayMs) => `${queue}.retry.${delayMs}`;
|
|
19
37
|
exports.retryQueueName = retryQueueName;
|
|
38
|
+
/** Dead-letter queue of `queue`. */
|
|
20
39
|
const deadLetterQueueName = (queue) => `${queue}.dlq`;
|
|
21
40
|
exports.deadLetterQueueName = deadLetterQueueName;
|
|
41
|
+
/** Smallest delay bucket for {@link delayQueueName}. */
|
|
42
|
+
exports.MIN_DELAY_BUCKET_MS = 1000;
|
|
43
|
+
/**
|
|
44
|
+
* Delay queue for `scheduleDelayed`: one per power-of-two bucket (1s, 2s, 4s …) at or above `delayMs`.
|
|
45
|
+
* Per-message TTLs only expire at the head of a queue, so bucketing bounds how long a short delay can
|
|
46
|
+
* wait behind a longer one (at most its own bucket size).
|
|
47
|
+
*
|
|
48
|
+
* @param queue Target queue (physical name).
|
|
49
|
+
* @param delayMs Requested delay in milliseconds.
|
|
50
|
+
* @returns `{queue}.delay.{bucketMs}`.
|
|
51
|
+
*/
|
|
52
|
+
function delayQueueName(queue, delayMs) {
|
|
53
|
+
let bucket = exports.MIN_DELAY_BUCKET_MS;
|
|
54
|
+
while (bucket < delayMs)
|
|
55
|
+
bucket *= 2;
|
|
56
|
+
return `${queue}.delay.${bucket}`;
|
|
57
|
+
}
|
|
22
58
|
//# sourceMappingURL=topology.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/messaging/topology.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/messaging/topology.ts"],"names":[],"mappings":";;;AAgDA,wCAYC;AAmBD,wCAIC;AApDD,MAAM,OAAO,GAAG,uBAAuB,CAAC;AACxC,MAAM,OAAO,GAAG,wBAAwB,CAAC;AAEzC,SAAS,OAAO,CAAC,KAAa,EAAE,KAAa,EAAE,OAAO,GAAG,OAAO;IAC9D,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,KAAK,eAAe,OAAO,UAAU,KAAK,IAAI,CAAC,CAAC;IAClG,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAC,OAAwB;IACrD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,OAAO;QACL,GAAG;QACH,MAAM;QACN,cAAc,EAAE,GAAG,GAAG,IAAI,MAAM,SAAS;QACzC,gBAAgB,EAAE,GAAG,GAAG,IAAI,MAAM,WAAW;QAC7C,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;QACrF,SAAS,EAAE,CAAC,OAAe,EAAE,OAAe,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QACnI,kBAAkB,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM;KAC/F,CAAC;AACJ,CAAC;AAED,gFAAgF;AACzE,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,OAAe,EAAE,EAAE,CAAC,GAAG,KAAK,UAAU,OAAO,EAAE,CAAC;AAAjF,QAAA,cAAc,kBAAmE;AAC9F,oCAAoC;AAC7B,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC;AAAxD,QAAA,mBAAmB,uBAAqC;AAErE,wDAAwD;AAC3C,QAAA,mBAAmB,GAAG,IAAI,CAAC;AAExC;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAAC,KAAa,EAAE,OAAe;IAC3D,IAAI,MAAM,GAAG,2BAAmB,CAAC;IACjC,OAAO,MAAM,GAAG,OAAO;QAAE,MAAM,IAAI,CAAC,CAAC;IACrC,OAAO,GAAG,KAAK,UAAU,MAAM,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.limiterKey = void 0;
|
|
3
18
|
exports.createLimiter = createLimiter;
|
|
4
19
|
exports.consumeOrThrow = consumeOrThrow;
|
|
5
20
|
exports.rateLimitMiddleware = rateLimitMiddleware;
|
|
@@ -7,23 +22,49 @@ const rate_limiter_flexible_1 = require("rate-limiter-flexible");
|
|
|
7
22
|
const response_js_1 = require("../common/response.js");
|
|
8
23
|
const errors_js_1 = require("../common/errors.js");
|
|
9
24
|
const index_js_1 = require("../logging/index.js");
|
|
10
|
-
|
|
25
|
+
const keyspace_js_1 = require("../cache/keyspace.js");
|
|
26
|
+
const keys_js_1 = require("./keys.js");
|
|
27
|
+
__exportStar(require("./keys.js"), exports);
|
|
28
|
+
/**
|
|
29
|
+
* Redis limiter with an in-memory insurance limiter so a Redis outage never blocks traffic. Its
|
|
30
|
+
* keys come from the keyspace; pass already-encoded keys (see {@link limiterKey}) to `consume`.
|
|
31
|
+
*
|
|
32
|
+
* @param options Points, window, keyspace and scope.
|
|
33
|
+
* @returns The limiter.
|
|
34
|
+
* @example const limiter = createLimiter({ keyspace: ks, scope: 'sign-in-ip', points: 10, durationSec: 60, redis });
|
|
35
|
+
*/
|
|
11
36
|
function createLimiter(options) {
|
|
12
|
-
const
|
|
37
|
+
const keyPrefix = options.keyspace.key(keys_js_1.RATE_LIMIT_PURPOSE, options.scope);
|
|
38
|
+
const memory = new rate_limiter_flexible_1.RateLimiterMemory({ keyPrefix, points: options.points, duration: options.durationSec, blockDuration: options.blockDurationSec ?? 0 });
|
|
13
39
|
if (!options.redis)
|
|
14
40
|
return memory;
|
|
15
41
|
return new rate_limiter_flexible_1.RateLimiterRedis({
|
|
16
42
|
storeClient: options.redis,
|
|
17
|
-
keyPrefix
|
|
43
|
+
keyPrefix,
|
|
18
44
|
points: options.points,
|
|
19
45
|
duration: options.durationSec,
|
|
20
46
|
blockDuration: options.blockDurationSec ?? 0,
|
|
21
47
|
insuranceLimiter: memory,
|
|
22
48
|
});
|
|
23
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Encodes a raw limiter key (user id, IP …) so it cannot add segments to the limiter's Redis key.
|
|
52
|
+
*
|
|
53
|
+
* @param raw Raw identifier.
|
|
54
|
+
* @returns The encoded key part.
|
|
55
|
+
* @example limiter.consume(limiterKey(req.ip))
|
|
56
|
+
*/
|
|
57
|
+
const limiterKey = (raw) => (0, keyspace_js_1.encodeKeyPart)(raw);
|
|
58
|
+
exports.limiterKey = limiterKey;
|
|
24
59
|
/**
|
|
25
60
|
* Consumes one point for `key`; throws TooManyRequestsError (429) when exhausted.
|
|
26
|
-
* For in-service checks such as per-identifier
|
|
61
|
+
* For in-service checks such as per-identifier sign-in throttling.
|
|
62
|
+
*
|
|
63
|
+
* @param limiter Limiter from {@link createLimiter}.
|
|
64
|
+
* @param key Encoded key (see {@link limiterKey}).
|
|
65
|
+
* @param message Optional public message for the 429.
|
|
66
|
+
* @throws TooManyRequestsError when the limit is exhausted; rethrows limiter failures.
|
|
67
|
+
* @example await consumeOrThrow(limiter, limiterKey(userId));
|
|
27
68
|
*/
|
|
28
69
|
async function consumeOrThrow(limiter, key, message) {
|
|
29
70
|
try {
|
|
@@ -35,13 +76,23 @@ async function consumeOrThrow(limiter, key, message) {
|
|
|
35
76
|
throw rejection;
|
|
36
77
|
}
|
|
37
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Express middleware that consumes one point per request. Sets `X-RateLimit-Limit` and
|
|
81
|
+
* `X-RateLimit-Remaining`; when exhausted answers 429 `RATE_LIMITED` with `Retry-After` (seconds).
|
|
82
|
+
* Fails open: a limiter error (not a rejection) is logged and the request continues.
|
|
83
|
+
*
|
|
84
|
+
* @param options Limiter options and `keyOf` (default user id, else client IP).
|
|
85
|
+
* @returns The middleware.
|
|
86
|
+
* @example router.post('/sessions', rateLimitMiddleware({ keyspace: ks, scope: 'sign-in-ip', points: 10, durationSec: 60, redis }), handler);
|
|
87
|
+
*/
|
|
38
88
|
function rateLimitMiddleware(options) {
|
|
39
89
|
const limiter = createLimiter(options);
|
|
40
90
|
const logger = options.logger ?? index_js_1.silentLogger;
|
|
41
91
|
const keyOf = options.keyOf ?? ((req) => req.user?.id ?? req.ip ?? 'unknown');
|
|
92
|
+
const scope = options.scope;
|
|
42
93
|
return async (req, res, next) => {
|
|
43
94
|
try {
|
|
44
|
-
const result = await limiter.consume(keyOf(req));
|
|
95
|
+
const result = await limiter.consume((0, exports.limiterKey)(keyOf(req)));
|
|
45
96
|
res.setHeader('X-RateLimit-Limit', options.points);
|
|
46
97
|
res.setHeader('X-RateLimit-Remaining', result.remainingPoints);
|
|
47
98
|
next();
|
|
@@ -49,7 +100,7 @@ function rateLimitMiddleware(options) {
|
|
|
49
100
|
catch (rejection) {
|
|
50
101
|
const ms = rejection?.msBeforeNext;
|
|
51
102
|
if (typeof ms !== 'number') {
|
|
52
|
-
logger.error('Rate limiter failure; allowing request', {
|
|
103
|
+
logger.error('Rate limiter failure; allowing request', { scope, error: String(rejection) });
|
|
53
104
|
next();
|
|
54
105
|
return;
|
|
55
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rate-limit/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rate-limit/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RATE_LIMIT_PURPOSE = void 0;
|
|
4
|
+
exports.rateLimitKey = rateLimitKey;
|
|
5
|
+
const index_js_1 = require("../config/index.js");
|
|
6
|
+
const keyspace_js_1 = require("../cache/keyspace.js");
|
|
7
|
+
/**
|
|
8
|
+
* Rate-limit key builder and the sliding-window limiter contract. Dependency-free (exported from the
|
|
9
|
+
* package root as well as `/rate-limit`); the consuming service implements the sliding window.
|
|
10
|
+
*/
|
|
11
|
+
/** Purpose segment for every rate-limit key: `{prefix}rl:{scope}:…`. */
|
|
12
|
+
exports.RATE_LIMIT_PURPOSE = 'rl';
|
|
13
|
+
const SCOPE_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
14
|
+
const DIMENSIONS = ['ip', 'userId', 'email', 'host', 'route'];
|
|
15
|
+
const DIMENSION_SEGMENT = { ip: 'ip', userId: 'user', email: 'email', host: 'host', route: 'route' };
|
|
16
|
+
function dimensionValue(name, raw) {
|
|
17
|
+
const value = raw.trim();
|
|
18
|
+
if (name === 'email')
|
|
19
|
+
return (0, keyspace_js_1.sensitivePart)(value.toLowerCase());
|
|
20
|
+
if (name === 'host')
|
|
21
|
+
return value.toLowerCase();
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Builds `{prefix}rl:{scope}[:ip:{ip}][:user:{id}][:email:{hash}][:host:{host}][:route:{route}]`.
|
|
26
|
+
*
|
|
27
|
+
* @param keyspace The service keyspace.
|
|
28
|
+
* @param input Scope plus at least one dimension.
|
|
29
|
+
* @returns The rate-limit key.
|
|
30
|
+
* @throws ConfigError when no dimension is given or the scope is invalid.
|
|
31
|
+
* @example rateLimitKey(ks, { scope: 'sign-in', ip: req.ip, email: body.email })
|
|
32
|
+
*/
|
|
33
|
+
function rateLimitKey(keyspace, input) {
|
|
34
|
+
if (!SCOPE_PATTERN.test(input.scope))
|
|
35
|
+
throw new index_js_1.ConfigError(`Rate-limit scope "${input.scope}" must be lower-case kebab-case`);
|
|
36
|
+
const parts = [];
|
|
37
|
+
for (const name of DIMENSIONS) {
|
|
38
|
+
const raw = input[name];
|
|
39
|
+
if (raw === undefined || raw.trim() === '')
|
|
40
|
+
continue;
|
|
41
|
+
parts.push(DIMENSION_SEGMENT[name], dimensionValue(name, raw));
|
|
42
|
+
}
|
|
43
|
+
if (!parts.length)
|
|
44
|
+
throw new index_js_1.ConfigError(`Rate-limit key "${input.scope}" needs at least one of ${DIMENSIONS.join(', ')}`);
|
|
45
|
+
return keyspace.key(exports.RATE_LIMIT_PURPOSE, input.scope, ...parts);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/rate-limit/keys.ts"],"names":[],"mappings":";;;AA+CA,oCAUC;AAzDD,iDAAiD;AACjD,sDAA2G;AAE3G;;;GAGG;AAEH,wEAAwE;AAC3D,QAAA,kBAAkB,GAAG,IAAI,CAAC;AAgBvC,MAAM,aAAa,GAAG,4BAA4B,CAAC;AACnD,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAGvE,MAAM,iBAAiB,GAA8B,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAEhI,SAAS,cAAc,CAAC,IAAe,EAAE,GAAW;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,IAAA,2BAAa,EAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAChE,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IAChD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,YAAY,CAAC,QAAuB,EAAE,KAAwB;IAC5E,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,sBAAW,CAAC,qBAAqB,KAAK,CAAC,KAAK,iCAAiC,CAAC,CAAC;IAC/H,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QACrD,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,MAAM,IAAI,sBAAW,CAAC,mBAAmB,KAAK,CAAC,KAAK,2BAA2B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3H,OAAO,QAAQ,CAAC,GAAG,CAAC,0BAAkB,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC;AACjE,CAAC"}
|
package/dist/cjs/socket/index.js
CHANGED
|
@@ -1,27 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.userRoom = void 0;
|
|
4
18
|
exports.createSocketServer = createSocketServer;
|
|
5
19
|
exports.gatewaySocketAuth = gatewaySocketAuth;
|
|
20
|
+
exports.createTicketHandshake = createTicketHandshake;
|
|
21
|
+
exports.createTicketSocketServer = createTicketSocketServer;
|
|
22
|
+
const redis_adapter_1 = require("@socket.io/redis-adapter");
|
|
6
23
|
const socket_io_1 = require("socket.io");
|
|
7
24
|
const index_js_1 = require("../identity/index.js");
|
|
8
25
|
const index_js_2 = require("../logging/index.js");
|
|
26
|
+
const ticket_js_1 = require("./ticket.js");
|
|
27
|
+
__exportStar(require("./ticket.js"), exports);
|
|
28
|
+
/** Name of the private room every connection of `userId` joins. */
|
|
9
29
|
const userRoom = (userId) => `user:${userId}`;
|
|
10
30
|
exports.userRoom = userRoom;
|
|
11
|
-
|
|
12
|
-
|
|
31
|
+
/** Builds the server: authenticate every handshake, then join only server-derived rooms. */
|
|
32
|
+
function buildServer(httpServer, core) {
|
|
33
|
+
const { logger } = core;
|
|
13
34
|
const io = new socket_io_1.Server(httpServer, {
|
|
14
|
-
path:
|
|
15
|
-
cors:
|
|
16
|
-
...(
|
|
17
|
-
...
|
|
35
|
+
path: core.path,
|
|
36
|
+
cors: core.cors,
|
|
37
|
+
...(core.adapter ? { adapter: core.adapter } : {}),
|
|
38
|
+
...core.serverOptions,
|
|
18
39
|
});
|
|
19
40
|
io.use(async (socket, next) => {
|
|
20
41
|
try {
|
|
21
|
-
const
|
|
22
|
-
if (!
|
|
42
|
+
const identity = await core.authenticate(socket);
|
|
43
|
+
if (!identity)
|
|
23
44
|
return next(new Error('Authentication failed'));
|
|
24
|
-
socket.data.
|
|
45
|
+
socket.data.identity = identity;
|
|
25
46
|
next();
|
|
26
47
|
}
|
|
27
48
|
catch (error) {
|
|
@@ -30,11 +51,12 @@ function createSocketServer(httpServer, options) {
|
|
|
30
51
|
}
|
|
31
52
|
});
|
|
32
53
|
io.on('connection', (socket) => {
|
|
33
|
-
const
|
|
34
|
-
const
|
|
54
|
+
const identity = socket.data.identity;
|
|
55
|
+
const userId = core.userIdOf(identity);
|
|
56
|
+
const rooms = core.rooms(identity);
|
|
35
57
|
void socket.join(rooms);
|
|
36
|
-
logger.debug('Socket connected', { userId
|
|
37
|
-
socket.on('disconnect', (reason) => logger.debug('Socket disconnected', { userId
|
|
58
|
+
logger.debug('Socket connected', { userId, rooms });
|
|
59
|
+
socket.on('disconnect', (reason) => logger.debug('Socket disconnected', { userId, reason }));
|
|
38
60
|
});
|
|
39
61
|
return {
|
|
40
62
|
io,
|
|
@@ -43,11 +65,100 @@ function createSocketServer(httpServer, options) {
|
|
|
43
65
|
close: () => new Promise((resolve) => { io.close(() => resolve()); }),
|
|
44
66
|
};
|
|
45
67
|
}
|
|
46
|
-
/**
|
|
47
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Creates a Socket.IO server that authenticates every connection and joins it only to server-derived rooms.
|
|
70
|
+
* The verified user is in `socket.data.identity`.
|
|
71
|
+
*
|
|
72
|
+
* @example const sockets = createSocketServer(httpServer, { path: '/ws', authenticate: gatewaySocketAuth({ secret, protocol }) });
|
|
73
|
+
*/
|
|
74
|
+
function createSocketServer(httpServer, options) {
|
|
75
|
+
return buildServer(httpServer, {
|
|
76
|
+
path: options.path,
|
|
77
|
+
cors: { origin: options.corsOrigins?.length ? options.corsOrigins : false, credentials: true },
|
|
78
|
+
adapter: options.adapter,
|
|
79
|
+
serverOptions: options.serverOptions,
|
|
80
|
+
logger: options.logger ?? index_js_2.silentLogger,
|
|
81
|
+
authenticate: options.authenticate,
|
|
82
|
+
userIdOf: (user) => user.id,
|
|
83
|
+
rooms: options.rooms ?? ((user) => [(0, exports.userRoom)(user.id)]),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Trusts the gateway-signed (v2) identity headers forwarded on the WebSocket upgrade request. The gateway
|
|
88
|
+
* signs the upgrade as `GET <handshake path>` (query ignored).
|
|
89
|
+
*
|
|
90
|
+
* @param options The shared secret (at least 32 characters) and the app's identity protocol.
|
|
91
|
+
* @returns An `authenticate` function for {@link createSocketServer}.
|
|
92
|
+
* @example createSocketServer(server, { path: '/ws', authenticate: gatewaySocketAuth({ secret, protocol }) });
|
|
93
|
+
*/
|
|
94
|
+
function gatewaySocketAuth(options) {
|
|
95
|
+
const secret = (0, index_js_1.assertGatewaySecret)(options.secret);
|
|
48
96
|
return (socket) => {
|
|
49
|
-
const result = (0, index_js_1.
|
|
97
|
+
const result = (0, index_js_1.verifyGatewayIdentity)({
|
|
98
|
+
headers: socket.handshake.headers, method: 'GET', path: socket.handshake.url, secret, protocol: options.protocol,
|
|
99
|
+
});
|
|
50
100
|
return result.status === 'authenticated' ? result.user : null;
|
|
51
101
|
};
|
|
52
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* The handshake check on its own (testable without a server): verifies the ticket from
|
|
105
|
+
* `socket.handshake.auth.ticket`, then the browser origin against `allowedOrigins(claims)`, then
|
|
106
|
+
* single use.
|
|
107
|
+
*
|
|
108
|
+
* @param options Ticket keys, audience, origin rule, replay check and rejection hook.
|
|
109
|
+
* @returns `authenticate(socket)` resolving to the claims, or null when refused.
|
|
110
|
+
*/
|
|
111
|
+
function createTicketHandshake(options) {
|
|
112
|
+
const reject = (reason, userId, origin) => {
|
|
113
|
+
options.onRejected?.({ reason, userId, path: options.path, origin });
|
|
114
|
+
return null;
|
|
115
|
+
};
|
|
116
|
+
return async (socket) => {
|
|
117
|
+
const origin = typeof socket.handshake.headers.origin === 'string' ? socket.handshake.headers.origin : null;
|
|
118
|
+
const auth = (socket.handshake.auth ?? {});
|
|
119
|
+
const result = (0, ticket_js_1.verifySocketTicket)(auth.ticket, options);
|
|
120
|
+
if (!result.ok)
|
|
121
|
+
return reject(result.reason, null, origin);
|
|
122
|
+
const { claims } = result;
|
|
123
|
+
if (origin ? !(await options.allowedOrigins(claims)).includes(origin) : !options.allowMissingOrigin) {
|
|
124
|
+
return reject('origin_not_allowed', claims.userId, origin);
|
|
125
|
+
}
|
|
126
|
+
if (options.isFirstUse && !(await options.isFirstUse(claims)))
|
|
127
|
+
return reject('replayed', claims.userId, origin);
|
|
128
|
+
return claims;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Creates a Socket.IO server whose clients authenticate with a short-lived ticket
|
|
133
|
+
* (`io(url, { path, auth: (cb) => getTicket().then((ticket) => cb({ ticket })) })`). Each connection
|
|
134
|
+
* auto-joins `user:{userId}`; the verified claims are in `socket.data.identity` for later room checks
|
|
135
|
+
* with `canJoinScopeRoom`.
|
|
136
|
+
*
|
|
137
|
+
* @param options HTTP server, path, ticket keys, origin rule, Redis + keyspace, rejection hook.
|
|
138
|
+
* @returns The emitter.
|
|
139
|
+
* @example createTicketSocketServer({ httpServer, path: '/ws', secret, domain, audience: 'admin-app', redis, keyspace, allowedOrigins: () => origins, onRejected })
|
|
140
|
+
*/
|
|
141
|
+
function createTicketSocketServer(options) {
|
|
142
|
+
const { redis, keyspace } = options;
|
|
143
|
+
if (redis && !keyspace)
|
|
144
|
+
throw new Error('createTicketSocketServer: a keyspace is required with redis');
|
|
145
|
+
const isFirstUse = redis && keyspace
|
|
146
|
+
? async (claims) => {
|
|
147
|
+
const ttl = Math.max(1, claims.exp - Math.floor(Date.now() / 1000));
|
|
148
|
+
return (await redis.set(keyspace.key('socket-ticket', claims.jti), '1', 'EX', ttl, 'NX')) === 'OK';
|
|
149
|
+
}
|
|
150
|
+
: undefined;
|
|
151
|
+
const authenticate = createTicketHandshake({ ...options, isFirstUse });
|
|
152
|
+
return buildServer(options.httpServer, {
|
|
153
|
+
path: options.path,
|
|
154
|
+
// Browsers do not apply CORS to WebSocket upgrades; the per-ticket origin check above is the real gate.
|
|
155
|
+
cors: { origin: true, credentials: false },
|
|
156
|
+
adapter: redis && keyspace ? (0, redis_adapter_1.createAdapter)(redis, redis.duplicate(), { key: keyspace.key('socket-io') }) : undefined,
|
|
157
|
+
serverOptions: options.serverOptions,
|
|
158
|
+
logger: options.logger ?? index_js_2.silentLogger,
|
|
159
|
+
authenticate,
|
|
160
|
+
userIdOf: (claims) => claims.userId,
|
|
161
|
+
rooms: (claims) => [(0, exports.userRoom)(claims.userId), ...(options.rooms?.(claims) ?? [])],
|
|
162
|
+
});
|
|
163
|
+
}
|
|
53
164
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/socket/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/socket/index.ts"],"names":[],"mappings":"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"}
|