fedipod 1.40.0 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/architecture.md +1 -3
- package/architecture.svg +93 -85
- package/gateway.md +7 -2
- package/lib/client/c2s.mjs +16 -5
- package/lib/client/masto/oauth.mjs +1 -1
- package/lib/connections/vault.mjs +1 -1
- package/lib/core/agent.mjs +720 -0
- package/lib/core/deliver.mjs +11 -1
- package/lib/core/gateway-move.mjs +58 -0
- package/lib/core/intake/group.mjs +10 -11
- package/lib/core/keys.mjs +1 -1
- package/lib/core/lease.mjs +4 -3
- package/lib/core/publisher/index.mjs +4 -6
- package/lib/core/publisher/notes.mjs +73 -4
- package/lib/core/remote.mjs +54 -0
- package/lib/core/shapes/shapes-text.mjs +11 -3
- package/lib/core/wire.mjs +4 -1
- package/lib/device/admin/index.mjs +4 -11
- package/lib/device/admin/routes/setup.mjs +60 -5
- package/lib/device/admin/server.mjs +18 -5
- package/lib/device/cli/commands/account.mjs +1 -1
- package/lib/device/cli/commands/run.mjs +2 -2
- package/lib/device/cli/commands/service.mjs +1 -1
- package/lib/device/cli/commands/setup.mjs +1 -1
- package/lib/device/cli/commands/state.mjs +1 -1
- package/lib/device/cli/context.mjs +1 -1
- package/lib/{gateway → device}/directory.mjs +1 -1
- package/lib/device/gateway-move.mjs +3 -58
- package/lib/device/home.mjs +3 -50
- package/lib/{client → device}/localapi.mjs +2 -2
- package/lib/device/remote.mjs +3 -54
- package/lib/gateway/copy.mjs +12 -3
- package/lib/gateway/front-core.mjs +16 -17
- package/lib/gateway/front-pages.mjs +31 -0
- package/lib/gateway/gateway-core.mjs +1 -1
- package/lib/gateway/held-mail.mjs +3 -0
- package/lib/gateway/keeper-session.mjs +10 -1
- package/lib/gateway/keeper.mjs +3 -0
- package/lib/gateway/masto-gateway.mjs +61 -12
- package/lib/gateway/outbox-door.mjs +31 -0
- package/lib/gateway/state-api.mjs +39 -7
- package/lib/server/embed.mjs +4 -4
- package/lib/shared/files.mjs +49 -0
- package/lib/shared/ua.mjs +3 -0
- package/lib/surface/index.mjs +7 -0
- package/lib/{device/admin → surface}/origins.mjs +1 -1
- package/lib/{device/admin → surface}/routes/gateway.mjs +7 -11
- package/lib/{device/admin → surface}/routes/lifecycle.mjs +3 -3
- package/lib/{device/admin → surface}/routes/owner.mjs +4 -60
- package/lib/{device/admin → surface}/routes/social.mjs +1 -1
- package/lib/{device/admin → surface}/static.mjs +6 -1
- package/lib/{device/admin → surface}/surface.mjs +19 -16
- package/package.json +23 -5
- package/run-agent.mjs +19 -720
- package/scripts/build-app.mjs +4 -0
- package/scripts/check-netlify-bundles.mjs +88 -0
- package/scripts/check-pod-calls.mjs +42 -0
- package/scripts/vendor-sanitize.mjs +27 -0
- package/vendor/idp-grant.cjs +11 -5
- package/vendor/sanitize-html.cjs +11456 -0
- package/web/app/agent.mjs +4 -2
- package/web/app/copy-mode.mjs +27 -3
- package/web/app/dist/boot.js.map +1 -1
- package/web/app/dist/sw.js +110 -24
- package/web/app/dist/sw.js.map +4 -4
- package/web/app-signin/app-signin.mjs +2 -2
- package/web/app-signin/index.html +13 -5
- package/browser.svg +0 -72
- /package/lib/{device/admin → surface}/routes/connections.mjs +0 -0
package/web/app/dist/sw.js
CHANGED
|
@@ -46490,6 +46490,10 @@ var StateApiStorage = class {
|
|
|
46490
46490
|
}
|
|
46491
46491
|
};
|
|
46492
46492
|
|
|
46493
|
+
// lib/core/publisher/index.mjs
|
|
46494
|
+
init_node_crypto();
|
|
46495
|
+
init_wire();
|
|
46496
|
+
|
|
46493
46497
|
// web/app/shims/node-fs.mjs
|
|
46494
46498
|
var PKG = JSON.stringify({ version: "0.18.0", name: "fedipod" });
|
|
46495
46499
|
var readFileSync = (p) => {
|
|
@@ -46508,10 +46512,6 @@ var unlinkSync = nope("unlinkSync");
|
|
|
46508
46512
|
var rmSync = nope("rmSync");
|
|
46509
46513
|
var node_fs_default = { readFileSync, existsSync, writeFileSync, mkdirSync, readdirSync, statSync, unlinkSync, rmSync };
|
|
46510
46514
|
|
|
46511
|
-
// lib/core/publisher/index.mjs
|
|
46512
|
-
init_node_crypto();
|
|
46513
|
-
init_wire();
|
|
46514
|
-
|
|
46515
46515
|
// lib/shared/ua.mjs
|
|
46516
46516
|
var version = "0";
|
|
46517
46517
|
try {
|
|
@@ -46529,6 +46529,7 @@ try {
|
|
|
46529
46529
|
}
|
|
46530
46530
|
}
|
|
46531
46531
|
var USER_AGENT = `fedipod/${version} (+https://github.com/jeff-zucker/FediPod)`;
|
|
46532
|
+
var AGENT_VERSION = version;
|
|
46532
46533
|
|
|
46533
46534
|
// lib/core/publisher/index.mjs
|
|
46534
46535
|
init_safefetch();
|
|
@@ -57531,11 +57532,31 @@ async function updateObject(publisher, s, patch, { updated = (/* @__PURE__ */ ne
|
|
|
57531
57532
|
return update;
|
|
57532
57533
|
}
|
|
57533
57534
|
function rowContent(obj) {
|
|
57535
|
+
const text = objectText(obj);
|
|
57536
|
+
const esc = (v) => String(v).replace(/[&<>"]/gu, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]);
|
|
57537
|
+
const on = annotationTarget(obj);
|
|
57538
|
+
const link = on.page ? `<a href="${esc(on.page)}">${esc(on.page)}</a>` : "";
|
|
57539
|
+
const context = on.exact ? `<p>${link ? `text from ${link}:` : "text:"}</p><blockquote><p>${esc(on.exact)}</p></blockquote>` : link ? `<p>${link}</p>` : "";
|
|
57540
|
+
if (text) return context ? `${context}<p>comment:</p>${text}` : text;
|
|
57541
|
+
return context || `<p><a href="${esc(obj?.id || "")}">${esc(obj?.type || "object")}</a></p>`;
|
|
57542
|
+
}
|
|
57543
|
+
function objectText(obj) {
|
|
57534
57544
|
if (typeof obj?.content === "string" && obj.content.trim()) return sanitizeHtml(obj.content);
|
|
57535
57545
|
const plain = [obj?.bodyValue, obj?.name, obj?.summary].find((v) => typeof v === "string" && v.trim());
|
|
57536
57546
|
if (plain) return contentHtml(plain);
|
|
57537
|
-
const
|
|
57538
|
-
return
|
|
57547
|
+
const bodies = [].concat(obj?.body || []).map((b) => b && typeof b === "object" && b.purpose !== "tagging" ? b.value && typeof b.value === "object" ? b.value["@value"] : b.value : null).filter((v) => typeof v === "string" && v.trim());
|
|
57548
|
+
return bodies.map((v) => /<[a-z]/iu.test(v) ? sanitizeHtml(v) : contentHtml(v)).join("");
|
|
57549
|
+
}
|
|
57550
|
+
function annotationTarget(obj) {
|
|
57551
|
+
const val = (v) => v && typeof v === "object" ? v["@value"] ?? v.id : v;
|
|
57552
|
+
for (const t of [].concat(obj?.target || [])) {
|
|
57553
|
+
const page2 = val(typeof t === "string" ? t : t?.source ?? t?.id);
|
|
57554
|
+
const quote = [].concat(t?.selector || []).find((sel) => sel?.type === "TextQuoteSelector");
|
|
57555
|
+
const exact = val(quote?.exact);
|
|
57556
|
+
const ok = typeof page2 === "string" && /^https?:\/\//u.test(page2);
|
|
57557
|
+
if (ok || exact) return { page: ok ? page2 : null, exact: typeof exact === "string" && exact.trim() ? exact.trim() : null };
|
|
57558
|
+
}
|
|
57559
|
+
return { page: null, exact: null };
|
|
57539
57560
|
}
|
|
57540
57561
|
async function publishNote(publisher, content, { inReplyTo, attachments, visibility = "public", spoilerText = null, sensitive = false, slug: wanted = null, also = [], deliverTo = [], quote = null } = {}) {
|
|
57541
57562
|
const { urls } = publisher;
|
|
@@ -57637,7 +57658,8 @@ async function publishNote(publisher, content, { inReplyTo, attachments, visibil
|
|
|
57637
57658
|
}
|
|
57638
57659
|
return note;
|
|
57639
57660
|
}
|
|
57640
|
-
async function publishObject(publisher, object, { visibility = "public", slug: wanted = null, also = [], deliverTo = [] } = {}) {
|
|
57661
|
+
async function publishObject(publisher, object, { visibility = "public", slug: wanted = null, also = [], deliverTo = [], unaddressed = false } = {}) {
|
|
57662
|
+
if (unaddressed) return publishUnaddressed(publisher, object, wanted);
|
|
57641
57663
|
const { urls } = publisher;
|
|
57642
57664
|
const priv = visibility === "private" || visibility === "direct";
|
|
57643
57665
|
if (priv) {
|
|
@@ -57695,6 +57717,45 @@ async function publishObject(publisher, object, { visibility = "public", slug: w
|
|
|
57695
57717
|
publisher.log(`${row.type || "object"} published: ${id} \u2192 ${inboxes.length} inbox(es)`);
|
|
57696
57718
|
return { id, createId, copied: !ownId };
|
|
57697
57719
|
}
|
|
57720
|
+
async function publishUnaddressed(publisher, object, wanted) {
|
|
57721
|
+
const { urls } = publisher;
|
|
57722
|
+
const published = (/* @__PURE__ */ new Date()).toISOString();
|
|
57723
|
+
const pod = publisher.config?.remotePod || urls.base;
|
|
57724
|
+
const ownId = typeof object.id === "string" && /^https?:\/\//u.test(object.id) && object.id.startsWith(pod) ? object.id : null;
|
|
57725
|
+
const name = await slugFor(publisher, urls.notes, wanted, published);
|
|
57726
|
+
const id = ownId || urls.notes + name;
|
|
57727
|
+
let doc = null;
|
|
57728
|
+
if (!ownId) {
|
|
57729
|
+
const { bto, bcc, ...sent } = object;
|
|
57730
|
+
doc = { ...sent, id, attributedTo: urls.actor, published: object.published || published };
|
|
57731
|
+
if (!doc["@context"]) doc["@context"] = AS_CTX;
|
|
57732
|
+
if (typeof doc.content === "string") doc.content = sanitizeHtml(doc.content);
|
|
57733
|
+
await write4(publisher.remote, id, doc);
|
|
57734
|
+
}
|
|
57735
|
+
const row = doc || object;
|
|
57736
|
+
publisher.store.addStatus({
|
|
57737
|
+
noteId: id,
|
|
57738
|
+
actor: urls.actor,
|
|
57739
|
+
content: rowContent(row),
|
|
57740
|
+
published: row.published || published,
|
|
57741
|
+
kind: "post",
|
|
57742
|
+
slug: name,
|
|
57743
|
+
visibility: "direct"
|
|
57744
|
+
});
|
|
57745
|
+
if (await publisher.store.commit?.() === false) publisher.log(`object kept but its timeline row was refused: ${id}`);
|
|
57746
|
+
const create = {
|
|
57747
|
+
"@context": AS_CTX,
|
|
57748
|
+
id: createActivityId(ownId ? urls.notes + name : id),
|
|
57749
|
+
type: "Create",
|
|
57750
|
+
actor: urls.actor,
|
|
57751
|
+
published: row.published || published,
|
|
57752
|
+
object: doc || id
|
|
57753
|
+
};
|
|
57754
|
+
await writeCreate(publisher.remote, create.id, create);
|
|
57755
|
+
publisher.recordOwn?.(create);
|
|
57756
|
+
publisher.log(`${row.type || "object"} kept, addressed to nobody: ${id}`);
|
|
57757
|
+
return { id, createId: create.id, copied: !ownId };
|
|
57758
|
+
}
|
|
57698
57759
|
function rowTags(note) {
|
|
57699
57760
|
const tags = [].concat(note.tag || []);
|
|
57700
57761
|
const mentions = tags.filter((t) => t.type === "Mention").map((t) => ({ href: t.href, name: t.name }));
|
|
@@ -58372,10 +58433,6 @@ async function writePages(remote, before = {}, pages) {
|
|
|
58372
58433
|
}
|
|
58373
58434
|
|
|
58374
58435
|
// lib/core/publisher/index.mjs
|
|
58375
|
-
var AGENT_VERSION = JSON.parse(node_fs_default.readFileSync(
|
|
58376
|
-
node_path_default.join(node_path_default.dirname(fileURLToPath(import.meta.url)), "../../../package.json"),
|
|
58377
|
-
"utf8"
|
|
58378
|
-
)).version;
|
|
58379
58436
|
var Publisher = class {
|
|
58380
58437
|
constructor({
|
|
58381
58438
|
config,
|
|
@@ -66457,6 +66514,11 @@ var ACTIVITY_TYPES = /* @__PURE__ */ new Set([
|
|
|
66457
66514
|
]);
|
|
66458
66515
|
var arr = (v) => v === void 0 || v === null ? [] : Array.isArray(v) ? v : [v];
|
|
66459
66516
|
var idOf2 = (v) => typeof v === "string" ? v : v?.id || null;
|
|
66517
|
+
var PUBLIC_SPELLINGS = /* @__PURE__ */ new Set(["Public", "as:Public"]);
|
|
66518
|
+
var audienceOf = (v) => {
|
|
66519
|
+
const id = idOf2(v);
|
|
66520
|
+
return PUBLIC_SPELLINGS.has(id) ? PUBLIC : id;
|
|
66521
|
+
};
|
|
66460
66522
|
function readBody(req) {
|
|
66461
66523
|
return new Promise((resolve2, reject) => {
|
|
66462
66524
|
let size = 0;
|
|
@@ -66474,6 +66536,7 @@ function readBody(req) {
|
|
|
66474
66536
|
req.on("error", reject);
|
|
66475
66537
|
});
|
|
66476
66538
|
}
|
|
66539
|
+
var isAnnotation = (o) => arr(o?.type).some((t) => t === "Annotation" || t === "oa:Annotation" || t === "http://www.w3.org/ns/oa#Annotation");
|
|
66477
66540
|
var C2S = class {
|
|
66478
66541
|
constructor({ agent: agent2, log: log2 = console.log, auth, scheme = null, mount = "" }) {
|
|
66479
66542
|
this.agent = agent2;
|
|
@@ -66706,8 +66769,8 @@ var C2S = class {
|
|
|
66706
66769
|
// every client means by a post with no audience chosen, and what a client
|
|
66707
66770
|
// that never addresses (dokieli's annotations) needs.
|
|
66708
66771
|
visibilityOf(activity, object) {
|
|
66709
|
-
const to = arr(activity.to ?? object?.to).map(
|
|
66710
|
-
const cc = arr(activity.cc ?? object?.cc).map(
|
|
66772
|
+
const to = arr(activity.to ?? object?.to).map(audienceOf);
|
|
66773
|
+
const cc = arr(activity.cc ?? object?.cc).map(audienceOf);
|
|
66711
66774
|
const blind = arr(activity.bto ?? object?.bto).length + arr(activity.bcc ?? object?.bcc).length;
|
|
66712
66775
|
if (!to.length && !cc.length) return blind ? "direct" : "public";
|
|
66713
66776
|
if (to.includes(PUBLIC)) return "public";
|
|
@@ -66738,7 +66801,7 @@ var C2S = class {
|
|
|
66738
66801
|
// in to/cc are listed and delivered to; the ones in bto/bcc are delivered
|
|
66739
66802
|
// to and never listed (§6).
|
|
66740
66803
|
addressedActors(activity, object) {
|
|
66741
|
-
const pick = (...fields) => [...new Set(fields.flatMap((f) => arr(activity[f] ?? object?.[f]).map(
|
|
66804
|
+
const pick = (...fields) => [...new Set(fields.flatMap((f) => arr(activity[f] ?? object?.[f]).map(audienceOf)))].filter((a) => typeof a === "string" && /^https?:\/\//u.test(a) && a !== PUBLIC && a !== this.urls.followers && a !== this.urls.actor);
|
|
66742
66805
|
return { also: pick("to", "cc", "audience"), deliverTo: pick("bto", "bcc") };
|
|
66743
66806
|
}
|
|
66744
66807
|
async _dispatch(activity, { slug, raw, reply, serial, at }) {
|
|
@@ -66760,7 +66823,8 @@ var C2S = class {
|
|
|
66760
66823
|
const { also, deliverTo } = this.addressedActors(activity, object);
|
|
66761
66824
|
if (makes !== "Note" && makes !== "Question") {
|
|
66762
66825
|
const asSent = raw && typeof raw === "object" && !Array.isArray(raw) ? ACTIVITY_TYPES.has(raw.type) ? raw.object && typeof raw.object === "object" ? raw.object : null : raw : null;
|
|
66763
|
-
const
|
|
66826
|
+
const unaddressed = isAnnotation(asSent || object) && ["to", "cc", "bto", "bcc", "audience"].every((f) => !arr(activity[f] ?? object[f]).length);
|
|
66827
|
+
const made2 = await agent2.publisher.publishObject(asSent || object, { visibility, slug, also, deliverTo, unaddressed });
|
|
66764
66828
|
return reply(201, { id: made2.createId, object: made2.id }, { location: made2.createId });
|
|
66765
66829
|
}
|
|
66766
66830
|
const text = String(object.source?.content ?? object.content ?? "");
|
|
@@ -66973,6 +67037,7 @@ var Lease = class {
|
|
|
66973
67037
|
this.timer = null;
|
|
66974
67038
|
this.heldUntil = 0;
|
|
66975
67039
|
this.denied = null;
|
|
67040
|
+
this.unreadable = null;
|
|
66976
67041
|
}
|
|
66977
67042
|
// null means the lease document is NOT THERE — nobody holds it. UNREADABLE
|
|
66978
67043
|
// means we could not ask, which is a different answer and must not be read as
|
|
@@ -66984,9 +67049,13 @@ var Lease = class {
|
|
|
66984
67049
|
try {
|
|
66985
67050
|
res = await this.fetchImpl(this.url, { headers: { accept: "application/json" } });
|
|
66986
67051
|
if (res.status === 404 || res.status === 410) return null;
|
|
66987
|
-
if (res.status >= 400)
|
|
67052
|
+
if (res.status >= 400) {
|
|
67053
|
+
this.unreadable = `HTTP ${res.status}`;
|
|
67054
|
+
return UNREADABLE;
|
|
67055
|
+
}
|
|
66988
67056
|
body = await res.text();
|
|
66989
|
-
} catch {
|
|
67057
|
+
} catch (e) {
|
|
67058
|
+
this.unreadable = e.message;
|
|
66990
67059
|
return UNREADABLE;
|
|
66991
67060
|
}
|
|
66992
67061
|
this.etag = res.headers?.get?.("etag") || null;
|
|
@@ -67017,7 +67086,7 @@ var Lease = class {
|
|
|
67017
67086
|
const cur = await this.readFresh();
|
|
67018
67087
|
if (cur === UNREADABLE) {
|
|
67019
67088
|
this.denied = "unreadable";
|
|
67020
|
-
this.log(
|
|
67089
|
+
this.log(`lease unreadable (${this.unreadable}) \u2014 staying a viewer`);
|
|
67021
67090
|
return false;
|
|
67022
67091
|
}
|
|
67023
67092
|
if (cur && cur.holder !== this.id && Date.now() < cur.expiresAt) {
|
|
@@ -67419,7 +67488,7 @@ function sendPodSigninPage(res, client, webId, mount = "") {
|
|
|
67419
67488
|
} catch {
|
|
67420
67489
|
}
|
|
67421
67490
|
const who = client.name ? escapeHtml(client.name) : where ? escapeHtml(where) : "A client";
|
|
67422
|
-
asking = `<p><strong>${who}</strong> is asking to use your account${where ? `, and will be sent back to <code>${escapeHtml(where)}</code>` : ""}.</p>`;
|
|
67491
|
+
asking = `<p><strong>${who}</strong> is asking to use your account${where ? `, and you will be sent back to <code>${escapeHtml(where)}</code>` : ""}.</p>`;
|
|
67423
67492
|
}
|
|
67424
67493
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-cache" });
|
|
67425
67494
|
res.end(`<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
@@ -71850,7 +71919,7 @@ var fail2 = () => {
|
|
|
71850
71919
|
};
|
|
71851
71920
|
var node_os_default = new Proxy({}, { get: () => fail2 });
|
|
71852
71921
|
|
|
71853
|
-
// lib/
|
|
71922
|
+
// lib/shared/files.mjs
|
|
71854
71923
|
function writeFileAtomic(file, body, { mode = 384 } = {}) {
|
|
71855
71924
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
71856
71925
|
node_fs_default.mkdirSync(node_path_default.dirname(file), { recursive: true, mode: 448 });
|
|
@@ -72951,9 +73020,18 @@ init_urls();
|
|
|
72951
73020
|
|
|
72952
73021
|
// web/app/copy-mode.mjs
|
|
72953
73022
|
var RENEW_BEFORE_MS = 2 * 36e5;
|
|
72954
|
-
|
|
73023
|
+
var ASK_AGAIN_MS = 15 * 6e4;
|
|
73024
|
+
var REMEMBERED = [404, 409, 501, 502, 503];
|
|
73025
|
+
var failedKey = (agent2, frontOrigin) => `copy-open-failed:${frontOrigin}:${agent2.webId}`;
|
|
73026
|
+
var forgetFailedOpen = (agent2, frontOrigin) => kvDel(failedKey(agent2, frontOrigin)).catch(() => {
|
|
73027
|
+
});
|
|
73028
|
+
async function openCopy(agent2, frontOrigin, { handle: handle7 = null, kept = null, askAnyway = false, letGo = false } = {}) {
|
|
72955
73029
|
if (kept && kept.expiresAt - Date.now() > RENEW_BEFORE_MS) return kept;
|
|
72956
73030
|
if (!agent2.sessionFetch || !frontOrigin) return null;
|
|
73031
|
+
const key = failedKey(agent2, frontOrigin);
|
|
73032
|
+
const failed = await kvGet(key).catch(() => null);
|
|
73033
|
+
const held = letGo && failed?.status === 409;
|
|
73034
|
+
if (!askAnyway && !held && failed && Date.now() - failed.at < ASK_AGAIN_MS) return null;
|
|
72957
73035
|
let res;
|
|
72958
73036
|
try {
|
|
72959
73037
|
res = await agent2.sessionFetch(`${frontOrigin.replace(/\/$/u, "")}/api/state/open`, {
|
|
@@ -72966,9 +73044,16 @@ async function openCopy(agent2, frontOrigin, { handle: handle7 = null, kept = nu
|
|
|
72966
73044
|
return null;
|
|
72967
73045
|
}
|
|
72968
73046
|
if (res.status !== 200) {
|
|
72969
|
-
if (![404, 409, 501].includes(res.status))
|
|
73047
|
+
if (![404, 409, 501].includes(res.status)) {
|
|
73048
|
+
const why = (await res.json().catch(() => null))?.error;
|
|
73049
|
+
agent2.log(`the account's copy: the gateway answered ${res.status}${why ? ` (${why})` : ""}`);
|
|
73050
|
+
}
|
|
73051
|
+
if (REMEMBERED.includes(res.status)) await kvPut(key, { at: Date.now(), status: res.status }).catch(() => {
|
|
73052
|
+
});
|
|
72970
73053
|
return null;
|
|
72971
73054
|
}
|
|
73055
|
+
if (failed) await kvDel(key).catch(() => {
|
|
73056
|
+
});
|
|
72972
73057
|
const copy = await res.json().catch(() => null);
|
|
72973
73058
|
return copy?.base && copy?.token ? { handle: copy.handle, base: copy.base, token: copy.token, expiresAt: copy.expiresAt, podHome: copy.podHome || null } : null;
|
|
72974
73059
|
}
|
|
@@ -73052,7 +73137,7 @@ async function moveIntoCopy(agent2, frontOrigin) {
|
|
|
73052
73137
|
if (agent2.copy) return true;
|
|
73053
73138
|
await agent2.store.commit();
|
|
73054
73139
|
await agent2.lease.release();
|
|
73055
|
-
const copy = await openCopy(agent2, frontOrigin, { handle: agent2.doorKey });
|
|
73140
|
+
const copy = await openCopy(agent2, frontOrigin, { handle: agent2.doorKey, letGo: true });
|
|
73056
73141
|
if (!copy) {
|
|
73057
73142
|
if (await agent2.lease.acquire()) agent2.lease.startRenewal();
|
|
73058
73143
|
return false;
|
|
@@ -73257,6 +73342,7 @@ var BrowserAgent = class _BrowserAgent {
|
|
|
73257
73342
|
if (!on) return { status: 200, ok: true, kept: false };
|
|
73258
73343
|
const said = await this.tellGateway("keeper", { handle: this.doorKey, on: true });
|
|
73259
73344
|
if (said?.status === 200) {
|
|
73345
|
+
await forgetFailedOpen(this, this.frontOrigin);
|
|
73260
73346
|
this._keeper.kept = true;
|
|
73261
73347
|
if (this.masto) this.masto.scheduling = true;
|
|
73262
73348
|
this.log("the gateway keeps this account running while the app is closed");
|
|
@@ -73470,7 +73556,7 @@ var BrowserAgent = class _BrowserAgent {
|
|
|
73470
73556
|
const warmFrom = restart ? await warmMeta(webId).catch(() => null) : null;
|
|
73471
73557
|
this.holderId = await this.deviceId();
|
|
73472
73558
|
this.frontOrigin = frontOrigin || null;
|
|
73473
|
-
this.copy = await openCopy(this, this.frontOrigin, { kept: isWarm(warmFrom) ? warmFrom.copy : null });
|
|
73559
|
+
this.copy = await openCopy(this, this.frontOrigin, { kept: isWarm(warmFrom) ? warmFrom.copy : null, askAnyway: !restart });
|
|
73474
73560
|
const warmRoot = isWarm(warmFrom) && !!warmFrom.copy === !!this.copy ? warmFrom.root : null;
|
|
73475
73561
|
const copyRoot = this.copy?.podHome?.startsWith(remotePod) ? this.copy.podHome.slice(remotePod.length) : null;
|
|
73476
73562
|
this._sweptAt = { ...warmFrom?.sweptAt || {} };
|