openvibers/openvibe.events Commits
Events: the key provider is openvibe-sdk/auth createNetworkKeys (SDK 0.40.0) (#53)
Changes
@@@ -22,7 +22,7 @@ npm test # every test/*.test.js, temp databases, no network neededNode 22 in production (`fnm exec --using=22.22.1 npm test`). Production: `/opt/openvibe.events`, env `/etc/openvibe/events.env`, unit [deploy/systemd/openvibe-events.service](deploy/systemd/openvibe-events.service), store PostgreSQL (`ov_events` on the host's data role), nginx [deploy/nginx/openvibe.events.conf](deploy/nginx/openvibe.events.conf) (the public vhost, on the API and product origin: it exposes the home and its discovery files, `/realtime/stream`, health, and the token-guarded `/api/v1/events`, `/api/v1/subscriptions` and `/api/v1/checkpoints` for developer apps; `/api/v1/deliveries` stays host-local; services on the host call `127.0.0.1:4300`).--`GET /api/health` is liveness. `GET /api/ready` (openvibe-shared/ready) is 200 only when every required check passes — `db` (a real query), `network_jwks` (the Network signing key has loaded: openvibe-sdk/auth's JWKS client, retried every 30 s while Network boots, refreshed every 15 minutes, refetched at once for a token naming an unknown kid, and the last good keys kept through a Network outage) and `delivery_worker` (when `EVENTS_WORKER` is on) — and 503 otherwise, with `failed: [...]`. The optional `dlq` check fails once more than `EVENTS_DLQ_DEGRADED_AT` (default 100) deliveries are dead: the service stays ready (200) and reports `status: "degraded"`, `degraded: ["dlq"]`. Each check carries `status`, `required`, `latency_ms`, `checked_at` and, for `dlq`, `detail: { depth, threshold }`; `latest_seq`, `deliveries`, `worker` and `realtime_connections` are still in the body. **Shape change (Track O):** `checks` used to be booleans (`{ db, worker, key }`); they are now objects keyed `db`, `network_jwks`, `delivery_worker`, `dlq`.++`GET /api/health` is liveness. `GET /api/ready` (openvibe-shared/ready) is 200 only when every required check passes — `db` (a real query), `network_jwks` (the Network signing key has loaded: openvibe-sdk/auth `createNetworkKeys`, retried every 30 s while Network boots, refreshed every 15 minutes, refetched at once for a token naming an unknown kid, and the last good keys kept through a Network outage) and `delivery_worker` (when `EVENTS_WORKER` is on) — and 503 otherwise, with `failed: [...]`. The optional `dlq` check fails once more than `EVENTS_DLQ_DEGRADED_AT` (default 100) deliveries are dead: the service stays ready (200) and reports `status: "degraded"`, `degraded: ["dlq"]`. Each check carries `status`, `required`, `latency_ms`, `checked_at` and, for `dlq`, `detail: { depth, threshold }`; `latest_seq`, `deliveries`, `worker` and `realtime_connections` are still in the body. **Shape change (Track O):** `checks` used to be booleans (`{ db, worker, key }`); they are now objects keyed `db`, `network_jwks`, `delivery_worker`, `dlq`.`GET /metrics` (Prometheus text, direct loopback callers only — a request carrying `X-Forwarded-For` gets 404, and nginx refuses the path): HTTP golden signals by route template (`http_requests_total`, `http_request_duration_seconds`, `http_requests_in_flight`; SSE sessions excluded), process metrics, `release_info`, and `events_deliveries{status}`, `events_dlq_depth`, `events_latest_seq`, `events_realtime_connections`, `events_delivery_latency_seconds{priority}` (acceptance → successful delivery, retries included), `events_delivery_attempts_total{outcome}`. `GET /release.json` is the deployed release (ADR-016, `release.mount` from openvibe-shared 1.5.0, with the manifest 1.1.0 fields under openvibe-contracts 0.32.0); its `POST /release-metrics` would count open tabs' update reports as `release_client_updates_total`, but Events has no pages and nginx does not proxy that path. `GET /limits.json` lists the developer limits enforced here (per project and environment), read from the running config; [openvibe.services/docs/limits](https://openvibe.services/docs/limits) renders it.@@@ -388,6 +388,6 @@ Part of the [OpenVibe network](https://openvibe.network). Built in the open by [<!-- versions:start -->- openvibe-contracts: v0.129.0--- openvibe-sdk: v0.38.0++- openvibe-sdk: v0.40.0- openvibe-shared: v3.0.0<!-- versions:end -->@@@ -8,7 +8,7 @@"port": 4300,"domain": "openvibe.events","contracts": "openvibe-contracts v0.129.0",-- "sdk": "openvibe-sdk v0.38.0",++ "sdk": "openvibe-sdk v0.40.0","shared": "openvibe-shared v3.0.0","capabilities": ["events.event.publish",@@@ -13,7 +13,7 @@"express": "^4.21.2","iovalkey": "^0.4.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.129.0",-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.38.0",++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.40.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v3.0.0","pg": "^8.23.0"},@@@ -844,9 +844,9 @@}},"node_modules/openvibe-sdk": {-- "version": "0.38.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.38.0",-- "integrity": "sha512-/Z+1kB5l4Hff0E1O1Zo+DcXaZX93wrmISOPP75sB7NqVUZVeKuJgjYu6vBwG8ufJjlk0vD3ZJ0ntBLI/3IKdpg==",++ "version": "0.40.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.40.0",++ "integrity": "sha512-fYX0zijJZDdwjXJGwroLDlb/wniY6NXVtgdPVJJHNgcdRmaAydpr6SKuxcLffmkTquyZQptwChsCvo+D6Wx+IA==","license": "MIT","engines": {"node": ">=20"@@@ -25,7 +25,7 @@"express": "^4.21.2","iovalkey": "^0.4.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.129.0",-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.38.0",++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.40.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v3.0.0","pg": "^8.23.0"},@@@ -18,8 +18,9 @@* (appOrService guard). Only there is a sandbox token (env=sandbox) accepted; every other route* refuses it with token.sandbox_refused.*-- * The key: Network's JWKS through openvibe-sdk/auth's process-wide client (the last good keys through a-- * Network outage, a rotation honoured on an unknown kid), or a pinned PEM (OV_NETWORK_PUBLIC_KEY).++ * The keys: openvibe-sdk/auth createNetworkKeys (server/index.js): Network's JWKS (the last good keys through a++ * Network outage, a rotation honoured on an unknown kid, retried every 30 s until the first load), or a pinned++ * PEM (OV_NETWORK_PUBLIC_KEY).** The service capabilities are in openvibe-contracts since v0.7; events.app.* arrive in v0.28.* capabilities.check() answers capability.unknown for an id the installed release does not know;@@@ -47,65 +48,6 @@ const CAPS = Object.freeze({resourceRead: 'events.resource.read',});--// ── Network public key ─────────────────────────────────────----const JWKS_RETRY_MS = 30 * 1000;--const JWKS_REFRESH_MS = 15 * 60 * 1000;----/**-- * Network's signing keys. With a PEM in config (OV_NETWORK_PUBLIC_KEY) that one key, never fetched. Otherwise-- * <networkInternalUrl>/api/.well-known/jwks through openvibe-sdk/auth's process-wide JWKS client (the verifiers read-- * the same client): start() retries every 30 s until the first load (Network may still be booting), then refreshes-- * every 15 minutes; a token naming an unknown kid refetches at once (a rotation).-- *-- * keys.verifyOptions what the SDK verifiers take: { publicKey } or { jwks: url, fetch, log }-- * keys.keysFor(kid) [{ kid, key }] to verify a realtime ticket with; throws when none has loaded-- */--function createKeys({ url = null, pem = null, fetchImpl = globalThis.fetch, log = console } = {}) {-- const pinned = pem ? crypto.createPublicKey(pem) : null;-- const jwksUrl = pinned || !url ? null : `${url.replace(/\/+$/, '')}/api/.well-known/jwks`;-- const client = jwksUrl ? sdkAuth.jwksClient(jwksUrl, { fetch: fetchImpl, log }) : null;-- let retryTimer = null;---- const loaded = () => Boolean(pinned) || Boolean(client && client.status().ready);---- /** One fetch now; the keys, or null (the client logged why). */-- async function refresh() {-- if (!client) return null;-- try { return await client.refresh(); } catch { return null; }-- }---- async function start() {-- if (!client) return pinned;-- client.start({ intervalMs: JWKS_REFRESH_MS });-- const attempt = async () => {-- retryTimer = null;-- const got = await refresh();-- if (!loaded()) {-- retryTimer = setTimeout(attempt, JWKS_RETRY_MS);-- retryTimer.unref?.();-- }-- return got;-- };-- return await attempt();-- }---- function stop() {-- clearTimeout(retryTimer);-- retryTimer = null;-- if (client) client.stop();-- }---- async function keysFor(kid) {-- if (pinned) return [{ kid: null, key: pinned }];-- if (!client) return [];-- return await client.keysForKid(kid || null);-- }---- const verifyOptions = pinned ? { publicKey: pinned } : { jwks: jwksUrl, fetch: fetchImpl, log };-- return { url: jwksUrl, loaded, start, stop, refresh, keysFor, verifyOptions };--}--// ── Capabilities ───────────────────────────────────────────/** Exact id or `family.*` grant (the rule openvibe-contracts applies to its known capabilities). */@@@ -328,4 +270,4 @@ function createAuth({ config, keys, store = null }) {return { verifyService, verifyUser, requireCap, appOrService, realtimeViewer };}--module.exports = { CAPS, createKeys, createAuth, hasCap, allows, verifyRealtimeTicket, serviceSlug, bearer, cookie };++module.exports = { CAPS, createAuth, hasCap, allows, verifyRealtimeTicket, serviceSlug, bearer, cookie };@@@ -12,7 +12,8 @@ const { openDb, createStore } = require('./store');const { createPolicyLibrary } = require('./fabric/policy');const { createCarriers } = require('./fabric/carriers');const { createPlanner } = require('./fabric/planner');--const { createKeys, createAuth } = require('./auth');++const { createNetworkKeys } = require('openvibe-sdk/auth');++const { createAuth } = require('./auth');const { createWorker } = require('./worker');const { createRealtime } = require('./realtime');const { createApp } = require('./app');@@@ -38,7 +39,7 @@ async function start({const carriers = createCarriers({ config, clock, log, valkey });const planner = createPlanner({ registry: carriers, db, clock, log });const store = createStore(db, { clock, maxHops: config.maxHops, usage: config.usage, policies, planner });-- const keys = createKeys({ url: config.networkInternalUrl, pem: config.networkPublicKey, fetchImpl, log });++ const keys = createNetworkKeys({ network: config.networkInternalUrl, publicKey: config.networkPublicKey, fetch: fetchImpl, log });const auth = createAuth({ config, keys, store });const metrics = createMetrics({ store });// appPost / dnsLookup: developer-app delivery and the subscribe-time DNS check (server/egress.js);
@@ -22,7 +22,7 @@ npm test # every test/*.test.js, temp databases, no network needed
@@ -22,7 +22,7 @@ npm test # every test/*.test.js, temp databases, no network needed
Node 22 in production (`fnm exec --using=22.22.1 npm test`). Production: `/opt/openvibe.events`, env `/etc/openvibe/events.env`, unit [deploy/systemd/openvibe-events.service](deploy/systemd/openvibe-events.service), store PostgreSQL (`ov_events` on the host's data role), nginx [deploy/nginx/openvibe.events.conf](deploy/nginx/openvibe.events.conf) (the public vhost, on the API and product origin: it exposes the home and its discovery files, `/realtime/stream`, health, and the token-guarded `/api/v1/events`, `/api/v1/subscriptions` and `/api/v1/checkpoints` for developer apps; `/api/v1/deliveries` stays host-local; services on the host call `127.0.0.1:4300`).
Node 22 in production (`fnm exec --using=22.22.1 npm test`). Production: `/opt/openvibe.events`, env `/etc/openvibe/events.env`, unit [deploy/systemd/openvibe-events.service](deploy/systemd/openvibe-events.service), store PostgreSQL (`ov_events` on the host's data role), nginx [deploy/nginx/openvibe.events.conf](deploy/nginx/openvibe.events.conf) (the public vhost, on the API and product origin: it exposes the home and its discovery files, `/realtime/stream`, health, and the token-guarded `/api/v1/events`, `/api/v1/subscriptions` and `/api/v1/checkpoints` for developer apps; `/api/v1/deliveries` stays host-local; services on the host call `127.0.0.1:4300`).
-`GET /api/health` is liveness. `GET /api/ready` (openvibe-shared/ready) is 200 only when every required check passes — `db` (a real query), `network_jwks` (the Network signing key has loaded: openvibe-sdk/auth's JWKS client, retried every 30 s while Network boots, refreshed every 15 minutes, refetched at once for a token naming an unknown kid, and the last good keys kept through a Network outage) and `delivery_worker` (when `EVENTS_WORKER` is on) — and 503 otherwise, with `failed: [...]`. The optional `dlq` check fails once more than `EVENTS_DLQ_DEGRADED_AT` (default 100) deliveries are dead: the service stays ready (200) and reports `status: "degraded"`, `degraded: ["dlq"]`. Each check carries `status`, `required`, `latency_ms`, `checked_at` and, for `dlq`, `detail: { depth, threshold }`; `latest_seq`, `deliveries`, `worker` and `realtime_connections` are still in the body. **Shape change (Track O):** `checks` used to be booleans (`{ db, worker, key }`); they are now objects keyed `db`, `network_jwks`, `delivery_worker`, `dlq`.
+`GET /api/health` is liveness. `GET /api/ready` (openvibe-shared/ready) is 200 only when every required check passes — `db` (a real query), `network_jwks` (the Network signing key has loaded: openvibe-sdk/auth `createNetworkKeys`, retried every 30 s while Network boots, refreshed every 15 minutes, refetched at once for a token naming an unknown kid, and the last good keys kept through a Network outage) and `delivery_worker` (when `EVENTS_WORKER` is on) — and 503 otherwise, with `failed: [...]`. The optional `dlq` check fails once more than `EVENTS_DLQ_DEGRADED_AT` (default 100) deliveries are dead: the service stays ready (200) and reports `status: "degraded"`, `degraded: ["dlq"]`. Each check carries `status`, `required`, `latency_ms`, `checked_at` and, for `dlq`, `detail: { depth, threshold }`; `latest_seq`, `deliveries`, `worker` and `realtime_connections` are still in the body. **Shape change (Track O):** `checks` used to be booleans (`{ db, worker, key }`); they are now objects keyed `db`, `network_jwks`, `delivery_worker`, `dlq`.
`GET /metrics` (Prometheus text, direct loopback callers only — a request carrying `X-Forwarded-For` gets 404, and nginx refuses the path): HTTP golden signals by route template (`http_requests_total`, `http_request_duration_seconds`, `http_requests_in_flight`; SSE sessions excluded), process metrics, `release_info`, and `events_deliveries{status}`, `events_dlq_depth`, `events_latest_seq`, `events_realtime_connections`, `events_delivery_latency_seconds{priority}` (acceptance → successful delivery, retries included), `events_delivery_attempts_total{outcome}`. `GET /release.json` is the deployed release (ADR-016, `release.mount` from openvibe-shared 1.5.0, with the manifest 1.1.0 fields under openvibe-contracts 0.32.0); its `POST /release-metrics` would count open tabs' update reports as `release_client_updates_total`, but Events has no pages and nginx does not proxy that path. `GET /limits.json` lists the developer limits enforced here (per project and environment), read from the running config; [openvibe.services/docs/limits](https://openvibe.services/docs/limits) renders it.
`GET /metrics` (Prometheus text, direct loopback callers only — a request carrying `X-Forwarded-For` gets 404, and nginx refuses the path): HTTP golden signals by route template (`http_requests_total`, `http_request_duration_seconds`, `http_requests_in_flight`; SSE sessions excluded), process metrics, `release_info`, and `events_deliveries{status}`, `events_dlq_depth`, `events_latest_seq`, `events_realtime_connections`, `events_delivery_latency_seconds{priority}` (acceptance → successful delivery, retries included), `events_delivery_attempts_total{outcome}`. `GET /release.json` is the deployed release (ADR-016, `release.mount` from openvibe-shared 1.5.0, with the manifest 1.1.0 fields under openvibe-contracts 0.32.0); its `POST /release-metrics` would count open tabs' update reports as `release_client_updates_total`, but Events has no pages and nginx does not proxy that path. `GET /limits.json` lists the developer limits enforced here (per project and environment), read from the running config; [openvibe.services/docs/limits](https://openvibe.services/docs/limits) renders it.
@@ -388,6 +388,6 @@ Part of the [OpenVibe network](https://openvibe.network). Built in the open by [
@@ -388,6 +388,6 @@ Part of the [OpenVibe network](https://openvibe.network). Built in the open by [
<!-- versions:start -->
<!-- versions:start -->
- openvibe-contracts: v0.129.0
- openvibe-contracts: v0.129.0
-- openvibe-sdk: v0.38.0
+- openvibe-sdk: v0.40.0
- openvibe-shared: v3.0.0
- openvibe-shared: v3.0.0
<!-- versions:end -->
<!-- versions:end -->
@@ -8,7 +8,7 @@
@@ -8,7 +8,7 @@
"port": 4300,
"port": 4300,
"domain": "openvibe.events",
"domain": "openvibe.events",
"contracts": "openvibe-contracts v0.129.0",
"contracts": "openvibe-contracts v0.129.0",
- "sdk": "openvibe-sdk v0.38.0",
+ "sdk": "openvibe-sdk v0.40.0",
"shared": "openvibe-shared v3.0.0",
"shared": "openvibe-shared v3.0.0",
"capabilities": [
"capabilities": [
"events.event.publish",
"events.event.publish",
@@ -13,7 +13,7 @@
@@ -13,7 +13,7 @@
"express": "^4.21.2",
"express": "^4.21.2",
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.129.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.129.0",
- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.38.0",
+ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.40.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v3.0.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v3.0.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
},
},
@@ -844,9 +844,9 @@
@@ -844,9 +844,9 @@
}
}
},
},
"node_modules/openvibe-sdk": {
"node_modules/openvibe-sdk": {
- "version": "0.38.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.38.0",
- "integrity": "sha512-/Z+1kB5l4Hff0E1O1Zo+DcXaZX93wrmISOPP75sB7NqVUZVeKuJgjYu6vBwG8ufJjlk0vD3ZJ0ntBLI/3IKdpg==",
+ "version": "0.40.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.40.0",
+ "integrity": "sha512-fYX0zijJZDdwjXJGwroLDlb/wniY6NXVtgdPVJJHNgcdRmaAydpr6SKuxcLffmkTquyZQptwChsCvo+D6Wx+IA==",
"license": "MIT",
"license": "MIT",
"engines": {
"engines": {
"node": ">=20"
"node": ">=20"
@@ -25,7 +25,7 @@
@@ -25,7 +25,7 @@
"express": "^4.21.2",
"express": "^4.21.2",
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.129.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.129.0",
- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.38.0",
+ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.40.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v3.0.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v3.0.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
},
},
@@ -18,8 +18,9 @@
@@ -18,8 +18,9 @@
* (appOrService guard). Only there is a sandbox token (env=sandbox) accepted; every other route
* (appOrService guard). Only there is a sandbox token (env=sandbox) accepted; every other route
* refuses it with token.sandbox_refused.
* refuses it with token.sandbox_refused.
*
*
- * The key: Network's JWKS through openvibe-sdk/auth's process-wide client (the last good keys through a
- * Network outage, a rotation honoured on an unknown kid), or a pinned PEM (OV_NETWORK_PUBLIC_KEY).
+ * The keys: openvibe-sdk/auth createNetworkKeys (server/index.js): Network's JWKS (the last good keys through a
+ * Network outage, a rotation honoured on an unknown kid, retried every 30 s until the first load), or a pinned
+ * PEM (OV_NETWORK_PUBLIC_KEY).
*
*
* The service capabilities are in openvibe-contracts since v0.7; events.app.* arrive in v0.28.
* The service capabilities are in openvibe-contracts since v0.7; events.app.* arrive in v0.28.
* capabilities.check() answers capability.unknown for an id the installed release does not know;
* capabilities.check() answers capability.unknown for an id the installed release does not know;
@@ -47,65 +48,6 @@ const CAPS = Object.freeze({
@@ -47,65 +48,6 @@ const CAPS = Object.freeze({
resourceRead: 'events.resource.read',
resourceRead: 'events.resource.read',
});
});
-// ── Network public key ─────────────────────────────────────
-
-const JWKS_RETRY_MS = 30 * 1000;
-const JWKS_REFRESH_MS = 15 * 60 * 1000;
-
-/**
- * Network's signing keys. With a PEM in config (OV_NETWORK_PUBLIC_KEY) that one key, never fetched. Otherwise
- * <networkInternalUrl>/api/.well-known/jwks through openvibe-sdk/auth's process-wide JWKS client (the verifiers read
- * the same client): start() retries every 30 s until the first load (Network may still be booting), then refreshes
- * every 15 minutes; a token naming an unknown kid refetches at once (a rotation).
- *
- * keys.verifyOptions what the SDK verifiers take: { publicKey } or { jwks: url, fetch, log }
- * keys.keysFor(kid) [{ kid, key }] to verify a realtime ticket with; throws when none has loaded
- */
-function createKeys({ url = null, pem = null, fetchImpl = globalThis.fetch, log = console } = {}) {
- const pinned = pem ? crypto.createPublicKey(pem) : null;
- const jwksUrl = pinned || !url ? null : `${url.replace(/\/+$/, '')}/api/.well-known/jwks`;
- const client = jwksUrl ? sdkAuth.jwksClient(jwksUrl, { fetch: fetchImpl, log }) : null;
- let retryTimer = null;
-
- const loaded = () => Boolean(pinned) || Boolean(client && client.status().ready);
-
- /** One fetch now; the keys, or null (the client logged why). */
- async function refresh() {
- if (!client) return null;
- try { return await client.refresh(); } catch { return null; }
- }
-
- async function start() {
- if (!client) return pinned;
- client.start({ intervalMs: JWKS_REFRESH_MS });
- const attempt = async () => {
- retryTimer = null;
- const got = await refresh();
- if (!loaded()) {
- retryTimer = setTimeout(attempt, JWKS_RETRY_MS);
- retryTimer.unref?.();
- }
- return got;
- };
- return await attempt();
- }
-
- function stop() {
- clearTimeout(retryTimer);
- retryTimer = null;
- if (client) client.stop();
- }
-
- async function keysFor(kid) {
- if (pinned) return [{ kid: null, key: pinned }];
- if (!client) return [];
- return await client.keysForKid(kid || null);
- }
-
- const verifyOptions = pinned ? { publicKey: pinned } : { jwks: jwksUrl, fetch: fetchImpl, log };
- return { url: jwksUrl, loaded, start, stop, refresh, keysFor, verifyOptions };
-}
-
// ── Capabilities ───────────────────────────────────────────
// ── Capabilities ───────────────────────────────────────────
/** Exact id or `family.*` grant (the rule openvibe-contracts applies to its known capabilities). */
/** Exact id or `family.*` grant (the rule openvibe-contracts applies to its known capabilities). */
@@ -328,4 +270,4 @@ function createAuth({ config, keys, store = null }) {
@@ -328,4 +270,4 @@ function createAuth({ config, keys, store = null }) {
return { verifyService, verifyUser, requireCap, appOrService, realtimeViewer };
return { verifyService, verifyUser, requireCap, appOrService, realtimeViewer };
}
}
-module.exports = { CAPS, createKeys, createAuth, hasCap, allows, verifyRealtimeTicket, serviceSlug, bearer, cookie };
+module.exports = { CAPS, createAuth, hasCap, allows, verifyRealtimeTicket, serviceSlug, bearer, cookie };
@@ -12,7 +12,8 @@ const { openDb, createStore } = require('./store');
@@ -12,7 +12,8 @@ const { openDb, createStore } = require('./store');
const { createPolicyLibrary } = require('./fabric/policy');
const { createPolicyLibrary } = require('./fabric/policy');
const { createCarriers } = require('./fabric/carriers');
const { createCarriers } = require('./fabric/carriers');
const { createPlanner } = require('./fabric/planner');
const { createPlanner } = require('./fabric/planner');
-const { createKeys, createAuth } = require('./auth');
+const { createNetworkKeys } = require('openvibe-sdk/auth');
+const { createAuth } = require('./auth');
const { createWorker } = require('./worker');
const { createWorker } = require('./worker');
const { createRealtime } = require('./realtime');
const { createRealtime } = require('./realtime');
const { createApp } = require('./app');
const { createApp } = require('./app');
@@ -38,7 +39,7 @@ async function start({
@@ -38,7 +39,7 @@ async function start({
const carriers = createCarriers({ config, clock, log, valkey });
const carriers = createCarriers({ config, clock, log, valkey });
const planner = createPlanner({ registry: carriers, db, clock, log });
const planner = createPlanner({ registry: carriers, db, clock, log });
const store = createStore(db, { clock, maxHops: config.maxHops, usage: config.usage, policies, planner });
const store = createStore(db, { clock, maxHops: config.maxHops, usage: config.usage, policies, planner });
- const keys = createKeys({ url: config.networkInternalUrl, pem: config.networkPublicKey, fetchImpl, log });
+ const keys = createNetworkKeys({ network: config.networkInternalUrl, publicKey: config.networkPublicKey, fetch: fetchImpl, log });
const auth = createAuth({ config, keys, store });
const auth = createAuth({ config, keys, store });
const metrics = createMetrics({ store });
const metrics = createMetrics({ store });
// appPost / dnsLookup: developer-app delivery and the subscribe-time DNS check (server/egress.js);
// appPost / dnsLookup: developer-app delivery and the subscribe-time DNS check (server/egress.js);