@ours.network/messenger-server 1.0.31-nightly.10 → 1.0.31-nightly.11
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.
|
@@ -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.11", sha: "0b84916c7fa85aa89cc5fcc004fb6b7cd79a26cd", 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-Y5H3QIV5.js";
|
|
14
14
|
|
|
15
15
|
// node_modules/bn.js/lib/bn.js
|
|
16
16
|
var require_bn = __commonJS({
|
|
@@ -2990,7 +2990,7 @@ var require_reporter = __commonJS({
|
|
|
2990
2990
|
if (state.obj !== null)
|
|
2991
2991
|
state.obj[key] = value;
|
|
2992
2992
|
};
|
|
2993
|
-
Reporter.prototype.path = function
|
|
2993
|
+
Reporter.prototype.path = function path2() {
|
|
2994
2994
|
return this._reporterState.path.join("/");
|
|
2995
2995
|
};
|
|
2996
2996
|
Reporter.prototype.enterObject = function enterObject() {
|
|
@@ -3031,8 +3031,8 @@ var require_reporter = __commonJS({
|
|
|
3031
3031
|
errors: state.errors
|
|
3032
3032
|
};
|
|
3033
3033
|
};
|
|
3034
|
-
function ReporterError(
|
|
3035
|
-
this.path =
|
|
3034
|
+
function ReporterError(path2, msg) {
|
|
3035
|
+
this.path = path2;
|
|
3036
3036
|
this.rethrow(msg);
|
|
3037
3037
|
}
|
|
3038
3038
|
inherits(ReporterError, Error);
|
|
@@ -3144,7 +3144,7 @@ var require_buffer = __commonJS({
|
|
|
3144
3144
|
const isCompatible = typeof data === "object" && data.constructor.name === "EncoderBuffer" && typeof data.length === "number" && typeof data.join === "function";
|
|
3145
3145
|
return isCompatible;
|
|
3146
3146
|
};
|
|
3147
|
-
EncoderBuffer.prototype.join = function
|
|
3147
|
+
EncoderBuffer.prototype.join = function join6(out, offset) {
|
|
3148
3148
|
if (!out)
|
|
3149
3149
|
out = Buffer2.alloc(this.length);
|
|
3150
3150
|
if (!offset)
|
|
@@ -11676,7 +11676,7 @@ var MessengerNotificationProducer = class {
|
|
|
11676
11676
|
};
|
|
11677
11677
|
|
|
11678
11678
|
// src/server.ts
|
|
11679
|
-
import { existsSync as
|
|
11679
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
11680
11680
|
import { readFile, realpath, stat } from "node:fs/promises";
|
|
11681
11681
|
import { createServer } from "node:http";
|
|
11682
11682
|
import { dirname as dirname5, extname, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "node:path";
|
|
@@ -11686,6 +11686,44 @@ import { Worker } from "node:worker_threads";
|
|
|
11686
11686
|
// src/api.ts
|
|
11687
11687
|
init_define_MESSENGER_BUILD_INFO();
|
|
11688
11688
|
|
|
11689
|
+
// src/workspace-profile.ts
|
|
11690
|
+
init_define_MESSENGER_BUILD_INFO();
|
|
11691
|
+
import { existsSync as existsSync2, lstatSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
11692
|
+
import { join as join2 } from "node:path";
|
|
11693
|
+
import { randomUUID } from "node:crypto";
|
|
11694
|
+
function profileName(value) {
|
|
11695
|
+
if (typeof value !== "string" || !value.trim() || value.length > 100 || /[\x00-\x1f\x7f]/.test(value)) throw Error("Name and Surname require printable text");
|
|
11696
|
+
return value.trim();
|
|
11697
|
+
}
|
|
11698
|
+
function path(dir, cid) {
|
|
11699
|
+
if (!/^[a-f0-9]{64}$/i.test(cid)) throw Error("Invalid identity");
|
|
11700
|
+
return join2(dir, "human-" + cid.toLowerCase() + ".json");
|
|
11701
|
+
}
|
|
11702
|
+
function readHumanProfile(dir, cid) {
|
|
11703
|
+
if (!/^[a-f0-9]{64}$/i.test(cid)) return;
|
|
11704
|
+
const file = path(dir, cid);
|
|
11705
|
+
if (!existsSync2(file)) return;
|
|
11706
|
+
const stat2 = lstatSync(file);
|
|
11707
|
+
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.nlink !== 1 || stat2.uid !== process.getuid?.() || (stat2.mode & 63) !== 0) throw Error("Private profile path required");
|
|
11708
|
+
const row = JSON.parse(readFileSync2(file, "utf8"));
|
|
11709
|
+
return { name: profileName(row.name), surname: profileName(row.surname) };
|
|
11710
|
+
}
|
|
11711
|
+
function writeHumanProfile(dir, cid, value) {
|
|
11712
|
+
const row = { name: profileName(value.name), surname: profileName(value.surname) };
|
|
11713
|
+
mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
11714
|
+
const directory = lstatSync(dir);
|
|
11715
|
+
if (!directory.isDirectory() || directory.isSymbolicLink() || directory.uid !== process.getuid?.() || (directory.mode & 63) !== 0) throw Error("Private profile directory required");
|
|
11716
|
+
const file = path(dir, cid);
|
|
11717
|
+
if (existsSync2(file)) {
|
|
11718
|
+
const stat2 = lstatSync(file);
|
|
11719
|
+
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.nlink !== 1 || stat2.uid !== process.getuid?.() || (stat2.mode & 63) !== 0) throw Error("Private profile path required");
|
|
11720
|
+
}
|
|
11721
|
+
const temporary = file + "." + randomUUID();
|
|
11722
|
+
writeFileSync2(temporary, JSON.stringify(row) + "\n", { mode: 384, flag: "wx" });
|
|
11723
|
+
renameSync2(temporary, file);
|
|
11724
|
+
return row;
|
|
11725
|
+
}
|
|
11726
|
+
|
|
11689
11727
|
// src/conversation.ts
|
|
11690
11728
|
init_define_MESSENGER_BUILD_INFO();
|
|
11691
11729
|
|
|
@@ -11956,8 +11994,8 @@ function toSse(event, identity) {
|
|
|
11956
11994
|
// src/command-invocations.ts
|
|
11957
11995
|
init_define_MESSENGER_BUILD_INFO();
|
|
11958
11996
|
import { createHash as createHash2 } from "node:crypto";
|
|
11959
|
-
import { chmodSync, mkdirSync as
|
|
11960
|
-
import { dirname as dirname2, join as
|
|
11997
|
+
import { chmodSync, mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
11998
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
11961
11999
|
var MAX_INVOCATIONS = 4096;
|
|
11962
12000
|
var InvocationConflictError = class extends Error {
|
|
11963
12001
|
};
|
|
@@ -11984,10 +12022,10 @@ var CommandInvocationStore = class _CommandInvocationStore {
|
|
|
11984
12022
|
}
|
|
11985
12023
|
static open(stateDir, identityCid, capacity = MAX_INVOCATIONS) {
|
|
11986
12024
|
if (!Number.isInteger(capacity) || capacity < 1) throw new Error("invocation capacity must be a positive integer");
|
|
11987
|
-
const file =
|
|
12025
|
+
const file = join3(stateDir, `typed-commands-${createHash2("sha256").update(identityCid).digest("hex").slice(0, 24)}.json`);
|
|
11988
12026
|
let state = { version: 1, records: {} };
|
|
11989
12027
|
try {
|
|
11990
|
-
const parsed = JSON.parse(
|
|
12028
|
+
const parsed = JSON.parse(readFileSync3(file, "utf8"));
|
|
11991
12029
|
if (!parsed || typeof parsed !== "object" || parsed.version !== 1 || !parsed.records || typeof parsed.records !== "object" || !Object.values(parsed.records).every(validRecord)) {
|
|
11992
12030
|
throw new Error("invalid typed command invocation state");
|
|
11993
12031
|
}
|
|
@@ -12035,11 +12073,11 @@ var CommandInvocationStore = class _CommandInvocationStore {
|
|
|
12035
12073
|
return record;
|
|
12036
12074
|
}
|
|
12037
12075
|
save() {
|
|
12038
|
-
|
|
12076
|
+
mkdirSync3(dirname2(this.file), { recursive: true, mode: 448 });
|
|
12039
12077
|
const temp = `${this.file}.${process.pid}.tmp`;
|
|
12040
|
-
|
|
12078
|
+
writeFileSync3(temp, JSON.stringify(this.state), { mode: 384 });
|
|
12041
12079
|
chmodSync(temp, 384);
|
|
12042
|
-
|
|
12080
|
+
renameSync3(temp, this.file);
|
|
12043
12081
|
}
|
|
12044
12082
|
};
|
|
12045
12083
|
function statusFor(delivery, wireId) {
|
|
@@ -20977,7 +21015,47 @@ var ROUTES = {
|
|
|
20977
21015
|
// ---- identity / profile --------------------------------------------------
|
|
20978
21016
|
// The old browser surface called the read half `getProfileName`; the name is a
|
|
20979
21017
|
// field on this result.
|
|
20980
|
-
"GET /api/identity": async ({ client }) => publicIdentity(await client.currentIdentity()),
|
|
21018
|
+
"GET /api/identity": async ({ client, deps }) => ({ ...publicIdentity(await client.currentIdentity()), humanProfile: readHumanProfile(deps.config.stateDir, deps.identityCid) }),
|
|
21019
|
+
"POST /api/identity/profile": async ({ client, deps, body }) => {
|
|
21020
|
+
const identity = await client.currentIdentity();
|
|
21021
|
+
if (!identity.isRoot || identity.temporary) throw bad("Human profile requires the root identity");
|
|
21022
|
+
return writeHumanProfile(deps.config.stateDir, deps.identityCid, { name: profileName(body.name), surname: profileName(body.surname) });
|
|
21023
|
+
},
|
|
21024
|
+
// First-party setup operation: daemon signs the command using this bound root.
|
|
21025
|
+
"GET /api/workspace/enrollment-identity": async ({ client }) => {
|
|
21026
|
+
const identity = await client.currentIdentity();
|
|
21027
|
+
if (!identity.isRoot || identity.temporary) throw bad("Workspace proof requires the bound Human root");
|
|
21028
|
+
return { cid: identity.cid };
|
|
21029
|
+
},
|
|
21030
|
+
"POST /api/workspace/enroll": async ({ client, deps, body }) => {
|
|
21031
|
+
const identity = await client.currentIdentity();
|
|
21032
|
+
if (!identity.isRoot || identity.temporary) throw bad("Workspace proof requires the bound Human root");
|
|
21033
|
+
const serverCid = str(body, "serverCid").toUpperCase();
|
|
21034
|
+
if (!/^[A-F0-9]{64}$/.test(serverCid) || !/^[A-Za-z0-9_-]{43}$/.test(str(body, "hostWorkspaceId"))) throw bad("Invalid workspace proof");
|
|
21035
|
+
const challenge = body.challenge;
|
|
21036
|
+
if (!challenge || !["nonce", "workspaceId", "accountId"].every((k3) => typeof challenge[k3] === "string" && /^[A-Za-z0-9_-]{43}$/.test(String(challenge[k3]))) || !Number.isFinite(challenge.expiresAt) || Number(challenge.expiresAt) <= Date.now() || Number(challenge.expiresAt) > Date.now() + 16 * 6e4) throw bad("Workspace challenge expired or invalid");
|
|
21037
|
+
let humanProfile;
|
|
21038
|
+
try {
|
|
21039
|
+
humanProfile = { name: profileName(body.name), surname: profileName(body.surname) };
|
|
21040
|
+
} catch {
|
|
21041
|
+
throw bad("Name and Surname require printable text up to 100 characters");
|
|
21042
|
+
}
|
|
21043
|
+
const invitation = str(body, "invitation");
|
|
21044
|
+
if (invitation.length > 8192) throw bad("Workspace invitation too large");
|
|
21045
|
+
writeHumanProfile(deps.config.stateDir, deps.identityCid, humanProfile);
|
|
21046
|
+
const peer = await client.addContact({ invite: invitation });
|
|
21047
|
+
if (peer.cid.toUpperCase() !== serverCid) throw bad("Enrollment server identity mismatch");
|
|
21048
|
+
const contactDeadline = Date.now() + 1e4;
|
|
21049
|
+
while (!(await client.listContacts()).contacts.some((contact) => contact.container_id.toUpperCase() === serverCid)) {
|
|
21050
|
+
if (Date.now() >= contactDeadline) throw bad("Enrollment contact is not ready; obtain a fresh setup payload before retrying");
|
|
21051
|
+
await new Promise((resolve3) => setTimeout(resolve3, 100));
|
|
21052
|
+
}
|
|
21053
|
+
const argumentsValue = { type: "ours.app.bind-workspace.v1", accountId: String(challenge.accountId), workspaceId: String(challenge.workspaceId), nonce: String(challenge.nonce), hostWorkspaceId: String(body.hostWorkspaceId) };
|
|
21054
|
+
const outcome = await client.sendCommand({ contact: serverCid, command: "bind-workspace", arguments: argumentsValue });
|
|
21055
|
+
if (!("sent" in outcome) || !outcome.sent) throw bad("Workspace proof was not sent");
|
|
21056
|
+
const invite = await client.generateInvite({ mode: "public" });
|
|
21057
|
+
return { submitted: true, rootCid: identity.cid, ownerInvite: invite.blob };
|
|
21058
|
+
},
|
|
20981
21059
|
"GET /api/identities": async ({ client }) => client.listIdentities(),
|
|
20982
21060
|
"POST /api/identity/bio": async ({ client, body }) => {
|
|
20983
21061
|
const bio = body.bio;
|
|
@@ -21991,11 +22069,11 @@ async function G(e2 = {}) {
|
|
|
21991
22069
|
init_define_MESSENGER_BUILD_INFO();
|
|
21992
22070
|
import { randomBytes } from "node:crypto";
|
|
21993
22071
|
import * as fs from "node:fs";
|
|
21994
|
-
import { isAbsolute, join as
|
|
22072
|
+
import { isAbsolute, join as join4, resolve, dirname as dirname3 } from "node:path";
|
|
21995
22073
|
import { spawnSync } from "node:child_process";
|
|
21996
|
-
function stateExists(
|
|
22074
|
+
function stateExists(path2) {
|
|
21997
22075
|
try {
|
|
21998
|
-
fs.lstatSync(
|
|
22076
|
+
fs.lstatSync(path2);
|
|
21999
22077
|
return true;
|
|
22000
22078
|
} catch (error) {
|
|
22001
22079
|
if (error.code === "ENOENT") return false;
|
|
@@ -22007,13 +22085,13 @@ var OwnerSession = class _OwnerSession {
|
|
|
22007
22085
|
constructor(stateDir, selection) {
|
|
22008
22086
|
this.stateDir = stateDir;
|
|
22009
22087
|
this.selection = selection;
|
|
22010
|
-
this.path =
|
|
22088
|
+
this.path = join4(stateDir, "owner-session.json");
|
|
22011
22089
|
}
|
|
22012
22090
|
record;
|
|
22013
22091
|
path;
|
|
22014
22092
|
lockFd;
|
|
22015
22093
|
static async open(stateDir, selection, attach) {
|
|
22016
|
-
const saved = stateDir && stateExists(
|
|
22094
|
+
const saved = stateDir && stateExists(join4(stateDir, "owner-session.json"));
|
|
22017
22095
|
if (!selection || process.platform !== "linux") {
|
|
22018
22096
|
if (saved) throw new ConfigurationError("Saved messenger ownership requires its qualified V1 activation and original selection");
|
|
22019
22097
|
return void 0;
|
|
@@ -22106,23 +22184,23 @@ var OwnerSession = class _OwnerSession {
|
|
|
22106
22184
|
}
|
|
22107
22185
|
}
|
|
22108
22186
|
activate() {
|
|
22109
|
-
for (let
|
|
22187
|
+
for (let path3 = this.stateDir; ; path3 = dirname3(path3)) {
|
|
22110
22188
|
let st3;
|
|
22111
22189
|
try {
|
|
22112
|
-
st3 = fs.lstatSync(
|
|
22190
|
+
st3 = fs.lstatSync(path3);
|
|
22113
22191
|
} catch (error) {
|
|
22114
22192
|
if (error.code !== "ENOENT") throw error;
|
|
22115
22193
|
}
|
|
22116
22194
|
if (st3 && (!st3.isDirectory() || st3.isSymbolicLink() || st3.uid !== 0 && st3.uid !== process.getuid() || (st3.mode & 18) !== 0 && !(st3.uid === 0 && (st3.mode & 512) !== 0))) {
|
|
22117
22195
|
throw new ConfigurationError("Messenger ownership state requires safe private directory ancestry");
|
|
22118
22196
|
}
|
|
22119
|
-
if (
|
|
22197
|
+
if (path3 === dirname3(path3)) break;
|
|
22120
22198
|
}
|
|
22121
22199
|
fs.mkdirSync(this.stateDir, { recursive: true, mode: 448 });
|
|
22122
22200
|
this.privateStat(this.stateDir, true);
|
|
22123
|
-
const
|
|
22124
|
-
this.lockFd = fs.openSync(
|
|
22125
|
-
const st2 = this.privateStat(
|
|
22201
|
+
const path2 = join4(this.stateDir, "owner-session.lock");
|
|
22202
|
+
this.lockFd = fs.openSync(path2, fs.constants.O_CREAT | fs.constants.O_RDWR | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK, 384);
|
|
22203
|
+
const st2 = this.privateStat(path2);
|
|
22126
22204
|
const opened = fs.fstatSync(this.lockFd);
|
|
22127
22205
|
if (st2.dev !== opened.dev || st2.ino !== opened.ino) throw new Error("Messenger activation file changed");
|
|
22128
22206
|
const acquired = spawnSync("flock", ["-n", "3"], {
|
|
@@ -22133,8 +22211,8 @@ var OwnerSession = class _OwnerSession {
|
|
|
22133
22211
|
throw new ConfigurationError(acquired.status === 1 ? "Messenger application state is already active" : "Messenger state locking is unavailable on this runtime");
|
|
22134
22212
|
}
|
|
22135
22213
|
}
|
|
22136
|
-
privateStat(
|
|
22137
|
-
const st2 = fs.lstatSync(
|
|
22214
|
+
privateStat(path2, directory = false) {
|
|
22215
|
+
const st2 = fs.lstatSync(path2);
|
|
22138
22216
|
if ((directory ? !st2.isDirectory() : !st2.isFile()) || st2.isSymbolicLink() || st2.uid !== process.getuid() || (st2.mode & 4095) !== (directory ? 448 : 384)) {
|
|
22139
22217
|
throw new ConfigurationError("Messenger owner state must be private, regular and owned by this user");
|
|
22140
22218
|
}
|
|
@@ -22285,9 +22363,9 @@ async function bindIdentity(runtime, cfg) {
|
|
|
22285
22363
|
// src/push.ts
|
|
22286
22364
|
init_define_MESSENGER_BUILD_INFO();
|
|
22287
22365
|
var import_web_push = __toESM(require_src2(), 1);
|
|
22288
|
-
import { createHash as createHash3, randomUUID, timingSafeEqual } from "node:crypto";
|
|
22289
|
-
import { chmodSync as chmodSync2, lstatSync as
|
|
22290
|
-
import { dirname as dirname4, join as
|
|
22366
|
+
import { createHash as createHash3, randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
|
|
22367
|
+
import { chmodSync as chmodSync2, lstatSync as lstatSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync5, renameSync as renameSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
22368
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
22291
22369
|
var MAX_BINDINGS = 32;
|
|
22292
22370
|
var MAX_ENDPOINT_LENGTH = 2048;
|
|
22293
22371
|
var MAX_LABEL_LENGTH = 160;
|
|
@@ -22483,15 +22561,15 @@ var PushStore = class _PushStore {
|
|
|
22483
22561
|
const env = typeof identityCidOrEnv === "string" ? envOrDependencies : identityCidOrEnv;
|
|
22484
22562
|
const deps = typeof identityCidOrEnv === "string" ? dependencies : envOrDependencies;
|
|
22485
22563
|
if (!nonEmpty3(identityCid, 512)) throw new Error("push identity CID must be a non-empty bounded string");
|
|
22486
|
-
const file =
|
|
22487
|
-
|
|
22564
|
+
const file = join5(stateDir, "push.json");
|
|
22565
|
+
mkdirSync6(dirname4(file), { recursive: true, mode: 448 });
|
|
22488
22566
|
let parsed;
|
|
22489
22567
|
try {
|
|
22490
|
-
const stat2 =
|
|
22568
|
+
const stat2 = lstatSync4(file);
|
|
22491
22569
|
if (!stat2.isFile() || stat2.isSymbolicLink()) throw preservedStateError(file, "not a safe regular file");
|
|
22492
22570
|
let value;
|
|
22493
22571
|
try {
|
|
22494
|
-
value = JSON.parse(
|
|
22572
|
+
value = JSON.parse(readFileSync5(file, "utf8"));
|
|
22495
22573
|
} catch (error) {
|
|
22496
22574
|
throw preservedStateError(file, `corrupt or unreadable (${error instanceof Error ? error.message : String(error)})`);
|
|
22497
22575
|
}
|
|
@@ -22569,7 +22647,7 @@ var PushStore = class _PushStore {
|
|
|
22569
22647
|
[identityCid]: {
|
|
22570
22648
|
...newIdentityState(),
|
|
22571
22649
|
bindings: (parsed?.subscriptions ?? []).map((row) => ({
|
|
22572
|
-
bindingId:
|
|
22650
|
+
bindingId: randomUUID2(),
|
|
22573
22651
|
endpoint: row.endpoint,
|
|
22574
22652
|
keys: row.keys,
|
|
22575
22653
|
createdAt: row.createdAt,
|
|
@@ -22590,9 +22668,9 @@ var PushStore = class _PushStore {
|
|
|
22590
22668
|
}
|
|
22591
22669
|
persist() {
|
|
22592
22670
|
const tmp = `${this.file}.tmp`;
|
|
22593
|
-
|
|
22671
|
+
writeFileSync6(tmp, JSON.stringify(this.state, null, 2), { mode: 384 });
|
|
22594
22672
|
chmodSync2(tmp, 384);
|
|
22595
|
-
|
|
22673
|
+
renameSync5(tmp, this.file);
|
|
22596
22674
|
chmodSync2(this.file, 384);
|
|
22597
22675
|
}
|
|
22598
22676
|
get publicKey() {
|
|
@@ -22641,7 +22719,7 @@ var PushStore = class _PushStore {
|
|
|
22641
22719
|
const preview = input.preview === void 0 ? previous?.preview ?? "full" : previewMode(input.preview);
|
|
22642
22720
|
if (!previous && owner.bindings.length >= MAX_BINDINGS) throw new Error(`push subscription limit is ${MAX_BINDINGS}`);
|
|
22643
22721
|
const createdAt = previous?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
22644
|
-
const bindingId = previous?.bindingId ??
|
|
22722
|
+
const bindingId = previous?.bindingId ?? randomUUID2();
|
|
22645
22723
|
const record = {
|
|
22646
22724
|
bindingId,
|
|
22647
22725
|
endpoint,
|
|
@@ -22951,7 +23029,7 @@ var PushStore = class _PushStore {
|
|
|
22951
23029
|
}
|
|
22952
23030
|
/** Compatibility for tests/old callers; durable production delivery uses jobs. */
|
|
22953
23031
|
async send(event) {
|
|
22954
|
-
const wire = `compat-${
|
|
23032
|
+
const wire = `compat-${randomUUID2()}`;
|
|
22955
23033
|
this.enqueueJob({ wireId: wire, kind: event.kind, contactId: event.contact_id });
|
|
22956
23034
|
const id = `${this.identityCid}:${wire}:${event.kind}`;
|
|
22957
23035
|
this.claimJob(id);
|
|
@@ -23120,7 +23198,7 @@ function liveFrame(event) {
|
|
|
23120
23198
|
return JSON.stringify({ type: "event", event: { v: 1, ...event } });
|
|
23121
23199
|
}
|
|
23122
23200
|
function attachPresenceServer(server, registry, options) {
|
|
23123
|
-
const
|
|
23201
|
+
const path2 = options.path ?? "/api/presence";
|
|
23124
23202
|
const pingIntervalMs = options.pingIntervalMs ?? 3e4;
|
|
23125
23203
|
const authTimeoutMs = options.authTimeoutMs ?? 5e3;
|
|
23126
23204
|
const wss = new import_websocket_server.default({ noServer: true, maxPayload: 8 * 1024 });
|
|
@@ -23130,7 +23208,7 @@ function attachPresenceServer(server, registry, options) {
|
|
|
23130
23208
|
pathname = new URL(request.url ?? "/", "http://localhost").pathname;
|
|
23131
23209
|
} catch {
|
|
23132
23210
|
}
|
|
23133
|
-
if (pathname !==
|
|
23211
|
+
if (pathname !== path2 || options.allowedOrigin && request.headers.origin !== options.allowedOrigin) {
|
|
23134
23212
|
socket.destroy();
|
|
23135
23213
|
return;
|
|
23136
23214
|
}
|
|
@@ -23288,8 +23366,8 @@ async function redirectStaleEntryAsset(req, res, appDir, pathname, basePath = "/
|
|
|
23288
23366
|
return false;
|
|
23289
23367
|
}
|
|
23290
23368
|
}
|
|
23291
|
-
async function readContainedFile(root,
|
|
23292
|
-
const [canonicalRoot, canonicalPath] = await Promise.all([realpath(root), realpath(
|
|
23369
|
+
async function readContainedFile(root, path2) {
|
|
23370
|
+
const [canonicalRoot, canonicalPath] = await Promise.all([realpath(root), realpath(path2)]);
|
|
23293
23371
|
const fromRoot = relative(canonicalRoot, canonicalPath);
|
|
23294
23372
|
if (fromRoot === "" || fromRoot === ".." || fromRoot.startsWith(`..${sep}`) || isAbsolute2(fromRoot) || !(await stat(canonicalPath)).isFile()) {
|
|
23295
23373
|
throw new Error("static asset is not a contained regular file");
|
|
@@ -23585,7 +23663,7 @@ async function start(cfg, buildInfo, dependencies = DEFAULT_START_DEPENDENCIES)
|
|
|
23585
23663
|
resolve2(moduleDir, "../dist/web"),
|
|
23586
23664
|
resolve2(moduleDir, "web")
|
|
23587
23665
|
];
|
|
23588
|
-
const appDir = process.env.OURS_MESSENGER_WEB_DIR ?? appCandidates.find((candidate) =>
|
|
23666
|
+
const appDir = process.env.OURS_MESSENGER_WEB_DIR ?? appCandidates.find((candidate) => existsSync3(resolve2(candidate, "index.html")) && existsSync3(resolve2(candidate, "assets"))) ?? resolve2(moduleDir, "__messenger_web_not_built__");
|
|
23589
23667
|
http = createServer((req, res) => {
|
|
23590
23668
|
const pathname = new URL(req.url ?? "/", "http://localhost").pathname;
|
|
23591
23669
|
let serving;
|
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-Y5H3QIV5.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-T57VZPJ5.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.11",
|
|
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",
|