@serfab/cadre-core 0.8.1 → 0.10.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 +6 -4
- package/dist/bootstrap-peer-store-file.d.ts +13 -0
- package/dist/bootstrap-peer-store-file.js +42 -0
- package/dist/bootstrap-peer-store-file.js.map +1 -0
- package/dist/bootstrap-peer-store.d.ts +73 -0
- package/dist/bootstrap-peer-store.js +128 -0
- package/dist/bootstrap-peer-store.js.map +1 -0
- package/dist/cadre-node.d.ts +1006 -101
- package/dist/cadre-node.js +1977 -283
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-authorization.d.ts +93 -0
- package/dist/control-authorization.js +57 -0
- package/dist/control-authorization.js.map +1 -0
- package/dist/control-cohort.d.ts +15 -15
- package/dist/control-cohort.js +14 -14
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +1033 -76
- package/dist/control-database.js +1520 -153
- package/dist/control-database.js.map +1 -1
- package/dist/control-formation-recorder.d.ts +91 -12
- package/dist/control-formation-recorder.js +131 -16
- package/dist/control-formation-recorder.js.map +1 -1
- package/dist/control-schema.d.ts +1 -1
- package/dist/control-schema.js +774 -186
- package/dist/control-schema.js.map +1 -1
- package/dist/control-stream.d.ts +38 -4
- package/dist/control-stream.js +70 -4
- package/dist/control-stream.js.map +1 -1
- package/dist/control-write-retry.d.ts +151 -0
- package/dist/control-write-retry.js +411 -0
- package/dist/control-write-retry.js.map +1 -0
- package/dist/delegate-admission.d.ts +134 -0
- package/dist/delegate-admission.js +244 -0
- package/dist/delegate-admission.js.map +1 -0
- package/dist/device-token.d.ts +12 -12
- package/dist/device-token.js +15 -14
- package/dist/device-token.js.map +1 -1
- package/dist/ed25519-key.d.ts +68 -0
- package/dist/ed25519-key.js +106 -0
- package/dist/ed25519-key.js.map +1 -0
- package/dist/file-durable-slot.d.ts +20 -0
- package/dist/file-durable-slot.js +53 -0
- package/dist/file-durable-slot.js.map +1 -0
- package/dist/formation-approval.d.ts +157 -0
- package/dist/formation-approval.js +375 -0
- package/dist/formation-approval.js.map +1 -0
- package/dist/fs-atomic.d.ts +38 -0
- package/dist/fs-atomic.js +97 -0
- package/dist/fs-atomic.js.map +1 -0
- package/dist/identity-key.d.ts +49 -0
- package/dist/identity-key.js +81 -0
- package/dist/identity-key.js.map +1 -0
- package/dist/index.d.ts +16 -6
- package/dist/index.js +44 -10
- package/dist/index.js.map +1 -1
- package/dist/key-store-file.d.ts +2 -24
- package/dist/key-store-file.js +10 -77
- package/dist/key-store-file.js.map +1 -1
- package/dist/key-store.d.ts +1 -1
- package/dist/key-store.js +1 -1
- package/dist/membership-connection-gater.d.ts +146 -0
- package/dist/membership-connection-gater.js +180 -0
- package/dist/membership-connection-gater.js.map +1 -0
- package/dist/node-local-snapshot.d.ts +109 -0
- package/dist/node-local-snapshot.js +182 -0
- package/dist/node-local-snapshot.js.map +1 -0
- package/dist/peer-authorization.d.ts +150 -11
- package/dist/peer-authorization.js +170 -13
- package/dist/peer-authorization.js.map +1 -1
- package/dist/peer-record.d.ts +24 -11
- package/dist/peer-record.js +29 -13
- package/dist/peer-record.js.map +1 -1
- package/dist/push-node.d.ts +38 -0
- package/dist/push-node.js +48 -0
- package/dist/push-node.js.map +1 -0
- package/dist/push-notifier-apns.d.ts +10 -2
- package/dist/push-notifier-apns.js +14 -10
- package/dist/push-notifier-apns.js.map +1 -1
- package/dist/push-notifier-fcm.d.ts +7 -1
- package/dist/push-notifier-fcm.js +9 -10
- package/dist/push-notifier-fcm.js.map +1 -1
- package/dist/push-notifier.d.ts +16 -35
- package/dist/push-notifier.js +16 -44
- package/dist/push-notifier.js.map +1 -1
- package/dist/relay-addrs.d.ts +45 -0
- package/dist/relay-addrs.js +103 -0
- package/dist/relay-addrs.js.map +1 -0
- package/dist/relay-reservation.d.ts +266 -0
- package/dist/relay-reservation.js +613 -0
- package/dist/relay-reservation.js.map +1 -0
- package/dist/seed-bootstrap.d.ts +263 -79
- package/dist/seed-bootstrap.js +413 -211
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/seed-trust-policy.d.ts +50 -24
- package/dist/seed-trust-policy.js +28 -19
- package/dist/seed-trust-policy.js.map +1 -1
- package/dist/strand-addr-protocol.d.ts +42 -13
- package/dist/strand-addr-protocol.js +58 -52
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-backfill.d.ts +109 -0
- package/dist/strand-backfill.js +279 -0
- package/dist/strand-backfill.js.map +1 -0
- package/dist/strand-database.d.ts +5 -5
- package/dist/strand-database.js +4 -4
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-formation-manager.d.ts +38 -9
- package/dist/strand-formation-manager.js +120 -17
- package/dist/strand-formation-manager.js.map +1 -1
- package/dist/strand-formation-protocol.d.ts +104 -5
- package/dist/strand-formation-protocol.js +233 -5
- package/dist/strand-formation-protocol.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +40 -2
- package/dist/strand-instance-manager.js +93 -15
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-member-key.d.ts +6 -6
- package/dist/strand-member-key.js +6 -6
- package/dist/strand-member-key.js.map +1 -1
- package/dist/strand-member-registry.d.ts +12 -12
- package/dist/strand-member-registry.js +22 -14
- package/dist/strand-member-registry.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +532 -138
- package/dist/strand-membership-writer.js +800 -179
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-solicitation.d.ts +99 -33
- package/dist/strand-solicitation.js +100 -52
- package/dist/strand-solicitation.js.map +1 -1
- package/dist/strand-transport-key.d.ts +40 -0
- package/dist/strand-transport-key.js +56 -0
- package/dist/strand-transport-key.js.map +1 -0
- package/dist/strand-wake-protocol.d.ts +9 -7
- package/dist/strand-wake-protocol.js +22 -46
- package/dist/strand-wake-protocol.js.map +1 -1
- package/dist/strand-watcher.d.ts +17 -2
- package/dist/strand-watcher.js +47 -3
- package/dist/strand-watcher.js.map +1 -1
- package/dist/trusted-owner-store-file.d.ts +12 -0
- package/dist/trusted-owner-store-file.js +39 -0
- package/dist/trusted-owner-store-file.js.map +1 -0
- package/dist/trusted-owner-store.d.ts +64 -0
- package/dist/trusted-owner-store.js +126 -0
- package/dist/trusted-owner-store.js.map +1 -0
- package/dist/types.d.ts +325 -50
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -1
- package/package.json +23 -8
- package/src/bootstrap-peer-store-file.ts +44 -0
- package/src/bootstrap-peer-store.ts +172 -0
- package/src/cadre-node.ts +2129 -295
- package/src/control-authorization.ts +114 -0
- package/src/control-cohort.ts +17 -17
- package/src/control-database.ts +1766 -191
- package/src/control-formation-recorder.ts +174 -21
- package/src/control-schema.ts +786 -198
- package/src/control-stream.ts +81 -4
- package/src/control-write-retry.ts +473 -0
- package/src/delegate-admission.ts +302 -0
- package/src/device-token.ts +19 -14
- package/src/ed25519-key.ts +134 -0
- package/src/file-durable-slot.ts +61 -0
- package/src/formation-approval.ts +604 -0
- package/src/fs-atomic.ts +107 -0
- package/src/identity-key.ts +109 -0
- package/src/index.ts +157 -24
- package/src/key-store-file.ts +10 -81
- package/src/key-store.ts +1 -1
- package/src/membership-connection-gater.ts +204 -0
- package/src/node-local-snapshot.ts +260 -0
- package/src/peer-authorization.ts +219 -13
- package/src/peer-record.ts +31 -13
- package/src/push-node.ts +64 -0
- package/src/push-notifier-apns.ts +16 -12
- package/src/push-notifier-fcm.ts +9 -10
- package/src/push-notifier.ts +16 -57
- package/src/relay-addrs.ts +111 -0
- package/src/relay-reservation.ts +823 -0
- package/src/seed-bootstrap.ts +490 -226
- package/src/seed-trust-policy.ts +65 -32
- package/src/strand-addr-protocol.ts +84 -53
- package/src/strand-backfill.ts +366 -0
- package/src/strand-database.ts +6 -6
- package/src/strand-formation-manager.ts +145 -19
- package/src/strand-formation-protocol.ts +310 -9
- package/src/strand-instance-manager.ts +113 -16
- package/src/strand-member-key.ts +7 -7
- package/src/strand-member-registry.ts +28 -23
- package/src/strand-membership-writer.ts +1430 -640
- package/src/strand-solicitation.ts +155 -90
- package/src/strand-transport-key.ts +58 -0
- package/src/strand-wake-protocol.ts +29 -46
- package/src/strand-watcher.ts +66 -3
- package/src/trusted-owner-store-file.ts +41 -0
- package/src/trusted-owner-store.ts +171 -0
- package/src/types.ts +342 -51
- package/dist/authority-key.d.ts +0 -41
- package/dist/authority-key.js +0 -52
- package/dist/authority-key.js.map +0 -1
- package/src/authority-key.ts +0 -68
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* push-node.ts — Node-only subpath entry for platform push **construction**.
|
|
3
|
+
*
|
|
4
|
+
* Import from the dedicated subpath, never the package root:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { createPushNotifier } from '@serfab/cadre-core/push-node';
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* The FCM/APNs implementations reach for `node:crypto` / `node:http2`, so they
|
|
11
|
+
* are quarantined here — unreachable from the cross-platform `./index.js` graph
|
|
12
|
+
* (same isolation pattern as `./key-store-file`). A React Native / browser entry
|
|
13
|
+
* never resolves this path, so the Node builtins never reach a bundler that
|
|
14
|
+
* cannot satisfy them. The core references only the {@link PushNotifier}
|
|
15
|
+
* *interface* (`push-notifier.ts`) and a Node host injects the instance built
|
|
16
|
+
* here into `CadreNodeConfig.push.notifier`.
|
|
17
|
+
*/
|
|
18
|
+
import { createFcmPushNotifier } from './push-notifier-fcm.js';
|
|
19
|
+
import { createApnsPushNotifier } from './push-notifier-apns.js';
|
|
20
|
+
/**
|
|
21
|
+
* Build a {@link PushNotifier} router over the configured credentials. Only the
|
|
22
|
+
* platforms whose credentials are present get a backing implementation; a `send`
|
|
23
|
+
* for an unconfigured platform returns a best-effort `no <platform> credentials`
|
|
24
|
+
* failure rather than throwing.
|
|
25
|
+
*/
|
|
26
|
+
export function createPushNotifier(creds, deps = {}) {
|
|
27
|
+
const fcm = creds.fcm ? createFcmPushNotifier(creds.fcm, deps.fcm) : undefined;
|
|
28
|
+
const apns = creds.apns ? createApnsPushNotifier(creds.apns, deps.apns) : undefined;
|
|
29
|
+
async function send(msg) {
|
|
30
|
+
if (msg.platform === 'fcm')
|
|
31
|
+
return fcm ? fcm.send(msg) : noCreds('fcm');
|
|
32
|
+
if (msg.platform === 'apns')
|
|
33
|
+
return apns ? apns.send(msg) : noCreds('apns');
|
|
34
|
+
return { ok: false, unregistered: false, error: `unknown platform ${String(msg.platform)}` };
|
|
35
|
+
}
|
|
36
|
+
async function close() {
|
|
37
|
+
await Promise.all([fcm?.close(), apns?.close()]);
|
|
38
|
+
}
|
|
39
|
+
return { send, close };
|
|
40
|
+
}
|
|
41
|
+
/** Best-effort no-op result for a platform with no configured credentials. */
|
|
42
|
+
function noCreds(platform) {
|
|
43
|
+
return { ok: false, unregistered: false, error: `no ${platform} credentials` };
|
|
44
|
+
}
|
|
45
|
+
// Per-platform builders + their injected-dep types, for a host that wants a
|
|
46
|
+
// single-platform notifier or to inject a fake transport directly.
|
|
47
|
+
export { createFcmPushNotifier, createApnsPushNotifier };
|
|
48
|
+
//# sourceMappingURL=push-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push-node.js","sourceRoot":"","sources":["../src/push-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAE,qBAAqB,EAAoB,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAqB,MAAM,yBAAyB,CAAC;AAWpF;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAsB,EAAE,OAAyB,EAAE;IACpF,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpF,KAAK,UAAU,IAAI,CAAC,GAAgB;QAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK;YAAE,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxE,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;IAC/F,CAAC;IAED,KAAK,UAAU,KAAK;QAClB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,8EAA8E;AAC9E,SAAS,OAAO,CAAC,QAAsB;IACrC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,cAAc,EAAE,CAAC;AACjF,CAAC;AAED,4EAA4E;AAC5E,mEAAmE;AACnE,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,CAAC"}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* push-notifier-apns.ts — APNs HTTP/2 strand-wake delivery.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* sends a background data push over an HTTP/2 session to Apple's gateway.
|
|
4
|
+
* Node-only: signs a provider JWT (ES256, JOSE raw r‖s via `node:crypto`) and
|
|
5
|
+
* sends a background data push over an HTTP/2 session to Apple's gateway. APNs
|
|
6
|
+
* mandates HTTP/2, so `node:http2` is unavoidable here — one reason the push
|
|
7
|
+
* path is injected rather than rebuilt on WebCrypto/`fetch`.
|
|
8
|
+
*
|
|
9
|
+
* Reachable only through the `@serfab/cadre-core/push-node` subpath — never from
|
|
10
|
+
* the cross-platform `./index.js` graph — so the `node:crypto` / `node:http2`
|
|
11
|
+
* imports below are safe: no RN/browser bundler ever resolves this module. (Plain
|
|
12
|
+
* named imports; the old namespace-import-to-only-warn dance is obsolete now that
|
|
13
|
+
* the module is unreachable from a browser build by construction.)
|
|
6
14
|
*
|
|
7
15
|
* The HTTP/2 call is behind an injected `Http2Requester` seam (bundled with a
|
|
8
16
|
* `close` into an {@link ApnsTransport}) so unit tests assert the request shape
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* push-notifier-apns.ts — APNs HTTP/2 strand-wake delivery.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* sends a background data push over an HTTP/2 session to Apple's gateway.
|
|
4
|
+
* Node-only: signs a provider JWT (ES256, JOSE raw r‖s via `node:crypto`) and
|
|
5
|
+
* sends a background data push over an HTTP/2 session to Apple's gateway. APNs
|
|
6
|
+
* mandates HTTP/2, so `node:http2` is unavoidable here — one reason the push
|
|
7
|
+
* path is injected rather than rebuilt on WebCrypto/`fetch`.
|
|
8
|
+
*
|
|
9
|
+
* Reachable only through the `@serfab/cadre-core/push-node` subpath — never from
|
|
10
|
+
* the cross-platform `./index.js` graph — so the `node:crypto` / `node:http2`
|
|
11
|
+
* imports below are safe: no RN/browser bundler ever resolves this module. (Plain
|
|
12
|
+
* named imports; the old namespace-import-to-only-warn dance is obsolete now that
|
|
13
|
+
* the module is unreachable from a browser build by construction.)
|
|
6
14
|
*
|
|
7
15
|
* The HTTP/2 call is behind an injected `Http2Requester` seam (bundled with a
|
|
8
16
|
* `close` into an {@link ApnsTransport}) so unit tests assert the request shape
|
|
@@ -18,12 +26,8 @@
|
|
|
18
26
|
* are never logged — failure log lines carry only a status/reason and a redacted
|
|
19
27
|
* token prefix.
|
|
20
28
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// namespace import only warns — same reasoning as the `node:http2` import below
|
|
24
|
-
// and the matching note in push-notifier-fcm.ts. Server-only; never run in browser.
|
|
25
|
-
import * as nodeCrypto from 'node:crypto';
|
|
26
|
-
import * as http2 from 'node:http2';
|
|
29
|
+
import { sign } from 'node:crypto';
|
|
30
|
+
import { connect } from 'node:http2';
|
|
27
31
|
import debug from 'debug';
|
|
28
32
|
import { MAX_REASON_LEN, b64urlJson, errText, redact } from './push-notifier-shared.js';
|
|
29
33
|
const APNS_PROD_HOST = 'https://api.push.apple.com';
|
|
@@ -124,7 +128,7 @@ export function createApnsPushNotifier(creds, deps = {}) {
|
|
|
124
128
|
const header = { alg: 'ES256', kid: creds.keyId };
|
|
125
129
|
const claims = { iss: creds.teamId, iat };
|
|
126
130
|
const signingInput = `${b64urlJson(header)}.${b64urlJson(claims)}`;
|
|
127
|
-
const sig =
|
|
131
|
+
const sig = sign('SHA256', Buffer.from(signingInput), {
|
|
128
132
|
key: creds.privateKey,
|
|
129
133
|
dsaEncoding: 'ieee-p1363',
|
|
130
134
|
}).toString('base64url');
|
|
@@ -149,7 +153,7 @@ function createHttp2Transport(host) {
|
|
|
149
153
|
function ensureSession() {
|
|
150
154
|
if (session && !session.closed && !session.destroyed)
|
|
151
155
|
return session;
|
|
152
|
-
const s =
|
|
156
|
+
const s = connect(host);
|
|
153
157
|
// Drop a dead session so ensureSession recreates it on the next request.
|
|
154
158
|
s.on('error', () => { if (session === s)
|
|
155
159
|
session = null; });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-notifier-apns.js","sourceRoot":"","sources":["../src/push-notifier-apns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"push-notifier-apns.js","sourceRoot":"","sources":["../src/push-notifier-apns.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* push-notifier-fcm.ts — FCM HTTP v1 strand-wake delivery.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Node-only: mints a Google OAuth2 access token (RS256 JWT bearer grant signed
|
|
5
5
|
* with `node:crypto`) and POSTs a data message to the FCM v1 endpoint. The legacy
|
|
6
6
|
* server-key `fcm.googleapis.com/fcm/send` API is deprecated, so we use HTTP v1.
|
|
7
7
|
*
|
|
8
|
+
* Reachable only through the `@serfab/cadre-core/push-node` subpath — never from
|
|
9
|
+
* the cross-platform `./index.js` graph — so the `node:crypto` import below is
|
|
10
|
+
* safe: no RN/browser bundler ever resolves this module. (Plain named import;
|
|
11
|
+
* the old namespace-import-to-only-warn dance is obsolete now that the module is
|
|
12
|
+
* unreachable from a browser build by construction.)
|
|
13
|
+
*
|
|
8
14
|
* The network call is behind an injected `fetch`-like seam so unit tests assert
|
|
9
15
|
* the request shape and map every documented response code with no real network
|
|
10
16
|
* and no credentials. Failures are returned as {@link PushSendResult} values.
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* push-notifier-fcm.ts — FCM HTTP v1 strand-wake delivery.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Node-only: mints a Google OAuth2 access token (RS256 JWT bearer grant signed
|
|
5
5
|
* with `node:crypto`) and POSTs a data message to the FCM v1 endpoint. The legacy
|
|
6
6
|
* server-key `fcm.googleapis.com/fcm/send` API is deprecated, so we use HTTP v1.
|
|
7
7
|
*
|
|
8
|
+
* Reachable only through the `@serfab/cadre-core/push-node` subpath — never from
|
|
9
|
+
* the cross-platform `./index.js` graph — so the `node:crypto` import below is
|
|
10
|
+
* safe: no RN/browser bundler ever resolves this module. (Plain named import;
|
|
11
|
+
* the old namespace-import-to-only-warn dance is obsolete now that the module is
|
|
12
|
+
* unreachable from a browser build by construction.)
|
|
13
|
+
*
|
|
8
14
|
* The network call is behind an injected `fetch`-like seam so unit tests assert
|
|
9
15
|
* the request shape and map every documented response code with no real network
|
|
10
16
|
* and no credentials. Failures are returned as {@link PushSendResult} values.
|
|
@@ -13,14 +19,7 @@
|
|
|
13
19
|
* device tokens are never logged — failure log lines carry only a status/error
|
|
14
20
|
* code and a redacted token prefix.
|
|
15
21
|
*/
|
|
16
|
-
|
|
17
|
-
// reached only via the guarded dynamic import in CadreNode, but bundlers still
|
|
18
|
-
// analyse that lazy chunk. A *named* import of `node:crypto` hard-fails the
|
|
19
|
-
// browser build ("sign is not exported by __vite-browser-external"), whereas a
|
|
20
|
-
// namespace import of the deliberately-unaliased external only warns (matching
|
|
21
|
-
// the `node:http2` namespace import in push-notifier-apns.ts). The browser
|
|
22
|
-
// never executes this code (config.push is node-only), so the warning is benign.
|
|
23
|
-
import * as nodeCrypto from 'node:crypto';
|
|
22
|
+
import { sign } from 'node:crypto';
|
|
24
23
|
import debug from 'debug';
|
|
25
24
|
import { MAX_REASON_LEN, b64urlJson, errText, redact } from './push-notifier-shared.js';
|
|
26
25
|
const TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token';
|
|
@@ -128,7 +127,7 @@ export function createFcmPushNotifier(creds, deps = {}) {
|
|
|
128
127
|
exp: iat + 3600,
|
|
129
128
|
};
|
|
130
129
|
const signingInput = `${b64urlJson(header)}.${b64urlJson(claims)}`;
|
|
131
|
-
const sig =
|
|
130
|
+
const sig = sign('RSA-SHA256', Buffer.from(signingInput), creds.privateKey).toString('base64url');
|
|
132
131
|
return `${signingInput}.${sig}`;
|
|
133
132
|
}
|
|
134
133
|
async function close() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-notifier-fcm.js","sourceRoot":"","sources":["../src/push-notifier-fcm.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"push-notifier-fcm.js","sourceRoot":"","sources":["../src/push-notifier-fcm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAExF,MAAM,cAAc,GAAG,qCAAqC,CAAC;AAC7D,MAAM,SAAS,GAAG,oDAAoD,CAAC;AACvE,MAAM,gBAAgB,GAAG,6CAA6C,CAAC;AACvE,sEAAsE;AACtE,MAAM,qBAAqB,GAAG,KAAM,CAAC;AACrC,2EAA2E;AAC3E,MAAM,oBAAoB,GAAG,OAAS,CAAC;AAEvC,MAAM,QAAQ,GAAG,KAAK,CAAC,uBAAuB,CAAC,CAAC;AA8BhD,MAAM,UAAU,qBAAqB,CAAC,KAAqB,EAAE,OAAoB,EAAE;IACjF,MAAM,OAAO,GAAa,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,0CAA0C,KAAK,CAAC,SAAS,gBAAgB,CAAC;IAE1F,IAAI,MAAM,GAA6B,IAAI,CAAC;IAE5C,KAAK,UAAU,IAAI,CAAC,GAAgB;QAClC,IAAI,KAAa,CAAC;QAClB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,sBAAsB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QAC7F,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAE7D,6EAA6E;QAC7E,sEAAsE;QACtE,IAAI,UAAkB,CAAC;QACvB,IAAI,CAAC;YACH,UAAU,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,yBAAyB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QAChG,CAAC;QACD,OAAO,SAAS,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,UAAU,QAAQ,CAAC,GAAgB,EAAE,KAAa;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,OAAO,EAAE;gBACP,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,IAAI,EAAE;oBACJ,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI;oBACtB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ;oBAC9B,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC;iBACpD;gBACD,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;aAC9B;SACF,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YACjF,IAAI;SACL,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED,SAAS,SAAS,CAAC,GAAqC,EAAE,WAAmB;QAC3E,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,sBAAsB,MAAM,CAAC,WAAW,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC;YAC9D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC3D,CAAC;QACD,GAAG,CAAC,qBAAqB,MAAM,CAAC,WAAW,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC;QAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC5D,CAAC;IAED,KAAK,UAAU,WAAW,CAAC,YAAqB;QAC9C,IAAI,CAAC,YAAY,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;QAC7E,MAAM,GAAG,IAAI,CAAC;QACd,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;QACvC,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,qBAAqB,EAAE,CAAC;QAC1F,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,UAAU,eAAe;QAC5B,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE;YACxC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI,EAAE,cAAc,kBAAkB,CAAC,gBAAgB,CAAC,cAAc,kBAAkB,CAAC,GAAG,CAAC,EAAE;SAChG,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,KAAK,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqD,CAAC;QACtF,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC;QACtG,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,SAAS,YAAY;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG;YACb,GAAG,EAAE,KAAK,CAAC,WAAW;YACtB,GAAG,EAAE,KAAK,CAAC,WAAW;YACtB,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,cAAc;YACnB,GAAG;YACH,GAAG,EAAE,GAAG,GAAG,IAAI;SAChB,CAAC;QACF,MAAM,YAAY,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClG,OAAO,GAAG,YAAY,IAAI,GAAG,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,UAAU,KAAK;QAClB,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,MAAc,EAAE,IAAY;IAClD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACjC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,IAAI,KAAK,kBAAkB,IAAI,qDAAqD,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kFAAkF;AAClF,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAE7B,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,EAAE,SAAS,CAAC;QACxF,OAAO,UAAU,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,SAAS,YAAY,CAAC,MAAc,EAAE,IAAY;IAChD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,GAAoB;IAC1C,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
package/dist/push-notifier.d.ts
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* push-notifier.ts — the platform-push **delivery**
|
|
2
|
+
* push-notifier.ts — the platform-push **delivery** contract for strand-wake.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* This module is the cross-platform-safe *interface* half: the message shape
|
|
5
|
+
* ({@link PushMessage}), the outcome value ({@link PushSendResult}), and the
|
|
6
|
+
* {@link PushNotifier} port a `CadreNode` sends over. It carries ZERO runtime
|
|
7
|
+
* dependencies and imports no implementation — so the RN/browser entry graph can
|
|
8
|
+
* reference the type without ever resolving `node:crypto` / `node:http2`.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* The concrete FCM/APNs implementations (`push-notifier-fcm.ts` /
|
|
11
|
+
* `push-notifier-apns.ts`) and the `createPushNotifier` router that builds them
|
|
12
|
+
* live behind the Node-only subpath `@serfab/cadre-core/push-node`
|
|
13
|
+
* (`push-node.ts`). A Node host constructs a notifier from that subpath and
|
|
14
|
+
* injects the instance into `CadreNodeConfig.push.notifier`; the cross-platform
|
|
15
|
+
* core never constructs one, so the Node-only builtins stay out of its graph.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* type-only re-export is erased at emit), and the only runtime constructor of a
|
|
20
|
-
* notifier is the in-package fan-out that runs inside a Node `CadreNode`. A
|
|
21
|
-
* cross-platform consumer imports the payload contract + types, never this value.
|
|
17
|
+
* Keep this file zero-import (beyond erased type-only imports): the whole point
|
|
18
|
+
* of the seam is that referencing the interface can never drag an implementation
|
|
19
|
+
* module into a bundler's graph.
|
|
22
20
|
*/
|
|
23
|
-
import type { PushPlatform
|
|
21
|
+
import type { PushPlatform } from './types.js';
|
|
24
22
|
import type { StrandWakePayload } from './strand-wake-payload.js';
|
|
25
|
-
import { type FcmPushDeps } from './push-notifier-fcm.js';
|
|
26
|
-
import { type ApnsPushDeps } from './push-notifier-apns.js';
|
|
27
23
|
/** One strand-wake data message addressed to one device. */
|
|
28
24
|
export interface PushMessage {
|
|
29
25
|
/** The resolved `DeviceToken.token` for the target peer. */
|
|
@@ -54,18 +50,3 @@ export interface PushNotifier {
|
|
|
54
50
|
/** Release transport resources (e.g. the APNs HTTP/2 session). */
|
|
55
51
|
close(): Promise<void>;
|
|
56
52
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Per-platform transport/clock/log seams, injected by tests. Defaults are the
|
|
59
|
-
* real implementations (global `fetch` for FCM, a `node:http2` session for APNs).
|
|
60
|
-
*/
|
|
61
|
-
export interface PushNotifierDeps {
|
|
62
|
-
fcm?: FcmPushDeps;
|
|
63
|
-
apns?: ApnsPushDeps;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Build a {@link PushNotifier} router over the configured credentials. Only the
|
|
67
|
-
* platforms whose credentials are present get a backing implementation; a `send`
|
|
68
|
-
* for an unconfigured platform returns a best-effort `no <platform> credentials`
|
|
69
|
-
* failure rather than throwing.
|
|
70
|
-
*/
|
|
71
|
-
export declare function createPushNotifier(creds: PushCredentials, deps?: PushNotifierDeps): PushNotifier;
|
package/dist/push-notifier.js
CHANGED
|
@@ -1,50 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* push-notifier.ts — the platform-push **delivery**
|
|
2
|
+
* push-notifier.ts — the platform-push **delivery** contract for strand-wake.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* This module is the cross-platform-safe *interface* half: the message shape
|
|
5
|
+
* ({@link PushMessage}), the outcome value ({@link PushSendResult}), and the
|
|
6
|
+
* {@link PushNotifier} port a `CadreNode` sends over. It carries ZERO runtime
|
|
7
|
+
* dependencies and imports no implementation — so the RN/browser entry graph can
|
|
8
|
+
* reference the type without ever resolving `node:crypto` / `node:http2`.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* The concrete FCM/APNs implementations (`push-notifier-fcm.ts` /
|
|
11
|
+
* `push-notifier-apns.ts`) and the `createPushNotifier` router that builds them
|
|
12
|
+
* live behind the Node-only subpath `@serfab/cadre-core/push-node`
|
|
13
|
+
* (`push-node.ts`). A Node host constructs a notifier from that subpath and
|
|
14
|
+
* injects the instance into `CadreNodeConfig.push.notifier`; the cross-platform
|
|
15
|
+
* core never constructs one, so the Node-only builtins stay out of its graph.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* type-only re-export is erased at emit), and the only runtime constructor of a
|
|
20
|
-
* notifier is the in-package fan-out that runs inside a Node `CadreNode`. A
|
|
21
|
-
* cross-platform consumer imports the payload contract + types, never this value.
|
|
17
|
+
* Keep this file zero-import (beyond erased type-only imports): the whole point
|
|
18
|
+
* of the seam is that referencing the interface can never drag an implementation
|
|
19
|
+
* module into a bundler's graph.
|
|
22
20
|
*/
|
|
23
|
-
|
|
24
|
-
import { createApnsPushNotifier } from './push-notifier-apns.js';
|
|
25
|
-
/**
|
|
26
|
-
* Build a {@link PushNotifier} router over the configured credentials. Only the
|
|
27
|
-
* platforms whose credentials are present get a backing implementation; a `send`
|
|
28
|
-
* for an unconfigured platform returns a best-effort `no <platform> credentials`
|
|
29
|
-
* failure rather than throwing.
|
|
30
|
-
*/
|
|
31
|
-
export function createPushNotifier(creds, deps = {}) {
|
|
32
|
-
const fcm = creds.fcm ? createFcmPushNotifier(creds.fcm, deps.fcm) : undefined;
|
|
33
|
-
const apns = creds.apns ? createApnsPushNotifier(creds.apns, deps.apns) : undefined;
|
|
34
|
-
async function send(msg) {
|
|
35
|
-
if (msg.platform === 'fcm')
|
|
36
|
-
return fcm ? fcm.send(msg) : noCreds('fcm');
|
|
37
|
-
if (msg.platform === 'apns')
|
|
38
|
-
return apns ? apns.send(msg) : noCreds('apns');
|
|
39
|
-
return { ok: false, unregistered: false, error: `unknown platform ${String(msg.platform)}` };
|
|
40
|
-
}
|
|
41
|
-
async function close() {
|
|
42
|
-
await Promise.all([fcm?.close(), apns?.close()]);
|
|
43
|
-
}
|
|
44
|
-
return { send, close };
|
|
45
|
-
}
|
|
46
|
-
/** Best-effort no-op result for a platform with no configured credentials. */
|
|
47
|
-
function noCreds(platform) {
|
|
48
|
-
return { ok: false, unregistered: false, error: `no ${platform} credentials` };
|
|
49
|
-
}
|
|
21
|
+
export {};
|
|
50
22
|
//# sourceMappingURL=push-notifier.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-notifier.js","sourceRoot":"","sources":["../src/push-notifier.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"push-notifier.js","sourceRoot":"","sources":["../src/push-notifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate `network.relayAddrs` — the operator-facing "use these relay servers"
|
|
3
|
+
* setting — into the mechanism this repo already has for reserving a circuit-relay
|
|
4
|
+
* slot: a `…/p2p/<relayPeerId>/p2p-circuit` entry in the node's listen addrs.
|
|
5
|
+
*
|
|
6
|
+
* `@libp2p/circuit-relay-v2`'s transport is always present on the Node path
|
|
7
|
+
* (`../optimystic/packages/db-p2p/src/libp2p-node.ts` pushes `circuitRelayTransport()`
|
|
8
|
+
* unconditionally), and listening on a relay's circuit addr is what makes libp2p dial
|
|
9
|
+
* that relay and hold a reservation. Everything downstream of the listen list —
|
|
10
|
+
* the reservation itself, `CadreNode.circuitRelayTargets()` picking delegate-announce
|
|
11
|
+
* targets, strand nodes inheriting the listen addrs, the `/p2p-circuit`-first address
|
|
12
|
+
* publishing in `registerSelf` — then works unchanged.
|
|
13
|
+
*
|
|
14
|
+
* So `relayAddrs` is a second, friendlier door onto an existing mechanism:
|
|
15
|
+
*
|
|
16
|
+
* effective listen addrs = listenAddrs ++ relayAddrs.map(a => a + '/p2p-circuit')
|
|
17
|
+
*
|
|
18
|
+
* NOTE: this is the FAIL-FAST route to a reservation — libp2p's transport manager
|
|
19
|
+
* throws when a configured circuit listener cannot listen, so naming a relay that
|
|
20
|
+
* is down means the node does not start. The fail-soft route is the bare
|
|
21
|
+
* `/p2p-circuit` search listener driven by `relay-reservation.ts`. The two are
|
|
22
|
+
* ALTERNATIVES, not layers: configuring `relayAddrs` on a node that already
|
|
23
|
+
* reserves via the search listener adds the fatal listener back and the node
|
|
24
|
+
* stops booting when its relay is down.
|
|
25
|
+
*/
|
|
26
|
+
import type { NetworkConfig } from './types.js';
|
|
27
|
+
/**
|
|
28
|
+
* The circuit-listen multiaddr for each configured relay: `<relayAddr>/p2p-circuit`.
|
|
29
|
+
* An entry that already carries `/p2p-circuit` is passed through unchanged.
|
|
30
|
+
* Throws on an entry that is unparsable or names no relay peerId — this is
|
|
31
|
+
* operator configuration, so a typo must fail loudly at start rather than
|
|
32
|
+
* silently costing the node its reachability.
|
|
33
|
+
*
|
|
34
|
+
* Deliberately unlike `extractCircuitRelayTargets` (`delegate-admission.ts`), which
|
|
35
|
+
* SKIPS a bad entry: that one reads addresses discovered at runtime from peers, where
|
|
36
|
+
* one bad entry must not be fatal.
|
|
37
|
+
*/
|
|
38
|
+
export declare function relayCircuitAddrs(relayAddrs: readonly string[]): string[];
|
|
39
|
+
/**
|
|
40
|
+
* The listen multiaddrs a node actually binds: configured `listenAddrs` plus the
|
|
41
|
+
* circuit-listen addr of every configured relay, deduplicated, order-stable
|
|
42
|
+
* (configured entries first). Returns `undefined` when neither field is set, so
|
|
43
|
+
* callers keep omitting `listenAddrs` and inherit db-p2p's default.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveListenAddrs(network: NetworkConfig | undefined): string[] | undefined;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate `network.relayAddrs` — the operator-facing "use these relay servers"
|
|
3
|
+
* setting — into the mechanism this repo already has for reserving a circuit-relay
|
|
4
|
+
* slot: a `…/p2p/<relayPeerId>/p2p-circuit` entry in the node's listen addrs.
|
|
5
|
+
*
|
|
6
|
+
* `@libp2p/circuit-relay-v2`'s transport is always present on the Node path
|
|
7
|
+
* (`../optimystic/packages/db-p2p/src/libp2p-node.ts` pushes `circuitRelayTransport()`
|
|
8
|
+
* unconditionally), and listening on a relay's circuit addr is what makes libp2p dial
|
|
9
|
+
* that relay and hold a reservation. Everything downstream of the listen list —
|
|
10
|
+
* the reservation itself, `CadreNode.circuitRelayTargets()` picking delegate-announce
|
|
11
|
+
* targets, strand nodes inheriting the listen addrs, the `/p2p-circuit`-first address
|
|
12
|
+
* publishing in `registerSelf` — then works unchanged.
|
|
13
|
+
*
|
|
14
|
+
* So `relayAddrs` is a second, friendlier door onto an existing mechanism:
|
|
15
|
+
*
|
|
16
|
+
* effective listen addrs = listenAddrs ++ relayAddrs.map(a => a + '/p2p-circuit')
|
|
17
|
+
*
|
|
18
|
+
* NOTE: this is the FAIL-FAST route to a reservation — libp2p's transport manager
|
|
19
|
+
* throws when a configured circuit listener cannot listen, so naming a relay that
|
|
20
|
+
* is down means the node does not start. The fail-soft route is the bare
|
|
21
|
+
* `/p2p-circuit` search listener driven by `relay-reservation.ts`. The two are
|
|
22
|
+
* ALTERNATIVES, not layers: configuring `relayAddrs` on a node that already
|
|
23
|
+
* reserves via the search listener adds the fatal listener back and the node
|
|
24
|
+
* stops booting when its relay is down.
|
|
25
|
+
*/
|
|
26
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
27
|
+
import { circuitRelayTargetOrThrow } from './delegate-admission.js';
|
|
28
|
+
/**
|
|
29
|
+
* The direct listener a node keeps when it configures `relayAddrs` but no
|
|
30
|
+
* `listenAddrs`. Without this, naming a relay would silently REPLACE the node's
|
|
31
|
+
* direct TCP listener with a circuit-only one.
|
|
32
|
+
*
|
|
33
|
+
* NOTE: mirrors `createLibp2pNode`'s own default listen addr in
|
|
34
|
+
* `../optimystic/packages/db-p2p/src/libp2p-node.ts` (`/ip4/0.0.0.0/tcp/<port>`,
|
|
35
|
+
* and `CadreNode` passes `port: 0`) — that file is the source of truth. If it
|
|
36
|
+
* ever changes its default, this constant has to follow.
|
|
37
|
+
*/
|
|
38
|
+
const DEFAULT_DIRECT_LISTEN_ADDR = '/ip4/0.0.0.0/tcp/0';
|
|
39
|
+
/**
|
|
40
|
+
* The circuit-listen multiaddr for each configured relay: `<relayAddr>/p2p-circuit`.
|
|
41
|
+
* An entry that already carries `/p2p-circuit` is passed through unchanged.
|
|
42
|
+
* Throws on an entry that is unparsable or names no relay peerId — this is
|
|
43
|
+
* operator configuration, so a typo must fail loudly at start rather than
|
|
44
|
+
* silently costing the node its reachability.
|
|
45
|
+
*
|
|
46
|
+
* Deliberately unlike `extractCircuitRelayTargets` (`delegate-admission.ts`), which
|
|
47
|
+
* SKIPS a bad entry: that one reads addresses discovered at runtime from peers, where
|
|
48
|
+
* one bad entry must not be fatal.
|
|
49
|
+
*/
|
|
50
|
+
export function relayCircuitAddrs(relayAddrs) {
|
|
51
|
+
return dedupe(relayAddrs.map(circuitListenAddr));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The listen multiaddrs a node actually binds: configured `listenAddrs` plus the
|
|
55
|
+
* circuit-listen addr of every configured relay, deduplicated, order-stable
|
|
56
|
+
* (configured entries first). Returns `undefined` when neither field is set, so
|
|
57
|
+
* callers keep omitting `listenAddrs` and inherit db-p2p's default.
|
|
58
|
+
*/
|
|
59
|
+
export function resolveListenAddrs(network) {
|
|
60
|
+
const circuits = relayCircuitAddrs(network?.relayAddrs ?? []);
|
|
61
|
+
const listenAddrs = network?.listenAddrs;
|
|
62
|
+
if (!listenAddrs && circuits.length === 0) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
// An explicitly empty `listenAddrs` (the React Native "cannot listen" case) stays
|
|
66
|
+
// empty — but a relay named alongside it still gets its circuit listener, since
|
|
67
|
+
// acquiring one is the whole point of configuring a relay.
|
|
68
|
+
return dedupe([...(listenAddrs ?? [DEFAULT_DIRECT_LISTEN_ADDR]), ...circuits]);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* One entry of {@link relayCircuitAddrs}: the addr the node listens on for this relay.
|
|
72
|
+
*
|
|
73
|
+
* NOTE: an entry carrying components AFTER `/p2p-circuit` — a full relayed DIAL addr,
|
|
74
|
+
* `…/p2p/<relay>/p2p-circuit/p2p/<someone else>` — is passed through as written and
|
|
75
|
+
* would be listened on verbatim. It validates (the relay it names is real), so only an
|
|
76
|
+
* operator who pastes a peer's relayed address into `relayAddrs` hits it; if that turns
|
|
77
|
+
* out to be a common paste, truncate at the `/p2p-circuit` component here.
|
|
78
|
+
*/
|
|
79
|
+
function circuitListenAddr(relayAddr) {
|
|
80
|
+
const alreadyCircuit = parseComponents(relayAddr).some((c) => c.name === 'p2p-circuit');
|
|
81
|
+
const listenAddr = alreadyCircuit ? relayAddr : `${relayAddr}/p2p-circuit`;
|
|
82
|
+
try {
|
|
83
|
+
circuitRelayTargetOrThrow(listenAddr); // validates the relay peerId
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
throw new Error(`network.relayAddrs entry names no relay peerId (expected <dial addr>/p2p/<relayPeerId>): ${relayAddr}`, { cause: err });
|
|
87
|
+
}
|
|
88
|
+
return listenAddr;
|
|
89
|
+
}
|
|
90
|
+
/** Multiaddr components of `relayAddr`, with the config field named on a parse failure. */
|
|
91
|
+
function parseComponents(relayAddr) {
|
|
92
|
+
try {
|
|
93
|
+
return multiaddr(relayAddr).getComponents();
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
throw new Error(`network.relayAddrs entry is not a valid multiaddr: ${relayAddr}`, { cause: err });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Exact-string dedupe, first occurrence wins, so the list is stable across restarts. */
|
|
100
|
+
function dedupe(addrs) {
|
|
101
|
+
return [...new Set(addrs)];
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=relay-addrs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-addrs.js","sourceRoot":"","sources":["../src/relay-addrs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAGpE;;;;;;;;;GASG;AACH,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA6B;IAC7D,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAkC;IACnE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,CAAC;IACzC,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,kFAAkF;IAClF,gFAAgF;IAChF,2DAA2D;IAC3D,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,0BAA0B,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;AACjF,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CAAC,SAAiB;IAC1C,MAAM,cAAc,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;IACxF,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,cAAc,CAAC;IAC3E,IAAI,CAAC;QACH,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC,6BAA6B;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,4FAA4F,SAAS,EAAE,EACvG,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,2FAA2F;AAC3F,SAAS,eAAe,CAAC,SAAiB;IACxC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sDAAsD,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IACrG,CAAC;AACH,CAAC;AAED,yFAAyF;AACzF,SAAS,MAAM,CAAC,KAAwB;IACtC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7B,CAAC"}
|