From db947a26880abd9df6826a65e36db53de06f59b4 Mon Sep 17 00:00:00 2001 From: svemagie <869694+svemagie@users.noreply.github.com> Date: Sun, 8 Mar 2026 04:17:01 +0100 Subject: [PATCH] Normalize legacy /admin login redirect targets --- README.md | 1 + scripts/patch-indieauth-devmode-guard.mjs | 43 +++++++++++++++++------ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 077f6ec4..f64e6f2a 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ## Admin login - The IndieKit admin uses root auth/session paths (for example: `/session/login`, `/auth`, `/auth/new-password`). +- Legacy `/admin` request paths are normalized to root login redirects (for example `/admin/posts` -> `/session/login?redirect=/posts`) to avoid post-login dead-end targets. - Login uses `PASSWORD_SECRET` (bcrypt hash), not `INDIEKIT_PASSWORD`. - If no `PASSWORD_SECRET` exists yet, open `/auth/new-password` once to generate it. - If login is blocked because `PASSWORD_SECRET` is missing/invalid, set `INDIEKIT_ALLOW_PASSWORD_SETUP=1` temporarily, restart, generate a new hash via `/auth/new-password`, set `PASSWORD_SECRET` to that hash, then remove `INDIEKIT_ALLOW_PASSWORD_SETUP`. diff --git a/scripts/patch-indieauth-devmode-guard.mjs b/scripts/patch-indieauth-devmode-guard.mjs index 67127567..334b11a7 100644 --- a/scripts/patch-indieauth-devmode-guard.mjs +++ b/scripts/patch-indieauth-devmode-guard.mjs @@ -4,16 +4,32 @@ const candidates = [ "node_modules/@indiekit/indiekit/lib/indieauth.js", ]; -const oldCode = `if (devMode) { +const oldDevModeCode = `if (devMode) { request.session.access_token = process.env.NODE_ENV; request.session.scope = "create update delete media"; } else if (!process.env.PASSWORD_SECRET) {`; -const newCode = `if (devMode && process.env.INDIEKIT_ALLOW_DEV_AUTH === "1") { +const newDevModeCode = `if (devMode && process.env.INDIEKIT_ALLOW_DEV_AUTH === "1") { request.session.access_token = process.env.NODE_ENV; request.session.scope = "create update delete media"; } else if (!process.env.PASSWORD_SECRET) {`; +const oldLoginRedirectCode = ` if (request.method === "GET") { + return response.redirect( + \`/session/login?redirect=\${request.originalUrl}\`, + ); + }`; + +const newLoginRedirectCode = ` if (request.method === "GET") { + const loginRedirect = + request.originalUrl === "/admin" + ? "/" + : request.originalUrl.replace(/^\\/admin(?=\\/)/, ""); + return response.redirect( + \`/session/login?redirect=\${loginRedirect}\`, + ); + }`; + async function exists(path) { try { await access(path); @@ -34,24 +50,29 @@ for (const filePath of candidates) { checked += 1; const source = await readFile(filePath, "utf8"); + let updated = source; - if (source.includes(newCode)) { - continue; + if (!updated.includes(newDevModeCode) && updated.includes(oldDevModeCode)) { + updated = updated.replace(oldDevModeCode, newDevModeCode); } - if (!source.includes(oldCode)) { - continue; + if ( + !updated.includes(newLoginRedirectCode) && + updated.includes(oldLoginRedirectCode) + ) { + updated = updated.replace(oldLoginRedirectCode, newLoginRedirectCode); } - const updated = source.replace(oldCode, newCode); - await writeFile(filePath, updated, "utf8"); - patched += 1; + if (updated !== source) { + await writeFile(filePath, updated, "utf8"); + patched += 1; + } } if (checked === 0) { console.log("[postinstall] No indieauth middleware files found"); } else if (patched === 0) { - console.log("[postinstall] indieauth dev-mode guard already patched"); + console.log("[postinstall] indieauth auth-guard patches already applied"); } else { - console.log(`[postinstall] Patched indieauth dev-mode guard in ${patched} file(s)`); + console.log(`[postinstall] Patched indieauth auth guards in ${patched} file(s)`); }