Skip to content

Latest commit

 

History

History
233 lines (183 loc) · 7.56 KB

File metadata and controls

233 lines (183 loc) · 7.56 KB

🇮🇹 README (IT) — README.it.md


@codecorn/empty-session-reaper

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.

npm downloads stars issues CI coverage umbrella license


Caratteristiche

  • 🧹 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.

Installazione

npm i @codecorn/empty-session-reaper

Import

// ✅ 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";

Uso A — “cookie + flash vuoto” (base)

// 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 {}
});

Uso B — policy avanzata (massimo controllo)

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));
  },
});

Uso C — preset opzionale cookieFlash

// 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 });

Bonus: Logger di mutazioni (capire l’origine)

// 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.


API (core)

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

Crediti

  • Cugggì (co-author & review)PYTORCHIA FOR LIFE
  • Federico Girolami (CodeCorn) — Maintainer

👤 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


📝 License

MIT © CodeCorn™

Distribuito sotto licenza MIT.


🤝 Contribuisci

Pull request benvenute. Per grosse modifiche apri una issue prima di iniziare.

Powered by CodeCorn™ 🚀