Middleware leggero per potare o debuggare le sessioni vuote (solo cookie + le tue regole) e mantenere snelli gli store Prisma/Redis.
Core agnostico — nessuna chiave applicativa all’interno. Porta tu la policy via opzioni.
- 🧹 Pota le sessioni “vuote” secondo le tue regole.
- 🔎 Debug con dry-run + logger; logger di mutazioni opzionale.
- 🧩 Agnostico: allowlist, predicate e denylist — nessuna chiave hardcoded.
- 🧪 Indipendente dallo store: Prisma/SQL, Redis, ecc.
- ⚙️ Predicate componibili (
emptyObject,equals,oneOf,and,or,flashEmptyOrOneOf). - 🧰 Preset opzionale:
cookieFlash()— avvio rapido. - 🧯 Safe: niente env, footprint minimo.
npm i @codecorn/empty-session-reaper// ✅ CommonJS (require)
const {
wireEmptySessionReaper,
predicates,
buildAllowedKeys,
wireSessionMutationLogger, // opzionale
} = require("@codecorn/empty-session-reaper");
const { cookieFlash } = require("@codecorn/empty-session-reaper/presets");// ✅ ESM / TypeScript
import {
wireEmptySessionReaper,
predicates as P,
buildAllowedKeys,
wireSessionMutationLogger, // opzionale
} from "@codecorn/empty-session-reaper";
import { cookieFlash } from "@codecorn/empty-session-reaper/presets";// Significato di buildAllowedKeys(input, expandBase, base):
// - base: lista iniziale (default: ['cookie'])
// - input: chiavi extra consentite (es. ['flash'])
// - expandBase:
// true => unisce base + input (['cookie'] + ['flash'] -> ['cookie','flash'])
// false => usa solo input (['flash'])
wireEmptySessionReaper(app, {
logger: (m, meta) => console.debug(m, meta),
allowedKeys: buildAllowedKeys(["flash"], true, ["cookie"]),
maxKeys: 2,
keyPredicates: { flash: P.emptyObject }, // flash innocuo se {}
});const isLoginFlash = (flash: any) => {
if (!flash || typeof flash !== "object") return false;
const ks = Object.keys(flash);
if (ks.length !== 1) return false;
const arr = Array.isArray((flash as any)[ks[0]]) ? (flash as any)[ks[0]] : [];
return arr.length === 1 && /^please sign in\.?$/i.test(String(arr[0] || ""));
};
wireEmptySessionReaper(app, {
logger: (m, meta) => console.debug(m, meta),
allowedKeys: ["cookie", "flash", "url", "flag"],
maxKeys: 4,
disallowedKeyPatterns: [/^csrf/i, /^token/i, /^user/i],
keyPredicates: {
flash: (v) => P.emptyObject(v) || isLoginFlash(v),
url: (v) => ["/", "/login", "/signin"].includes(String(v || "")),
flag: P.oneOf([false, "auto"]),
},
isSessionPrunable: (s) => {
const url = String((s as any).url || "");
return !(/\.(env|git)\b/i.test(url) || /\/upload\/\./i.test(url));
},
});// cookie + flash: flash è {} OPPURE un messaggio ammesso (default: "Please sign in.")
const preset = cookieFlash({
// flashKey: 'flash',
// flashField: 'error',
// loginMessages: [/^please sign in\.?$/i, /^access denied$/i],
// extraAllowedKeys: ['url'],
// maxKeys: 3,
// disallowedKeyPatterns: [/^csrf/i, /^token/i],
// extraPredicates: { url: (v) => ['/', '/login'].includes(String(v || '')) },
// finalCheck: (s) => !/\.env\b/i.test(String((s as any).url || '')),
});
wireEmptySessionReaper(app, { logger: console.debug, ...preset });// Subito dopo session(...) e prima del reaper:
wireSessionMutationLogger(app, {
logger: (label, meta) => console.debug(label, meta),
includeValues: false, // true per loggare anche i valori (usa redact per mascherarli)
redact: (k, v) => (/(token|secret|pass)/i.test(k) ? "[redacted]" : v),
label: "mutazione sessione",
});Logga
{ path, added: [...], removed: [...] }quando le chiavi di sessione cambiano.
createEmptySessionReaper(opts) -> (req, res, next) => void
wireEmptySessionReaper(app, opts) -> middleware
buildAllowedKeys(input?: string[], expandBase?: boolean, base?: string[]) -> string[]
- base: lista iniziale (default: ["cookie"])
- input: chiavi extra ammesse (es. ["flash"])
- expandBase: true = unisci; false = usa solo input
predicates:
- emptyObject(v)
- equals(x)
- oneOf([a,b,c])
- and(p1,p2,...)
- or(p1,p2,...)
- flashEmptyOrOneOf(field='error', messages=[/^please sign in\.?$/i])
createSessionMutationLogger(opts) -> middleware
wireSessionMutationLogger(app, opts) -> middleware
lookUpSessMutation(app, opts) -> alias di wireSessionMutationLogger- Cugggì (co-author & review) — PYTORCHIA FOR LIFE
- Federico Girolami (CodeCorn) — Maintainer
👨💻 Federico Girolami
Full Stack Developer | System Integrator | Digital Solution Architect 🚀
📫 Get in Touch
🌐 Website: codecorn.it *(Under Construction)*
📧 Email: f.girolami@codecorn.it
🐙 GitHub: github.com/fgirolami29
MIT © CodeCorn™
Distribuito sotto licenza MIT.
Pull request benvenute. Per grosse modifiche apri una issue prima di iniziare.
Powered by CodeCorn™ 🚀