fedipod 1.57.2 → 1.57.5
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/gateway.md +4 -2
- package/lib/core/intake/group.mjs +5 -3
- package/lib/core/intake/index.mjs +8 -2
- package/lib/gateway/copy.mjs +23 -2
- package/lib/gateway/front-core.mjs +7 -7
- package/lib/gateway/gateway-core.mjs +8 -5
- package/lib/gateway/held-mail.mjs +0 -12
- package/lib/gateway/keeper-due.mjs +17 -4
- package/package.json +2 -2
- package/scripts/check-netlify-bundles.mjs +7 -2
- package/scripts/forum-package.mjs +28 -6
- package/web/app/boot.mjs +21 -5
- package/web/app/dist/boot.js +88 -29
- package/web/app/dist/boot.js.map +2 -2
- package/web/app/dist/sw.js +99 -30
- package/web/app/dist/sw.js.map +3 -3
- package/web/app/sw-src.mjs +23 -2
package/web/app/dist/sw.js
CHANGED
|
@@ -59641,7 +59641,8 @@ function isModerationAsk(intake, activity) {
|
|
|
59641
59641
|
if (activity.type === "Delete") {
|
|
59642
59642
|
const id = typeof activity.object === "string" ? activity.object : activity.object?.id;
|
|
59643
59643
|
const s = id && intake.store.getStatuses().find((x) => x.noteId === id);
|
|
59644
|
-
|
|
59644
|
+
const by = typeof activity.actor === "string" ? activity.actor : activity.actor?.id;
|
|
59645
|
+
return !!s && s.kind !== "post" && s.actor !== by;
|
|
59645
59646
|
}
|
|
59646
59647
|
if (activity.type === "Add" || activity.type === "Remove") {
|
|
59647
59648
|
const target = typeof activity.target === "string" ? activity.target : activity.target?.id;
|
|
@@ -65864,6 +65865,7 @@ var Intake = class {
|
|
|
65864
65865
|
}
|
|
65865
65866
|
}
|
|
65866
65867
|
async _drainOnce() {
|
|
65868
|
+
this.moreWaiting = false;
|
|
65867
65869
|
this._sweepGen = this.store.generation;
|
|
65868
65870
|
const cooling = this.drainCooldownUntil - Date.now();
|
|
65869
65871
|
if (cooling > 0) {
|
|
@@ -65919,10 +65921,11 @@ var Intake = class {
|
|
|
65919
65921
|
return true;
|
|
65920
65922
|
};
|
|
65921
65923
|
let spent = 0;
|
|
65924
|
+
let cut = false;
|
|
65922
65925
|
for (const { url, size, receipt: hasReceipt } of items) {
|
|
65923
65926
|
if (url.endsWith(".keep")) continue;
|
|
65924
65927
|
if (spent >= MAX_ITEMS_PER_DRAIN) {
|
|
65925
|
-
this._drainAgain = handled > 0 || pending.length > 0;
|
|
65928
|
+
cut = this._drainAgain = handled > 0 || pending.length > 0;
|
|
65926
65929
|
break;
|
|
65927
65930
|
}
|
|
65928
65931
|
if (isBatch(url)) {
|
|
@@ -65971,7 +65974,9 @@ var Intake = class {
|
|
|
65971
65974
|
if (!await dropStrayReceipt(this.remote, stray)) break;
|
|
65972
65975
|
await new Promise((r) => setTimeout(r, DELETE_GAP_MS));
|
|
65973
65976
|
}
|
|
65974
|
-
|
|
65977
|
+
const more = handled > 0 && all.length > items.length;
|
|
65978
|
+
this.moreWaiting = more || cut;
|
|
65979
|
+
if (more && !this.stopped) this._drainAgain = true;
|
|
65975
65980
|
}
|
|
65976
65981
|
// One delivery, alone in the inbox or in a batch: read as JSON-LD, checked
|
|
65977
65982
|
// against its receipt, handled, and dead-lettered if refused. Throws when it
|
|
@@ -74794,49 +74799,89 @@ function solidOidcSession({ dbName = "solid-oidc-session", clientName = "Solid a
|
|
|
74794
74799
|
await idbDel("session");
|
|
74795
74800
|
await idbDel("pending");
|
|
74796
74801
|
}
|
|
74797
|
-
|
|
74798
|
-
|
|
74799
|
-
|
|
74800
|
-
|
|
74801
|
-
|
|
74802
|
+
const ended = (message) => Object.assign(new Error(message), { signedOut: true });
|
|
74803
|
+
const stillGood = (row) => Date.now() < row.expiresAt - 3e4;
|
|
74804
|
+
const locks = () => globalThis.navigator?.locks;
|
|
74805
|
+
const oneAtATime = (fn) => locks()?.request ? locks().request(`${dbName}:renew`, fn) : fn();
|
|
74806
|
+
const RACE_WAIT_MS = 1500;
|
|
74807
|
+
function sessionHandle(first) {
|
|
74808
|
+
let s = first;
|
|
74809
|
+
let jwkP = publicJwk(s.pair);
|
|
74810
|
+
const host = () => new URL(s.tokenEndpoint).host;
|
|
74811
|
+
const takeUp2 = (row) => {
|
|
74812
|
+
s = row;
|
|
74813
|
+
jwkP = publicJwk(row.pair);
|
|
74814
|
+
};
|
|
74815
|
+
const reread = async () => {
|
|
74816
|
+
const row = await idbGet("session");
|
|
74817
|
+
if (!row) throw ended("signed out \u2014 sign in again");
|
|
74818
|
+
if (row.webId !== s.webId) throw new Error("signed in as somebody else since this session was read");
|
|
74819
|
+
takeUp2(row);
|
|
74820
|
+
};
|
|
74821
|
+
const refresh = () => oneAtATime(async () => {
|
|
74822
|
+
const mine = s.accessToken;
|
|
74823
|
+
await reread();
|
|
74824
|
+
if (s.accessToken !== mine && stillGood(s)) return;
|
|
74825
|
+
if (!s.refreshToken) {
|
|
74826
|
+
await idbDel("session");
|
|
74827
|
+
throw ended("session expired and there is no refresh token \u2014 sign in again");
|
|
74828
|
+
}
|
|
74829
|
+
const sent = s;
|
|
74802
74830
|
const jwk = await jwkP;
|
|
74803
74831
|
let res;
|
|
74804
74832
|
try {
|
|
74805
|
-
res = await fetch(
|
|
74833
|
+
res = await fetch(sent.tokenEndpoint, {
|
|
74806
74834
|
method: "POST",
|
|
74807
|
-
headers: { "content-type": "application/x-www-form-urlencoded", dpop: await dpopProof(
|
|
74808
|
-
body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: refreshToken, client_id:
|
|
74835
|
+
headers: { "content-type": "application/x-www-form-urlencoded", dpop: await dpopProof(sent.pair, jwk, "POST", sent.tokenEndpoint) },
|
|
74836
|
+
body: new URLSearchParams({ grant_type: "refresh_token", refresh_token: sent.refreshToken, client_id: sent.client_id, scope: "openid webid offline_access" })
|
|
74809
74837
|
});
|
|
74810
74838
|
} catch (e) {
|
|
74811
|
-
throw new Error(`${e.message} \u2014 renewing your sign-in at ${
|
|
74839
|
+
throw new Error(`${e.message} \u2014 renewing your sign-in at ${host()}`);
|
|
74812
74840
|
}
|
|
74813
74841
|
const tok = await res.json().catch(() => ({}));
|
|
74842
|
+
const now = await idbGet("session");
|
|
74843
|
+
if (now && now.webId !== sent.webId) throw new Error("signed in as somebody else while this session was refreshing");
|
|
74844
|
+
if (res.ok && tok.access_token) {
|
|
74845
|
+
if (!now) throw ended("signed out while this sign-in was being renewed");
|
|
74846
|
+
takeUp2({
|
|
74847
|
+
...sent,
|
|
74848
|
+
accessToken: tok.access_token,
|
|
74849
|
+
refreshToken: tok.refresh_token || sent.refreshToken,
|
|
74850
|
+
expiresAt: Date.now() + Math.max(30, tok.expires_in || 300) * 1e3
|
|
74851
|
+
});
|
|
74852
|
+
await idbPut("session", s);
|
|
74853
|
+
return;
|
|
74854
|
+
}
|
|
74814
74855
|
if (res.status === 429) {
|
|
74815
|
-
throw new Error(`${
|
|
74856
|
+
throw new Error(`${host()} is asking us to slow down \u2014 your sign-in could not be renewed just now`);
|
|
74816
74857
|
}
|
|
74817
|
-
if (
|
|
74858
|
+
if (res.status >= 400 && res.status < 500 && typeof tok.error === "string") {
|
|
74859
|
+
let row = now;
|
|
74860
|
+
if (row && row.accessToken === sent.accessToken && !locks()?.request) {
|
|
74861
|
+
await new Promise((r) => setTimeout(r, RACE_WAIT_MS));
|
|
74862
|
+
row = await idbGet("session");
|
|
74863
|
+
}
|
|
74864
|
+
if (row && row.webId === sent.webId && row.accessToken !== sent.accessToken && stillGood(row)) {
|
|
74865
|
+
takeUp2(row);
|
|
74866
|
+
return;
|
|
74867
|
+
}
|
|
74868
|
+
if (!row) throw ended("signed out \u2014 sign in again");
|
|
74818
74869
|
await idbDel("session");
|
|
74819
|
-
throw
|
|
74820
|
-
}
|
|
74821
|
-
accessToken = tok.access_token;
|
|
74822
|
-
expiresAt = Date.now() + Math.max(30, tok.expires_in || 300) * 1e3;
|
|
74823
|
-
if (tok.refresh_token) refreshToken = tok.refresh_token;
|
|
74824
|
-
const now = await idbGet("session");
|
|
74825
|
-
if (now && now.webId !== s.webId) {
|
|
74826
|
-
throw new Error("signed in as somebody else while this session was refreshing");
|
|
74870
|
+
throw ended("refresh failed \u2014 sign in again");
|
|
74827
74871
|
}
|
|
74828
|
-
|
|
74829
|
-
};
|
|
74872
|
+
throw new Error(`${host()} could not renew your sign-in just now (HTTP ${res.status})`);
|
|
74873
|
+
});
|
|
74830
74874
|
const send = async (url, init) => {
|
|
74875
|
+
const { accessToken, pair } = s;
|
|
74831
74876
|
const jwk = await jwkP;
|
|
74832
74877
|
const ath = b64u3(await sha2564(accessToken));
|
|
74833
|
-
const headers = { ...init.headers || {}, authorization: `DPoP ${accessToken}`, dpop: await dpopProof(
|
|
74878
|
+
const headers = { ...init.headers || {}, authorization: `DPoP ${accessToken}`, dpop: await dpopProof(pair, jwk, init.method || "GET", url, ath) };
|
|
74834
74879
|
return fetch(url, { ...init, headers });
|
|
74835
74880
|
};
|
|
74836
74881
|
const authFetch = async (url, init = {}) => {
|
|
74837
|
-
if (
|
|
74882
|
+
if (!stillGood(s)) await refresh();
|
|
74838
74883
|
const res = await send(url, init);
|
|
74839
|
-
if (res.status === 401 && refreshToken) {
|
|
74884
|
+
if (res.status === 401 && s.refreshToken) {
|
|
74840
74885
|
try {
|
|
74841
74886
|
await refresh();
|
|
74842
74887
|
} catch {
|
|
@@ -74846,7 +74891,17 @@ function solidOidcSession({ dbName = "solid-oidc-session", clientName = "Solid a
|
|
|
74846
74891
|
}
|
|
74847
74892
|
return res;
|
|
74848
74893
|
};
|
|
74849
|
-
|
|
74894
|
+
const check = async () => {
|
|
74895
|
+
try {
|
|
74896
|
+
await reread();
|
|
74897
|
+
if (!stillGood(s)) await refresh();
|
|
74898
|
+
return true;
|
|
74899
|
+
} catch (e) {
|
|
74900
|
+
if (e.signedOut) return false;
|
|
74901
|
+
throw e;
|
|
74902
|
+
}
|
|
74903
|
+
};
|
|
74904
|
+
return { webId: first.webId, issuer: first.issuer, fetch: authFetch, refresh, check, signOut: signOut2 };
|
|
74850
74905
|
}
|
|
74851
74906
|
return { beginLogin: beginLogin2, completeLogin: completeLogin2, getSession: getSession2, signOut: signOut2 };
|
|
74852
74907
|
}
|
|
@@ -74983,9 +75038,11 @@ function notAllowed(request, url) {
|
|
|
74983
75038
|
}
|
|
74984
75039
|
self.addEventListener("install", () => self.skipWaiting());
|
|
74985
75040
|
self.addEventListener("activate", (e) => e.waitUntil(self.clients.claim()));
|
|
75041
|
+
var signedOut = (message) => Object.assign(new Error(message), { code: "signed-out" });
|
|
74986
75042
|
async function bootFromSession(frontOrigin, restart) {
|
|
74987
75043
|
const oidc = await getSession();
|
|
74988
|
-
if (!oidc) throw
|
|
75044
|
+
if (!oidc) throw signedOut("no session \u2014 sign in first");
|
|
75045
|
+
if (await oidc.check().catch(() => true) === false) throw signedOut("the sign-in this browser was holding has ended \u2014 sign in again");
|
|
74989
75046
|
const a = new BrowserAgent({ log: agentLog });
|
|
74990
75047
|
a.recentLog = recentLog;
|
|
74991
75048
|
await a.boot({ oidc, frontOrigin: frontOrigin || self.location.origin, restart });
|
|
@@ -75044,6 +75101,17 @@ function stillWorking(first) {
|
|
|
75044
75101
|
});
|
|
75045
75102
|
return Promise.race([work, cap]).finally(() => clearTimeout(timer));
|
|
75046
75103
|
}
|
|
75104
|
+
var sentToSignIn = 0;
|
|
75105
|
+
async function toSignIn() {
|
|
75106
|
+
if (Date.now() - sentToSignIn < 1e4) return;
|
|
75107
|
+
sentToSignIn = Date.now();
|
|
75108
|
+
const pages = await self.clients.matchAll({ type: "window" }).catch(() => []);
|
|
75109
|
+
for (const c of pages) {
|
|
75110
|
+
const at = new URL(c.url).pathname;
|
|
75111
|
+
if (c.frameType === "top-level" && (at.startsWith("/app/") || at.startsWith("/admin/"))) c.navigate("/").catch(() => {
|
|
75112
|
+
});
|
|
75113
|
+
}
|
|
75114
|
+
}
|
|
75047
75115
|
async function serve(request, url) {
|
|
75048
75116
|
const refuse = notAllowed(request, url);
|
|
75049
75117
|
if (refuse) {
|
|
@@ -75053,7 +75121,8 @@ async function serve(request, url) {
|
|
|
75053
75121
|
if (!agent) {
|
|
75054
75122
|
try {
|
|
75055
75123
|
await ensureBooting(void 0, { restart: true });
|
|
75056
|
-
} catch {
|
|
75124
|
+
} catch (e) {
|
|
75125
|
+
if (e.code === "signed-out") await toSignIn();
|
|
75057
75126
|
}
|
|
75058
75127
|
}
|
|
75059
75128
|
if (!agent) return json(503, { error: "not signed in on this browser \u2014 sign in at the front page" });
|