Bypass auth/session pages in frontend serviceworker cache
This commit is contained in:
@@ -77,6 +77,6 @@
|
|||||||
- The frontend sharp runtime patch makes icon generation non-fatal on FreeBSD when `sharp` cannot load, preventing startup crashes in asset controller imports.
|
- The frontend sharp runtime patch makes icon generation non-fatal on FreeBSD when `sharp` cannot load, preventing startup crashes in asset controller imports.
|
||||||
- The files upload route patch fixes browser multi-upload by posting to `/files/upload` (session-authenticated) instead of direct `/media` calls without bearer token.
|
- The files upload route patch fixes browser multi-upload by posting to `/files/upload` (session-authenticated) instead of direct `/media` calls without bearer token.
|
||||||
- The files upload locale patch adds missing `files.upload.dropText`/`files.upload.browse`/`files.upload.submitMultiple` labels in endpoint locale files so UI text does not render raw translation keys.
|
- The files upload locale patch adds missing `files.upload.dropText`/`files.upload.browse`/`files.upload.submitMultiple` labels in endpoint locale files so UI text does not render raw translation keys.
|
||||||
- The frontend serviceworker patch ensures `@indiekit/frontend/lib/serviceworker.js` exists at runtime to avoid ENOENT in the offline/service worker route.
|
- The frontend serviceworker patch ensures `@indiekit/frontend/lib/serviceworker.js` exists at runtime, and forces network-only handling for `/auth` and `/session` pages to avoid stale cached login/consent screens.
|
||||||
- The conversations guard patch prevents `Cannot read properties of undefined (reading 'find')` when the `conversation_items` collection is temporarily unavailable.
|
- The conversations guard patch prevents `Cannot read properties of undefined (reading 'find')` when the `conversation_items` collection is temporarily unavailable.
|
||||||
- The indieauth dev-mode guard patch prevents accidental production auth bypass by requiring explicit `INDIEKIT_ALLOW_DEV_AUTH=1` to enable dev auto-login.
|
- The indieauth dev-mode guard patch prevents accidental production auth bypass by requiring explicit `INDIEKIT_ALLOW_DEV_AUTH=1` to enable dev auto-login.
|
||||||
|
|||||||
@@ -23,6 +23,51 @@ self.addEventListener("activate", (event) => {
|
|||||||
self.addEventListener("fetch", () => {});
|
self.addEventListener("fetch", () => {});
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const authBypassMarker = "Never cache auth/session pages";
|
||||||
|
const oldFetchCacheLine = " const retrieveFromCache = caches.match(request);";
|
||||||
|
const newFetchCacheBlock = ` const requestUrl = new URL(request.url);
|
||||||
|
|
||||||
|
// Never cache auth/session pages; always go to network.
|
||||||
|
if (
|
||||||
|
requestUrl.origin === self.location.origin &&
|
||||||
|
/^\\/(auth|session)(?:\\/|$)/.test(requestUrl.pathname)
|
||||||
|
) {
|
||||||
|
event.respondWith(fetch(request));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const retrieveFromCache = caches.match(request);`;
|
||||||
|
|
||||||
|
const clearAuthSessionEntriesFn = `
|
||||||
|
async function clearAuthSessionEntries() {
|
||||||
|
try {
|
||||||
|
const pagesCache = await caches.open(pagesCacheName);
|
||||||
|
const keys = await pagesCache.keys();
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
keys
|
||||||
|
.filter((request) => {
|
||||||
|
const requestUrl = new URL(request.url);
|
||||||
|
return (
|
||||||
|
requestUrl.origin === self.location.origin &&
|
||||||
|
/^\\/(auth|session)(?:\\/|$)/.test(requestUrl.pathname)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map((request) => pagesCache.delete(request)),
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error clearing auth/session cache entries", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const activateOld = ` await clearOldCaches();
|
||||||
|
await clients.claim();`;
|
||||||
|
|
||||||
|
const activateNew = ` await clearOldCaches();
|
||||||
|
await clearAuthSessionEntries();
|
||||||
|
await clients.claim();`;
|
||||||
|
|
||||||
async function exists(filePath) {
|
async function exists(filePath) {
|
||||||
try {
|
try {
|
||||||
await access(filePath);
|
await access(filePath);
|
||||||
@@ -32,11 +77,33 @@ async function exists(filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await exists(expected)) {
|
function patchServiceworker(content) {
|
||||||
console.log("[postinstall] frontend serviceworker already present");
|
let updated = content;
|
||||||
process.exit(0);
|
|
||||||
|
if (!updated.includes(authBypassMarker) && updated.includes(oldFetchCacheLine)) {
|
||||||
|
updated = updated.replace(oldFetchCacheLine, newFetchCacheBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!updated.includes("async function clearAuthSessionEntries()") &&
|
||||||
|
updated.includes("async function trimCache(cacheName, maxItems)")
|
||||||
|
) {
|
||||||
|
updated = updated.replace(
|
||||||
|
"async function trimCache(cacheName, maxItems)",
|
||||||
|
`${clearAuthSessionEntriesFn}\nasync function trimCache(cacheName, maxItems)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated.includes(activateOld)) {
|
||||||
|
updated = updated.replace(activateOld, activateNew);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
let restored = false;
|
||||||
|
|
||||||
|
if (!(await exists(expected))) {
|
||||||
let sourcePath = null;
|
let sourcePath = null;
|
||||||
for (const candidate of candidates) {
|
for (const candidate of candidates) {
|
||||||
if (await exists(candidate)) {
|
if (await exists(candidate)) {
|
||||||
@@ -50,8 +117,21 @@ await mkdir(path.dirname(expected), { recursive: true });
|
|||||||
if (sourcePath) {
|
if (sourcePath) {
|
||||||
const content = await readFile(sourcePath, "utf8");
|
const content = await readFile(sourcePath, "utf8");
|
||||||
await writeFile(expected, content, "utf8");
|
await writeFile(expected, content, "utf8");
|
||||||
|
restored = true;
|
||||||
console.log(`[postinstall] Restored frontend serviceworker from ${sourcePath}`);
|
console.log(`[postinstall] Restored frontend serviceworker from ${sourcePath}`);
|
||||||
} else {
|
} else {
|
||||||
await writeFile(expected, fallback, "utf8");
|
await writeFile(expected, fallback, "utf8");
|
||||||
|
restored = true;
|
||||||
console.log("[postinstall] Created fallback frontend serviceworker");
|
console.log("[postinstall] Created fallback frontend serviceworker");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = await readFile(expected, "utf8");
|
||||||
|
const updated = patchServiceworker(source);
|
||||||
|
|
||||||
|
if (updated !== source) {
|
||||||
|
await writeFile(expected, updated, "utf8");
|
||||||
|
console.log("[postinstall] Patched frontend serviceworker auth/session cache bypass");
|
||||||
|
} else if (!restored) {
|
||||||
|
console.log("[postinstall] frontend serviceworker already present");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user