@ours.network/messenger-server 1.0.31-nightly.14 → 1.0.31-nightly.16
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
CHANGED
|
@@ -413,3 +413,25 @@ Set `OURS_NOTIFICATIONS_ORIGIN` and a Messenger-scoped `OURS_NOTIFICATIONS_PRODU
|
|
|
413
413
|
Workspace enrollment supports optional `preserveProfile: true` on its protected POST endpoint. This skips human profile creation/replacement (including an absent profile); root checks and the signed binding command remain mandatory. The protected enrollment-identity response advertises `preserveProfile: true` so clients can fail closed against older servers. Omitted/false keeps fresh-host account profile setup.
|
|
414
414
|
|
|
415
415
|
Messenger may run as the Human root or as a permanent identity under it. For the latter, the enrollment-identity response also carries `rootCid`, the root the daemon describes for the bound identity; `POST /api/identity/profile` accepts both. Only a Messenger bound to the root itself signs the workspace binding on `POST /api/workspace/enroll`; for an identity under the root the caller obtains that signature from the root outside Messenger.
|
|
416
|
+
|
|
417
|
+
After successful contact removal, the notification producer durably retires that
|
|
418
|
+
conversation through the notification service's scoped `/api/v1/delete-target`
|
|
419
|
+
route. Pending sends for that contact are removed; cleanup follows any already
|
|
420
|
+
inflight send and retries after service outages or restart. Watch replay confirms
|
|
421
|
+
absence against a complete contacts/pending inventory before dropping an event.
|
|
422
|
+
Inventory errors preserve the queue. The gateway and notification service must
|
|
423
|
+
support this producer lifecycle route before source cleanup can be delivered.
|
|
424
|
+
|
|
425
|
+
Profile-preserving workspace enrollment reuses an already authenticated contact
|
|
426
|
+
with the exact pinned enrollment server CID. This permits a fresh signed account
|
|
427
|
+
challenge after the one-time invitation was used for registration retirement;
|
|
428
|
+
account-side invitation provenance or an exact signed replacement handoff still
|
|
429
|
+
controls proof acceptance.
|
|
430
|
+
|
|
431
|
+
`POST /api/workspace/unregister` carries the first-party retirement command when
|
|
432
|
+
Messenger already holds the Human root lease. It requires local API/CSRF
|
|
433
|
+
authentication, a permanent root matching `rootCid`, the exact ready enrollment
|
|
434
|
+
server contact, and well-formed workspace/host/nonce identifiers. An optional
|
|
435
|
+
three-field replacement challenge is forwarded unchanged. The account service
|
|
436
|
+
owns retirement authorization and cleanup; this route only sends the signed
|
|
437
|
+
command and acknowledges submission.
|
|
@@ -38,7 +38,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
38
|
var define_MESSENGER_BUILD_INFO_default;
|
|
39
39
|
var init_define_MESSENGER_BUILD_INFO = __esm({
|
|
40
40
|
"<define:__MESSENGER_BUILD_INFO__>"() {
|
|
41
|
-
define_MESSENGER_BUILD_INFO_default = { name: "@ours.network/messenger-server", version: "1.0.31-nightly.
|
|
41
|
+
define_MESSENGER_BUILD_INFO_default = { name: "@ours.network/messenger-server", version: "1.0.31-nightly.16", sha: "64376e7737f42d8375850bfb548840977e7250d2", dirty: true };
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
publicEngineError,
|
|
11
11
|
publicInternalError,
|
|
12
12
|
reportFailure
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NB6YYTBL.js";
|
|
14
14
|
|
|
15
15
|
// node_modules/bn.js/lib/bn.js
|
|
16
16
|
var require_bn = __commonJS({
|
|
@@ -868,23 +868,23 @@ var require_bn = __commonJS({
|
|
|
868
868
|
var lo = r & 67108863;
|
|
869
869
|
var carry = r / 67108864 | 0;
|
|
870
870
|
out.words[0] = lo;
|
|
871
|
-
for (var
|
|
871
|
+
for (var k2 = 1; k2 < len; k2++) {
|
|
872
872
|
var ncarry = carry >>> 26;
|
|
873
873
|
var rword = carry & 67108863;
|
|
874
|
-
var maxJ = Math.min(
|
|
875
|
-
for (var j = Math.max(0,
|
|
876
|
-
var i =
|
|
874
|
+
var maxJ = Math.min(k2, num.length - 1);
|
|
875
|
+
for (var j = Math.max(0, k2 - self.length + 1); j <= maxJ; j++) {
|
|
876
|
+
var i = k2 - j | 0;
|
|
877
877
|
a = self.words[i] | 0;
|
|
878
878
|
b2 = num.words[j] | 0;
|
|
879
879
|
r = a * b2 + rword;
|
|
880
880
|
ncarry += r / 67108864 | 0;
|
|
881
881
|
rword = r & 67108863;
|
|
882
882
|
}
|
|
883
|
-
out.words[
|
|
883
|
+
out.words[k2] = rword | 0;
|
|
884
884
|
carry = ncarry | 0;
|
|
885
885
|
}
|
|
886
886
|
if (carry !== 0) {
|
|
887
|
-
out.words[
|
|
887
|
+
out.words[k2] = carry | 0;
|
|
888
888
|
} else {
|
|
889
889
|
out.length--;
|
|
890
890
|
}
|
|
@@ -1450,13 +1450,13 @@ var require_bn = __commonJS({
|
|
|
1450
1450
|
out.length = self.length + num.length;
|
|
1451
1451
|
var carry = 0;
|
|
1452
1452
|
var hncarry = 0;
|
|
1453
|
-
for (var
|
|
1453
|
+
for (var k2 = 0; k2 < out.length - 1; k2++) {
|
|
1454
1454
|
var ncarry = hncarry;
|
|
1455
1455
|
hncarry = 0;
|
|
1456
1456
|
var rword = carry & 67108863;
|
|
1457
|
-
var maxJ = Math.min(
|
|
1458
|
-
for (var j = Math.max(0,
|
|
1459
|
-
var i =
|
|
1457
|
+
var maxJ = Math.min(k2, num.length - 1);
|
|
1458
|
+
for (var j = Math.max(0, k2 - self.length + 1); j <= maxJ; j++) {
|
|
1459
|
+
var i = k2 - j;
|
|
1460
1460
|
var a = self.words[i] | 0;
|
|
1461
1461
|
var b2 = num.words[j] | 0;
|
|
1462
1462
|
var r = a * b2;
|
|
@@ -1468,12 +1468,12 @@ var require_bn = __commonJS({
|
|
|
1468
1468
|
hncarry += ncarry >>> 26;
|
|
1469
1469
|
ncarry &= 67108863;
|
|
1470
1470
|
}
|
|
1471
|
-
out.words[
|
|
1471
|
+
out.words[k2] = rword;
|
|
1472
1472
|
carry = ncarry;
|
|
1473
1473
|
ncarry = hncarry;
|
|
1474
1474
|
}
|
|
1475
1475
|
if (carry !== 0) {
|
|
1476
|
-
out.words[
|
|
1476
|
+
out.words[k2] = carry;
|
|
1477
1477
|
} else {
|
|
1478
1478
|
out.length--;
|
|
1479
1479
|
}
|
|
@@ -5479,13 +5479,13 @@ var require_ece = __commonJS({
|
|
|
5479
5479
|
var MODE_DECRYPT = "decrypt";
|
|
5480
5480
|
var keylog;
|
|
5481
5481
|
if (process.env.ECE_KEYLOG === "1") {
|
|
5482
|
-
keylog = function(m2,
|
|
5483
|
-
console.warn(m2 + " [" +
|
|
5484
|
-
return
|
|
5482
|
+
keylog = function(m2, k2) {
|
|
5483
|
+
console.warn(m2 + " [" + k2.length + "]: " + k2.toString("base64url"));
|
|
5484
|
+
return k2;
|
|
5485
5485
|
};
|
|
5486
5486
|
} else {
|
|
5487
|
-
keylog = function(m2,
|
|
5488
|
-
return
|
|
5487
|
+
keylog = function(m2, k2) {
|
|
5488
|
+
return k2;
|
|
5489
5489
|
};
|
|
5490
5490
|
}
|
|
5491
5491
|
function decode(b2) {
|
|
@@ -6559,8 +6559,8 @@ var require_node2 = __commonJS({
|
|
|
6559
6559
|
exports.inspectOpts = Object.keys(process.env).filter((key) => {
|
|
6560
6560
|
return /^debug_/i.test(key);
|
|
6561
6561
|
}).reduce((obj, key) => {
|
|
6562
|
-
const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_2,
|
|
6563
|
-
return
|
|
6562
|
+
const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_2, k2) => {
|
|
6563
|
+
return k2.toUpperCase();
|
|
6564
6564
|
});
|
|
6565
6565
|
let val = process.env[key];
|
|
6566
6566
|
if (/^(yes|on|true|enabled)$/i.test(val)) {
|
|
@@ -6646,18 +6646,18 @@ var require_helpers = __commonJS({
|
|
|
6646
6646
|
"node_modules/agent-base/dist/helpers.js"(exports) {
|
|
6647
6647
|
"use strict";
|
|
6648
6648
|
init_define_MESSENGER_BUILD_INFO();
|
|
6649
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m2,
|
|
6650
|
-
if (k22 === void 0) k22 =
|
|
6651
|
-
var desc = Object.getOwnPropertyDescriptor(m2,
|
|
6649
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m2, k2, k22) {
|
|
6650
|
+
if (k22 === void 0) k22 = k2;
|
|
6651
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k2);
|
|
6652
6652
|
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
6653
6653
|
desc = { enumerable: true, get: function() {
|
|
6654
|
-
return m2[
|
|
6654
|
+
return m2[k2];
|
|
6655
6655
|
} };
|
|
6656
6656
|
}
|
|
6657
6657
|
Object.defineProperty(o, k22, desc);
|
|
6658
|
-
}) : (function(o, m2,
|
|
6659
|
-
if (k22 === void 0) k22 =
|
|
6660
|
-
o[k22] = m2[
|
|
6658
|
+
}) : (function(o, m2, k2, k22) {
|
|
6659
|
+
if (k22 === void 0) k22 = k2;
|
|
6660
|
+
o[k22] = m2[k2];
|
|
6661
6661
|
}));
|
|
6662
6662
|
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v2) {
|
|
6663
6663
|
Object.defineProperty(o, "default", { enumerable: true, value: v2 });
|
|
@@ -6668,7 +6668,7 @@ var require_helpers = __commonJS({
|
|
|
6668
6668
|
if (mod && mod.__esModule) return mod;
|
|
6669
6669
|
var result = {};
|
|
6670
6670
|
if (mod != null) {
|
|
6671
|
-
for (var
|
|
6671
|
+
for (var k2 in mod) if (k2 !== "default" && Object.prototype.hasOwnProperty.call(mod, k2)) __createBinding(result, mod, k2);
|
|
6672
6672
|
}
|
|
6673
6673
|
__setModuleDefault(result, mod);
|
|
6674
6674
|
return result;
|
|
@@ -6717,18 +6717,18 @@ var require_dist = __commonJS({
|
|
|
6717
6717
|
"node_modules/agent-base/dist/index.js"(exports) {
|
|
6718
6718
|
"use strict";
|
|
6719
6719
|
init_define_MESSENGER_BUILD_INFO();
|
|
6720
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m2,
|
|
6721
|
-
if (k22 === void 0) k22 =
|
|
6722
|
-
var desc = Object.getOwnPropertyDescriptor(m2,
|
|
6720
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m2, k2, k22) {
|
|
6721
|
+
if (k22 === void 0) k22 = k2;
|
|
6722
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k2);
|
|
6723
6723
|
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
6724
6724
|
desc = { enumerable: true, get: function() {
|
|
6725
|
-
return m2[
|
|
6725
|
+
return m2[k2];
|
|
6726
6726
|
} };
|
|
6727
6727
|
}
|
|
6728
6728
|
Object.defineProperty(o, k22, desc);
|
|
6729
|
-
}) : (function(o, m2,
|
|
6730
|
-
if (k22 === void 0) k22 =
|
|
6731
|
-
o[k22] = m2[
|
|
6729
|
+
}) : (function(o, m2, k2, k22) {
|
|
6730
|
+
if (k22 === void 0) k22 = k2;
|
|
6731
|
+
o[k22] = m2[k2];
|
|
6732
6732
|
}));
|
|
6733
6733
|
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v2) {
|
|
6734
6734
|
Object.defineProperty(o, "default", { enumerable: true, value: v2 });
|
|
@@ -6739,7 +6739,7 @@ var require_dist = __commonJS({
|
|
|
6739
6739
|
if (mod && mod.__esModule) return mod;
|
|
6740
6740
|
var result = {};
|
|
6741
6741
|
if (mod != null) {
|
|
6742
|
-
for (var
|
|
6742
|
+
for (var k2 in mod) if (k2 !== "default" && Object.prototype.hasOwnProperty.call(mod, k2)) __createBinding(result, mod, k2);
|
|
6743
6743
|
}
|
|
6744
6744
|
__setModuleDefault(result, mod);
|
|
6745
6745
|
return result;
|
|
@@ -6971,18 +6971,18 @@ var require_dist2 = __commonJS({
|
|
|
6971
6971
|
"node_modules/https-proxy-agent/dist/index.js"(exports) {
|
|
6972
6972
|
"use strict";
|
|
6973
6973
|
init_define_MESSENGER_BUILD_INFO();
|
|
6974
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m2,
|
|
6975
|
-
if (k22 === void 0) k22 =
|
|
6976
|
-
var desc = Object.getOwnPropertyDescriptor(m2,
|
|
6974
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m2, k2, k22) {
|
|
6975
|
+
if (k22 === void 0) k22 = k2;
|
|
6976
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k2);
|
|
6977
6977
|
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
6978
6978
|
desc = { enumerable: true, get: function() {
|
|
6979
|
-
return m2[
|
|
6979
|
+
return m2[k2];
|
|
6980
6980
|
} };
|
|
6981
6981
|
}
|
|
6982
6982
|
Object.defineProperty(o, k22, desc);
|
|
6983
|
-
}) : (function(o, m2,
|
|
6984
|
-
if (k22 === void 0) k22 =
|
|
6985
|
-
o[k22] = m2[
|
|
6983
|
+
}) : (function(o, m2, k2, k22) {
|
|
6984
|
+
if (k22 === void 0) k22 = k2;
|
|
6985
|
+
o[k22] = m2[k2];
|
|
6986
6986
|
}));
|
|
6987
6987
|
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v2) {
|
|
6988
6988
|
Object.defineProperty(o, "default", { enumerable: true, value: v2 });
|
|
@@ -6993,7 +6993,7 @@ var require_dist2 = __commonJS({
|
|
|
6993
6993
|
if (mod && mod.__esModule) return mod;
|
|
6994
6994
|
var result = {};
|
|
6995
6995
|
if (mod != null) {
|
|
6996
|
-
for (var
|
|
6996
|
+
for (var k2 in mod) if (k2 !== "default" && Object.prototype.hasOwnProperty.call(mod, k2)) __createBinding(result, mod, k2);
|
|
6997
6997
|
}
|
|
6998
6998
|
__setModuleDefault(result, mod);
|
|
6999
6999
|
return result;
|
|
@@ -9656,10 +9656,10 @@ var require_extension = __commonJS({
|
|
|
9656
9656
|
if (!Array.isArray(configurations)) configurations = [configurations];
|
|
9657
9657
|
return configurations.map((params) => {
|
|
9658
9658
|
return [extension2].concat(
|
|
9659
|
-
Object.keys(params).map((
|
|
9660
|
-
let values = params[
|
|
9659
|
+
Object.keys(params).map((k2) => {
|
|
9660
|
+
let values = params[k2];
|
|
9661
9661
|
if (!Array.isArray(values)) values = [values];
|
|
9662
|
-
return values.map((v2) => v2 === true ?
|
|
9662
|
+
return values.map((v2) => v2 === true ? k2 : `${k2}=${v2}`).join("; ");
|
|
9663
9663
|
})
|
|
9664
9664
|
).join("; ");
|
|
9665
9665
|
}).join(", ");
|
|
@@ -11131,11 +11131,12 @@ function producerConfig(env = process.env) {
|
|
|
11131
11131
|
}
|
|
11132
11132
|
var NotificationOutbox = class {
|
|
11133
11133
|
constructor(file, config, project, warn = () => {
|
|
11134
|
-
}) {
|
|
11134
|
+
}, shouldRetire) {
|
|
11135
11135
|
this.file = file;
|
|
11136
11136
|
this.config = config;
|
|
11137
11137
|
this.project = project;
|
|
11138
11138
|
this.warn = warn;
|
|
11139
|
+
this.shouldRetire = shouldRetire;
|
|
11139
11140
|
mkdirSync(dirname(file), { recursive: true, mode: 448 });
|
|
11140
11141
|
const saved = existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : { entries: [] };
|
|
11141
11142
|
this.entries = Array.isArray(saved) ? saved : saved.entries;
|
|
@@ -11186,6 +11187,12 @@ var NotificationOutbox = class {
|
|
|
11186
11187
|
this.persist([...this.entries, { id, value }], cursor);
|
|
11187
11188
|
return true;
|
|
11188
11189
|
}
|
|
11190
|
+
retireTarget(url, matches) {
|
|
11191
|
+
const id = `delete-target:${url}`;
|
|
11192
|
+
const retained = this.entries.filter((entry) => entry.operation === "delete-target" || !matches(entry.value, entry.payload));
|
|
11193
|
+
if (!retained.some((entry) => entry.id === id)) retained.push({ id, value: { url }, operation: "delete-target" });
|
|
11194
|
+
this.persist(retained);
|
|
11195
|
+
}
|
|
11189
11196
|
drain() {
|
|
11190
11197
|
return this.running ??= this.drainOnce().finally(() => {
|
|
11191
11198
|
this.running = void 0;
|
|
@@ -11194,9 +11201,15 @@ var NotificationOutbox = class {
|
|
|
11194
11201
|
async drainOnce() {
|
|
11195
11202
|
for (const entry of [...this.entries].slice(0, 32)) {
|
|
11196
11203
|
try {
|
|
11197
|
-
|
|
11198
|
-
|
|
11199
|
-
|
|
11204
|
+
if (!this.entries.some((current) => current.id === entry.id)) continue;
|
|
11205
|
+
const value = entry.operation === "delete-target" ? this.shouldRetire && !await this.shouldRetire(entry.value.url) ? void 0 : entry.value : entry.payload ?? await this.project(entry.value, entry.id);
|
|
11206
|
+
if (!this.entries.some((current) => current.id === entry.id)) continue;
|
|
11207
|
+
if (value === void 0) {
|
|
11208
|
+
this.persist(this.entries.filter((current) => current.id !== entry.id));
|
|
11209
|
+
continue;
|
|
11210
|
+
}
|
|
11211
|
+
if (!entry.operation && !entry.payload) this.persist(this.entries.map((e2) => e2.id === entry.id ? { ...e2, payload: value } : e2));
|
|
11212
|
+
const response = await fetch(this.config.origin + (entry.operation === "delete-target" ? "/api/v1/delete-target" : "/api/v1/send"), {
|
|
11200
11213
|
method: "POST",
|
|
11201
11214
|
redirect: "error",
|
|
11202
11215
|
signal: AbortSignal.timeout(1e4),
|
|
@@ -11643,8 +11656,15 @@ var PushDeliveryQueue = class {
|
|
|
11643
11656
|
var MessengerNotificationProducer = class {
|
|
11644
11657
|
constructor(stateDir, config, identityCid, client, warn) {
|
|
11645
11658
|
this.identityCid = identityCid;
|
|
11659
|
+
const knownContact = async (cid) => {
|
|
11660
|
+
if (!client.listContacts) return void 0;
|
|
11661
|
+
const view = await client.listContacts();
|
|
11662
|
+
if (!Array.isArray(view.contacts) || !Array.isArray(view.pending) || [...view.contacts, ...view.pending].some((contact) => typeof contact?.container_id !== "string")) throw Error("Contact inventory unavailable");
|
|
11663
|
+
return [...view.contacts, ...view.pending].some((contact) => contact.container_id.toLowerCase() === cid.toLowerCase());
|
|
11664
|
+
};
|
|
11646
11665
|
this.outbox = new NotificationOutbox(join(stateDir, "notification-outbox.json"), config, async (value, eventId) => {
|
|
11647
11666
|
const record = value;
|
|
11667
|
+
if (await knownContact(record.sender_id) === false) return;
|
|
11648
11668
|
const event = await projectPushEvent(client, {
|
|
11649
11669
|
contactId: record.sender_id,
|
|
11650
11670
|
wireId: record.wire_id,
|
|
@@ -11657,7 +11677,7 @@ var MessengerNotificationProducer = class {
|
|
|
11657
11677
|
body: event.body.slice(0, 512) || "New message",
|
|
11658
11678
|
url: `/fleet/chats?source=messenger&chat=${encodeURIComponent(record.sender_id)}&detail=1#chat-message-${encodeURIComponent(record.wire_id)}`
|
|
11659
11679
|
};
|
|
11660
|
-
}, warn);
|
|
11680
|
+
}, warn, async (url) => await knownContact(new URL(url, "https://ours.invalid").searchParams.get("chat")) !== true);
|
|
11661
11681
|
}
|
|
11662
11682
|
outbox;
|
|
11663
11683
|
admit(record) {
|
|
@@ -11670,6 +11690,21 @@ var MessengerNotificationProducer = class {
|
|
|
11670
11690
|
});
|
|
11671
11691
|
return { status: admitted ? "queued" : "saturated" };
|
|
11672
11692
|
}
|
|
11693
|
+
retireContact(cid) {
|
|
11694
|
+
const url = `/fleet/chats?source=messenger&chat=${encodeURIComponent(cid)}`;
|
|
11695
|
+
this.outbox.retireTarget(url, (value, payload) => {
|
|
11696
|
+
const record = value;
|
|
11697
|
+
if (typeof record?.sender_id === "string" && record.sender_id.toLowerCase() === cid.toLowerCase()) return true;
|
|
11698
|
+
if (!payload) return false;
|
|
11699
|
+
try {
|
|
11700
|
+
const target = new URL(payload.url, "https://ours.invalid");
|
|
11701
|
+
return target.pathname === "/fleet/chats" && target.searchParams.get("source") === "messenger" && target.searchParams.get("chat")?.toLowerCase() === cid.toLowerCase();
|
|
11702
|
+
} catch {
|
|
11703
|
+
return false;
|
|
11704
|
+
}
|
|
11705
|
+
});
|
|
11706
|
+
void this.outbox.drain();
|
|
11707
|
+
}
|
|
11673
11708
|
close() {
|
|
11674
11709
|
return this.outbox.close();
|
|
11675
11710
|
}
|
|
@@ -20999,7 +21034,13 @@ var ROUTES = {
|
|
|
20999
21034
|
// operation: roots ride along on the contacts view.
|
|
21000
21035
|
"GET /api/contacts/roots": async ({ client }) => ({ roots: (await client.listContacts()).roots }),
|
|
21001
21036
|
"POST /api/contacts/add": async ({ client, body }) => client.addContact({ invite: str(body, "invite"), name: optStr(body, "name") }),
|
|
21002
|
-
"POST /api/contacts/remove": async ({ client, body }) =>
|
|
21037
|
+
"POST /api/contacts/remove": async ({ client, body, deps }) => {
|
|
21038
|
+
const contact = str(body, "contact");
|
|
21039
|
+
const canonical3 = deps.retireContactNotifications ? (await resolveContact(client, contact)).cid : contact;
|
|
21040
|
+
const result = await client.removeContact({ contact: canonical3 });
|
|
21041
|
+
deps.retireContactNotifications?.(canonical3);
|
|
21042
|
+
return result;
|
|
21043
|
+
},
|
|
21003
21044
|
"POST /api/contacts/rename": async ({ client, body }) => client.renameContact({ contact: str(body, "contact"), name: str(body, "name") }),
|
|
21004
21045
|
"GET /api/contacts/local-book": async ({ client }) => client.listLocalContactBook(),
|
|
21005
21046
|
"POST /api/contacts/local-book/policy": async ({ client, body }) => client.setLocalBookPolicy({ expose: optBool(body, "expose"), auto_accept: optBool(body, "auto_accept") }),
|
|
@@ -21038,13 +21079,38 @@ var ROUTES = {
|
|
|
21038
21079
|
return human.rootCid === void 0 ? { cid: identity.cid, preserveProfile: true } : { cid: identity.cid, rootCid: human.rootCid, preserveProfile: true };
|
|
21039
21080
|
},
|
|
21040
21081
|
// First-party setup operation: daemon signs the command using this bound root.
|
|
21082
|
+
"POST /api/workspace/unregister": async ({ client, body }) => {
|
|
21083
|
+
const identity = await client.currentIdentity();
|
|
21084
|
+
if (!identity.isRoot || identity.temporary) throw bad("Workspace retirement requires the bound Human root");
|
|
21085
|
+
const rootCid = str(body, "rootCid").toUpperCase(), serverCid = str(body, "serverCid").toUpperCase();
|
|
21086
|
+
if (!/^[A-F0-9]{64}$/.test(rootCid) || !/^[A-F0-9]{64}$/.test(serverCid) || identity.cid.toUpperCase() !== rootCid) throw bad("Workspace retirement identity mismatch");
|
|
21087
|
+
const command = { type: "ours.app.unregister-workspace.v1" };
|
|
21088
|
+
for (const key of ["workspaceId", "hostWorkspaceId", "operationNonce"]) {
|
|
21089
|
+
const value = str(body, key);
|
|
21090
|
+
if (!/^[A-Za-z0-9_-]{43}$/.test(value)) throw bad("Invalid workspace retirement");
|
|
21091
|
+
command[key] = value;
|
|
21092
|
+
}
|
|
21093
|
+
if (body.operationExpiresAt !== void 0) {
|
|
21094
|
+
if (!Number.isSafeInteger(body.operationExpiresAt) || Number(body.operationExpiresAt) <= 0 || Number(body.operationExpiresAt) > Date.now() + 864e5) throw bad("Invalid retirement deadline");
|
|
21095
|
+
command.operationExpiresAt = Number(body.operationExpiresAt);
|
|
21096
|
+
}
|
|
21097
|
+
if (body.replacement !== void 0) {
|
|
21098
|
+
const replacement = body.replacement;
|
|
21099
|
+
if (!replacement || typeof replacement !== "object" || Object.keys(replacement).length !== 3 || !["workspaceId", "accountId", "nonce"].every((key) => typeof replacement[key] === "string" && /^[A-Za-z0-9_-]{43}$/.test(replacement[key]))) throw bad("Invalid replacement challenge");
|
|
21100
|
+
command.replacement = Object.fromEntries(["workspaceId", "accountId", "nonce"].map((key) => [key, replacement[key]]));
|
|
21101
|
+
}
|
|
21102
|
+
if (!(await client.listContacts()).contacts.some((contact) => contact.container_id.toUpperCase() === serverCid)) throw bad("Original enrollment contact is not ready");
|
|
21103
|
+
const outcome = await client.sendCommand({ contact: serverCid, command: "unregister-workspace", arguments: command });
|
|
21104
|
+
if (!("sent" in outcome) || !outcome.sent) throw bad("Workspace retirement was not sent");
|
|
21105
|
+
return { submitted: true, rootCid: identity.cid };
|
|
21106
|
+
},
|
|
21041
21107
|
"POST /api/workspace/enroll": async ({ client, deps, body }) => {
|
|
21042
21108
|
const identity = await client.currentIdentity();
|
|
21043
21109
|
if (!identity.isRoot || identity.temporary) throw bad("Workspace proof requires the bound Human root");
|
|
21044
21110
|
const serverCid = str(body, "serverCid").toUpperCase();
|
|
21045
21111
|
if (!/^[A-F0-9]{64}$/.test(serverCid) || !/^[A-Za-z0-9_-]{43}$/.test(str(body, "hostWorkspaceId"))) throw bad("Invalid workspace proof");
|
|
21046
21112
|
const challenge = body.challenge;
|
|
21047
|
-
if (!challenge || !["nonce", "workspaceId", "accountId"].every((
|
|
21113
|
+
if (!challenge || !["nonce", "workspaceId", "accountId"].every((k2) => typeof challenge[k2] === "string" && /^[A-Za-z0-9_-]{43}$/.test(String(challenge[k2]))) || !Number.isFinite(challenge.expiresAt) || Number(challenge.expiresAt) <= Date.now() || Number(challenge.expiresAt) > Date.now() + 16 * 6e4) throw bad("Workspace challenge expired or invalid");
|
|
21048
21114
|
const preserveProfile = optBool(body, "preserveProfile") === true;
|
|
21049
21115
|
let humanProfile;
|
|
21050
21116
|
if (!preserveProfile) try {
|
|
@@ -21055,8 +21121,11 @@ var ROUTES = {
|
|
|
21055
21121
|
const invitation = str(body, "invitation");
|
|
21056
21122
|
if (invitation.length > 8192) throw bad("Workspace invitation too large");
|
|
21057
21123
|
if (humanProfile) writeHumanProfile(deps.config.stateDir, deps.identityCid, humanProfile);
|
|
21058
|
-
const
|
|
21059
|
-
if (
|
|
21124
|
+
const connected = preserveProfile && (await client.listContacts()).contacts.some((contact) => contact.container_id.toUpperCase() === serverCid);
|
|
21125
|
+
if (!connected) {
|
|
21126
|
+
const peer = await client.addContact({ invite: invitation });
|
|
21127
|
+
if (peer.cid.toUpperCase() !== serverCid) throw bad("Enrollment server identity mismatch");
|
|
21128
|
+
}
|
|
21060
21129
|
const contactDeadline = Date.now() + 1e4;
|
|
21061
21130
|
while (!(await client.listContacts()).contacts.some((contact) => contact.container_id.toUpperCase() === serverCid)) {
|
|
21062
21131
|
if (Date.now() >= contactDeadline) throw bad("Enrollment contact is not ready; obtain a fresh setup payload before retrying");
|
|
@@ -21200,15 +21269,15 @@ var ROUTES = {
|
|
|
21200
21269
|
if (keys === null || typeof keys !== "object" || Array.isArray(keys)) {
|
|
21201
21270
|
throw bad("keys must be an object with p256dh and auth");
|
|
21202
21271
|
}
|
|
21203
|
-
const
|
|
21204
|
-
if (typeof
|
|
21272
|
+
const k2 = keys;
|
|
21273
|
+
if (typeof k2.p256dh !== "string" || typeof k2.auth !== "string") {
|
|
21205
21274
|
throw bad("keys.p256dh and keys.auth must be strings");
|
|
21206
21275
|
}
|
|
21207
21276
|
let saved;
|
|
21208
21277
|
try {
|
|
21209
21278
|
saved = deps.push.ensure({
|
|
21210
21279
|
endpoint: str(body, "endpoint"),
|
|
21211
|
-
keys: { p256dh:
|
|
21280
|
+
keys: { p256dh: k2.p256dh, auth: k2.auth },
|
|
21212
21281
|
label: optStr(body, "label"),
|
|
21213
21282
|
preview: body.preview === void 0 ? void 0 : str(body, "preview"),
|
|
21214
21283
|
bindingId: optStr(body, "binding_id")
|
|
@@ -21347,18 +21416,18 @@ import { randomBytes as randomBytes2 } from "node:crypto";
|
|
|
21347
21416
|
// node_modules/@ours.network/sdk/dist/index.js
|
|
21348
21417
|
init_define_MESSENGER_BUILD_INFO();
|
|
21349
21418
|
|
|
21350
|
-
// node_modules/@ours.network/sdk/dist/chunk-
|
|
21419
|
+
// node_modules/@ours.network/sdk/dist/chunk-VJJU7HLN.js
|
|
21351
21420
|
init_define_MESSENGER_BUILD_INFO();
|
|
21352
21421
|
|
|
21353
|
-
// node_modules/@ours.network/sdk/dist/chunk-
|
|
21422
|
+
// node_modules/@ours.network/sdk/dist/chunk-SHYFSAAM.js
|
|
21354
21423
|
init_define_MESSENGER_BUILD_INFO();
|
|
21355
21424
|
import * as e from "node:fs";
|
|
21356
|
-
import { randomBytes as
|
|
21357
|
-
import { dirname as p, isAbsolute as
|
|
21358
|
-
import { homedir as
|
|
21359
|
-
import { resolve as
|
|
21425
|
+
import { randomBytes as m } from "node:crypto";
|
|
21426
|
+
import { dirname as p, isAbsolute as b, resolve as v } from "node:path";
|
|
21427
|
+
import { homedir as T } from "node:os";
|
|
21428
|
+
import { resolve as _, join as A, dirname as h, basename as R } from "node:path";
|
|
21360
21429
|
function u(t, o = false) {
|
|
21361
|
-
if (typeof process.geteuid != "function" || !e.constants.O_NOFOLLOW || !e.constants.O_NONBLOCK || typeof t != "string" || !
|
|
21430
|
+
if (typeof process.geteuid != "function" || !e.constants.O_NOFOLLOW || !e.constants.O_NONBLOCK || typeof t != "string" || !b(t) || v(t) !== t) throw new Error();
|
|
21362
21431
|
let s = process.geteuid(), r = [];
|
|
21363
21432
|
for (let i = p(t); r.unshift(i), i !== p(i); i = p(i)) ;
|
|
21364
21433
|
return r.map((i, l) => {
|
|
@@ -21375,36 +21444,36 @@ function u(t, o = false) {
|
|
|
21375
21444
|
n = e.lstatSync(i);
|
|
21376
21445
|
}
|
|
21377
21446
|
if (!n.isDirectory() || n.uid !== 0 && n.uid !== s) throw new Error();
|
|
21378
|
-
let
|
|
21379
|
-
if (n.mode & 18 && !
|
|
21447
|
+
let a = n.uid === 0 && (n.mode & 512) !== 0;
|
|
21448
|
+
if (n.mode & 18 && !a) throw new Error();
|
|
21380
21449
|
if (l === r.length - 1 && (n.uid !== s || (n.mode & 4095) !== 448)) throw new Error();
|
|
21381
21450
|
return `${n.dev}:${n.ino}:${n.uid}:${n.gid}:${n.mode}`;
|
|
21382
21451
|
}).join("|");
|
|
21383
21452
|
}
|
|
21384
|
-
function
|
|
21453
|
+
function O(t, o = 65536, s = false) {
|
|
21385
21454
|
let r;
|
|
21386
21455
|
try {
|
|
21387
|
-
let i = u(t), l = process.geteuid(), n = (
|
|
21388
|
-
if (!
|
|
21389
|
-
return `${
|
|
21390
|
-
},
|
|
21456
|
+
let i = u(t), l = process.geteuid(), n = (c) => {
|
|
21457
|
+
if (!c.isFile() || c.uid !== l || (c.mode & 4095) !== 384 || c.size < 1 || c.size > o) throw new Error();
|
|
21458
|
+
return `${c.dev}:${c.ino}:${c.uid}:${c.gid}:${c.mode}:${c.size}:${c.mtimeMs}:${c.ctimeMs}`;
|
|
21459
|
+
}, a = n(e.lstatSync(t));
|
|
21391
21460
|
r = e.openSync(t, e.constants.O_RDONLY | e.constants.O_NOFOLLOW | e.constants.O_NONBLOCK);
|
|
21392
21461
|
let d2 = e.fstatSync(r);
|
|
21393
|
-
if (n(d2) !==
|
|
21462
|
+
if (n(d2) !== a || u(t) !== i || n(e.lstatSync(t)) !== a) throw new Error();
|
|
21394
21463
|
let f = Buffer.alloc(d2.size);
|
|
21395
|
-
if (e.readSync(r, f, 0, f.length, 0) !== f.length || n(e.fstatSync(r)) !==
|
|
21464
|
+
if (e.readSync(r, f, 0, f.length, 0) !== f.length || n(e.fstatSync(r)) !== a || u(t) !== i || n(e.lstatSync(t)) !== a) throw new Error();
|
|
21396
21465
|
if (s) {
|
|
21397
21466
|
e.fsyncSync(r);
|
|
21398
|
-
for (let
|
|
21399
|
-
let S = e.openSync(
|
|
21467
|
+
for (let c = p(t); ; c = p(c)) {
|
|
21468
|
+
let S = e.openSync(c, e.constants.O_RDONLY | e.constants.O_DIRECTORY | e.constants.O_NOFOLLOW);
|
|
21400
21469
|
try {
|
|
21401
21470
|
e.fsyncSync(S);
|
|
21402
21471
|
} finally {
|
|
21403
21472
|
e.closeSync(S);
|
|
21404
21473
|
}
|
|
21405
|
-
if (
|
|
21474
|
+
if (c === p(c)) break;
|
|
21406
21475
|
}
|
|
21407
|
-
if (u(t) !== i || n(e.lstatSync(t)) !==
|
|
21476
|
+
if (u(t) !== i || n(e.lstatSync(t)) !== a) throw new Error();
|
|
21408
21477
|
}
|
|
21409
21478
|
return f;
|
|
21410
21479
|
} catch {
|
|
@@ -21413,24 +21482,24 @@ function m(t, o = 65536, s = false) {
|
|
|
21413
21482
|
r !== void 0 && e.closeSync(r);
|
|
21414
21483
|
}
|
|
21415
21484
|
}
|
|
21416
|
-
function
|
|
21485
|
+
function w(t, o) {
|
|
21417
21486
|
let s, r;
|
|
21418
21487
|
try {
|
|
21419
21488
|
try {
|
|
21420
|
-
return e.lstatSync(t), { token:
|
|
21489
|
+
return e.lstatSync(t), { token: g(t), source: "file" };
|
|
21421
21490
|
} catch (f) {
|
|
21422
21491
|
if (f.code !== "ENOENT") throw f;
|
|
21423
21492
|
}
|
|
21424
21493
|
if (!o) return null;
|
|
21425
|
-
let i = u(t, true), l =
|
|
21494
|
+
let i = u(t, true), l = m(32).toString("hex"), n = `${t}.${m(16).toString("hex")}.tmp`;
|
|
21426
21495
|
if (r = e.openSync(n, e.constants.O_WRONLY | e.constants.O_CREAT | e.constants.O_EXCL | e.constants.O_NOFOLLOW, 384), s = n, e.fchmodSync(r, 384), e.writeFileSync(r, `${l}
|
|
21427
21496
|
`), e.fsyncSync(r), e.closeSync(r), r = void 0, u(t) !== i) throw new Error();
|
|
21428
|
-
let
|
|
21497
|
+
let a = "generated";
|
|
21429
21498
|
try {
|
|
21430
21499
|
e.linkSync(s, t);
|
|
21431
21500
|
} catch (f) {
|
|
21432
21501
|
if (f.code !== "EEXIST") throw f;
|
|
21433
|
-
|
|
21502
|
+
a = "file";
|
|
21434
21503
|
}
|
|
21435
21504
|
e.unlinkSync(s), s = void 0;
|
|
21436
21505
|
let d2 = e.openSync(p(t), e.constants.O_RDONLY | e.constants.O_DIRECTORY | e.constants.O_NOFOLLOW);
|
|
@@ -21439,29 +21508,29 @@ function T(t, o) {
|
|
|
21439
21508
|
} finally {
|
|
21440
21509
|
e.closeSync(d2);
|
|
21441
21510
|
}
|
|
21442
|
-
return { token:
|
|
21511
|
+
return { token: g(t), source: a };
|
|
21443
21512
|
} catch {
|
|
21444
21513
|
throw new Error("Credential publication or reuse failed; no in-memory fallback or automatic repair");
|
|
21445
21514
|
} finally {
|
|
21446
21515
|
r !== void 0 && e.closeSync(r), s !== void 0 && e.unlinkSync(s);
|
|
21447
21516
|
}
|
|
21448
21517
|
}
|
|
21449
|
-
function
|
|
21450
|
-
let o =
|
|
21518
|
+
function g(t) {
|
|
21519
|
+
let o = O(t, 4096).toString("utf8");
|
|
21451
21520
|
if (!/^[\x21-\x7e]+(?:\r?\n)?$/.test(o)) throw new Error("Credential file contains an invalid token");
|
|
21452
21521
|
return o.trimEnd();
|
|
21453
21522
|
}
|
|
21454
|
-
var
|
|
21455
|
-
var $2 = { brokerUrl: "wss://broker1.ours.network", port: 3050, stateDir:
|
|
21523
|
+
var I = 100 * 1024 * 1024;
|
|
21524
|
+
var $2 = { brokerUrl: "wss://broker1.ours.network", port: 3050, stateDir: _(T(), ".ours"), gcIntervalMs: 36e5, historyMaxBytes: I, apiVisibility: "owner", apiAuthMode: "legacy" };
|
|
21456
21525
|
var K = "daemon-token";
|
|
21457
21526
|
|
|
21458
|
-
// node_modules/@ours.network/sdk/dist/chunk-
|
|
21527
|
+
// node_modules/@ours.network/sdk/dist/chunk-VJJU7HLN.js
|
|
21459
21528
|
import { homedir as me } from "node:os";
|
|
21460
21529
|
import { isAbsolute as ye, join as ge, resolve as ne } from "node:path";
|
|
21461
21530
|
import { randomBytes as V } from "node:crypto";
|
|
21462
21531
|
import { readFileSync as Ee } from "node:fs";
|
|
21463
21532
|
import { homedir as ve } from "node:os";
|
|
21464
|
-
import { join as
|
|
21533
|
+
import { join as M2, resolve as P } from "node:path";
|
|
21465
21534
|
var d = class extends Error {
|
|
21466
21535
|
constructor(n, r, i) {
|
|
21467
21536
|
super(r);
|
|
@@ -21555,7 +21624,7 @@ var x = class {
|
|
|
21555
21624
|
explicitApiToken;
|
|
21556
21625
|
credentialPath;
|
|
21557
21626
|
get apiToken() {
|
|
21558
|
-
return this.credentialPath === void 0 ? this.explicitApiToken :
|
|
21627
|
+
return this.credentialPath === void 0 ? this.explicitApiToken : g(this.credentialPath);
|
|
21559
21628
|
}
|
|
21560
21629
|
fetchImpl;
|
|
21561
21630
|
commandHandlers = /* @__PURE__ */ new Map();
|
|
@@ -21897,7 +21966,7 @@ function we(e2) {
|
|
|
21897
21966
|
function re(e2 = process.env) {
|
|
21898
21967
|
let t = he(e2), n;
|
|
21899
21968
|
try {
|
|
21900
|
-
n = JSON.parse(
|
|
21969
|
+
n = JSON.parse(O(t).toString("utf8"));
|
|
21901
21970
|
} catch {
|
|
21902
21971
|
throw new O2("selected profile is missing, invalid JSON or unsafe; require a 0700 directory and a 0600 regular file");
|
|
21903
21972
|
}
|
|
@@ -21928,13 +21997,13 @@ function Oe(e2 = {}) {
|
|
|
21928
21997
|
let t = e2.env ?? process.env;
|
|
21929
21998
|
if (t.OURS_TLS_CERT !== void 0 || t.OURS_TLS_KEY !== void 0) throw new p2("INCOHERENT_SELECTION", "Daemon TLS is not supported in V1; remove OURS_TLS_CERT/OURS_TLS_KEY and explicitly configure HTTP");
|
|
21930
21999
|
if (e2.endpoint !== void 0 && new URL(e2.endpoint).protocol !== "http:" && new URL(e2.endpoint).protocol !== "https:") throw new p2("INCOHERENT_SELECTION", "Client requires an HTTP or HTTPS daemon endpoint");
|
|
21931
|
-
let n = e2.readTextFile ?? ((E) => Ee(E, "utf8")), r = e2.homeDir ?? ve(), i =
|
|
22000
|
+
let n = e2.readTextFile ?? ((E) => Ee(E, "utf8")), r = e2.homeDir ?? ve(), i = k(t, "OURS_INSTANCE");
|
|
21932
22001
|
if (i !== void 0) throw new p2("INCOHERENT_SELECTION", `OURS_INSTANCE=${JSON.stringify(i)} is set, but named daemon instances are not implemented. Select the daemon with an explicit endpoint/port option or with OURS_PORT, and unset OURS_INSTANCE.`);
|
|
21933
22002
|
if (e2.stateDir !== void 0 && e2.expectStateDir !== void 0) {
|
|
21934
22003
|
let E = P(e2.stateDir), T2 = P(e2.expectStateDir);
|
|
21935
22004
|
if (E !== T2) throw new p2("INCOHERENT_SELECTION", `stateDir ${JSON.stringify(E)} and expectStateDir ${JSON.stringify(T2)} name different directories. The state directory decides which token is read; the expected one decides which daemon that token may be sent to. Reconcile them, or pass only one.`);
|
|
21936
22005
|
}
|
|
21937
|
-
let o = Re(e2.configPath,
|
|
22006
|
+
let o = Re(e2.configPath, k(t, "OURS_CONFIG")), s = o ? Se(o.value, n) : {}, a = ie(e2.port, Ae(k(t, "OURS_PORT")), s.port, oe), c = ie(e2.stateDir ?? e2.expectStateDir, k(t, "OURS_STATE_DIR"), s.stateDir, M2(r, _e)), l = { value: P(c.value), source: c.source }, m2 = e2.endpoint !== void 0 ? { value: y(e2.endpoint), source: "explicit" } : { value: `http://127.0.0.1:${a.value}`, source: a.source }, f = k(t, "OURS_API_TOKEN");
|
|
21938
22007
|
Te({ endpointSelected: e2.endpoint !== void 0 || a.source !== "default", endpointSource: m2.source, stateDirIntentional: Ie.includes(l.source), stateDirSource: l.source, hasExplicitToken: e2.token !== void 0 && e2.token !== "", hasEnvToken: f !== void 0, requireExplicitSelection: e2.requireExplicitSelection === true, portSource: a.source });
|
|
21939
22008
|
let g2 = be(e2.token, f, s, l, e2.readTextFile);
|
|
21940
22009
|
return { baseUrl: m2, port: a, stateDir: l, expectStateDir: e2.expectStateDir !== void 0 ? P(e2.expectStateDir) : l.value, ...g2 ? { token: g2 } : {}, ...o ? { configPath: o } : {} };
|
|
@@ -21957,11 +22026,11 @@ function be(e2, t, n, r, i) {
|
|
|
21957
22026
|
let o = n.apiToken?.trim();
|
|
21958
22027
|
if (o) return { value: o, source: "config-file" };
|
|
21959
22028
|
if (i === void 0) {
|
|
21960
|
-
let s =
|
|
22029
|
+
let s = w(M2(r.value, J), false);
|
|
21961
22030
|
return s ? { value: s.token, source: "token-file" } : void 0;
|
|
21962
22031
|
}
|
|
21963
22032
|
try {
|
|
21964
|
-
let s = i(
|
|
22033
|
+
let s = i(M2(r.value, J)).trim();
|
|
21965
22034
|
if (s) return { value: s, source: "token-file" };
|
|
21966
22035
|
} catch {
|
|
21967
22036
|
}
|
|
@@ -22002,7 +22071,7 @@ function Se(e2, t) {
|
|
|
22002
22071
|
}
|
|
22003
22072
|
return o;
|
|
22004
22073
|
}
|
|
22005
|
-
function
|
|
22074
|
+
function k(e2, t) {
|
|
22006
22075
|
let n = e2[t];
|
|
22007
22076
|
if (n === void 0) return;
|
|
22008
22077
|
let r = n.trim();
|
|
@@ -22063,18 +22132,18 @@ async function G(e2 = {}) {
|
|
|
22063
22132
|
if (i === "external") _2.includes("external-sessions-v1") || _2.push("external-sessions-v1");
|
|
22064
22133
|
else if (_2.includes("external-sessions-v1")) throw new Error("External capabilities require explicit sessionMode: external; refusing local-mode fallback");
|
|
22065
22134
|
{
|
|
22066
|
-
let b2 = await globalThis.fetch(u2(T2, "/selection"), { signal: s ? AbortSignal.any([s, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3), redirect: "error" }),
|
|
22067
|
-
if (!b2.ok || !
|
|
22068
|
-
let j =
|
|
22135
|
+
let b2 = await globalThis.fetch(u2(T2, "/selection"), { signal: s ? AbortSignal.any([s, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3), redirect: "error" }), I2 = await F(b2);
|
|
22136
|
+
if (!b2.ok || !I2 || Object.keys(I2).length !== 3 || Object.keys(I2).some((S) => !["schema", "instanceId", "capabilities"].includes(S)) || I2.schema !== 1 || I2.instanceId !== a) throw new Error("Daemon instance selection metadata is absent, incompatible or mismatched");
|
|
22137
|
+
let j = I2.capabilities;
|
|
22069
22138
|
if (!Array.isArray(j) || j.some((S) => typeof S != "string") || _2.some((S) => !j.includes(S))) throw new Error("Daemon does not support the required capabilities; refusing local-mode fallback");
|
|
22070
22139
|
}
|
|
22071
|
-
let H = l === void 0 ? E :
|
|
22140
|
+
let H = l === void 0 ? E : g(l);
|
|
22072
22141
|
if (typeof H != "string" || !H.trim()) throw new Error("Instance selection requires an explicit API token after daemon verification");
|
|
22073
22142
|
return new x({ url: T2, sessionMode: i, requestSignal: s, ...l === void 0 ? { apiToken: H } : { credentialPath: l }, leaseToken: n ?? V(32).toString("hex"), clientPid: r });
|
|
22074
22143
|
}
|
|
22075
22144
|
if (c !== void 0) throw new Error("Capability selection requires an expected daemon instance");
|
|
22076
22145
|
let f = Oe(m2);
|
|
22077
|
-
return await Ne(f, { fetch: o }), new x({ url: f.baseUrl.value, leaseToken: n ?? V(32).toString("hex"), clientPid: r, ...f.token?.source === "token-file" && m2.readTextFile === void 0 ? { credentialPath:
|
|
22146
|
+
return await Ne(f, { fetch: o }), new x({ url: f.baseUrl.value, leaseToken: n ?? V(32).toString("hex"), clientPid: r, ...f.token?.source === "token-file" && m2.readTextFile === void 0 ? { credentialPath: M2(f.expectStateDir, J) } : { apiToken: f.token?.value }, fetch: o, requestSignal: s });
|
|
22078
22147
|
}
|
|
22079
22148
|
|
|
22080
22149
|
// src/owner-session.ts
|
|
@@ -23667,7 +23736,8 @@ async function start(cfg, buildInfo, dependencies = DEFAULT_START_DEPENDENCIES)
|
|
|
23667
23736
|
presenceSockets: presence.socketCount
|
|
23668
23737
|
}),
|
|
23669
23738
|
events,
|
|
23670
|
-
identityCid: bound.cid
|
|
23739
|
+
identityCid: bound.cid,
|
|
23740
|
+
retireContactNotifications: notificationOutbox ? (cid) => notificationOutbox.retireContact(cid) : void 0
|
|
23671
23741
|
};
|
|
23672
23742
|
const moduleDir = dirname5(fileURLToPath(import.meta.url));
|
|
23673
23743
|
const appCandidates = [
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
normalizeBasePath,
|
|
8
8
|
operatorError,
|
|
9
9
|
reportFailure
|
|
10
|
-
} from "./chunks/chunk-
|
|
10
|
+
} from "./chunks/chunk-NB6YYTBL.js";
|
|
11
11
|
|
|
12
12
|
// src/cli.ts
|
|
13
13
|
init_define_MESSENGER_BUILD_INFO();
|
|
@@ -131,7 +131,7 @@ async function main() {
|
|
|
131
131
|
}
|
|
132
132
|
if (process.argv.length !== 3) throw new ConfigurationError("serve does not accept command-line options");
|
|
133
133
|
const cfg = loadConfig();
|
|
134
|
-
const { start } = await import("./chunks/server-
|
|
134
|
+
const { start } = await import("./chunks/server-QMB6SIVE.js");
|
|
135
135
|
const handle = await start(cfg, BUILD_INFO);
|
|
136
136
|
let closing = false;
|
|
137
137
|
const shutdown = (signal) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/messenger-server",
|
|
3
|
-
"version": "1.0.31-nightly.
|
|
3
|
+
"version": "1.0.31-nightly.16",
|
|
4
4
|
"description": "Self-hosted Messenger REST/SSE backend for one identity on a shared Ours daemon.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-Apache-2.0",
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
34
34
|
"test:startup": "node --import tsx tests/startup-readiness.test.mjs",
|
|
35
35
|
"test:runtime-catalog-candidate": "node --import tsx tests/runtime-command-catalog-reopen-e2e.test.mjs",
|
|
36
|
-
"test:offline": "for f in tests/workspace-profile-preservation.test.mjs tests/notification-producer.test.mjs tests/base-path.test.mjs tests/build-epoch.test.mjs tests/owner-session.test.mjs tests/v1-runtime.test.mjs tests/typed-commands-core.test.mjs tests/shared-daemon-contract.test.mjs tests/room-envelope-matrix.test.mjs tests/bundle-smoke.test.mjs tests/build-metadata.test.mjs tests/production-security.test.mjs tests/conversation-page.test.mjs tests/media-response.test.mjs tests/html-preview-transform.test.mjs tests/html-preview-response.test.mjs tests/push-store.test.mjs tests/push-store-hardening.test.mjs tests/push-delivery.test.mjs tests/push-queue-saturation.test.mjs tests/events.test.mjs tests/watch-cursor.test.mjs tests/watch-reconcile.test.mjs tests/introduction-send-guard.test.mjs tests/sse-e2e.test.mjs tests/presence.test.mjs tests/static-hosting.test.mjs tests/room-preview.test.mjs; do echo \"# $f\"; node --import tsx \"$f\" || exit 1; done",
|
|
36
|
+
"test:offline": "for f in tests/workspace-profile-preservation.test.mjs tests/notification-producer.test.mjs tests/notification-contact-retirement.test.mjs tests/workspace-root-retirement.test.mjs tests/base-path.test.mjs tests/build-epoch.test.mjs tests/owner-session.test.mjs tests/v1-runtime.test.mjs tests/typed-commands-core.test.mjs tests/shared-daemon-contract.test.mjs tests/room-envelope-matrix.test.mjs tests/bundle-smoke.test.mjs tests/build-metadata.test.mjs tests/production-security.test.mjs tests/conversation-page.test.mjs tests/media-response.test.mjs tests/html-preview-transform.test.mjs tests/html-preview-response.test.mjs tests/push-store.test.mjs tests/push-store-hardening.test.mjs tests/push-delivery.test.mjs tests/push-queue-saturation.test.mjs tests/events.test.mjs tests/watch-cursor.test.mjs tests/watch-reconcile.test.mjs tests/introduction-send-guard.test.mjs tests/sse-e2e.test.mjs tests/presence.test.mjs tests/static-hosting.test.mjs tests/room-preview.test.mjs; do echo \"# $f\"; node --import tsx \"$f\" || exit 1; done",
|
|
37
37
|
"test:loopback": "for f in tests/shared-daemon-e2e.test.mjs tests/typed-command-loopback-e2e.test.mjs tests/introduction-send.test.mjs tests/rest-e2e.test.mjs; do echo \"# $f\"; node --import tsx \"$f\" || exit 1; done",
|
|
38
38
|
"test": "npm run build && npm run test:startup && npm run test:offline && npm run test:loopback"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@eslint-community/regexpp": "4.12.2",
|
|
42
|
-
"@ours.network/sdk": "3.8.1-nightly.
|
|
42
|
+
"@ours.network/sdk": "3.8.1-nightly.16",
|
|
43
43
|
"parse5": "^8.0.1",
|
|
44
44
|
"web-push": "^3.6.7",
|
|
45
45
|
"ws": "^8.21.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@ours.network/cli": "2.8.1-nightly.
|
|
49
|
-
"@ours.network/daemon": "3.8.1-nightly.
|
|
48
|
+
"@ours.network/cli": "2.8.1-nightly.14",
|
|
49
|
+
"@ours.network/daemon": "3.8.1-nightly.8",
|
|
50
50
|
"@playwright/test": "^1.62.1",
|
|
51
51
|
"@types/node": "^20.14.0",
|
|
52
52
|
"@types/web-push": "^3.6.4",
|