UNPKG

koa-stateless-csrf

Version:
77 lines (76 loc) 2.44 kB
import { timingSafeEqual as y, randomBytes as k } from "crypto"; const a = 32, b = () => k(a), E = (e, n) => e.length === a && n.length === a && y(e, n), O = (e, n) => e.length === a && n.length === a * 2 ? E(e, S(n)) : !1, o = (e, n) => { const l = e.length; if (l !== n.length) throw new Error("Lengths of slices are not equal"); for (let f = 0; f < l; ++f) e[f] ^= n[f]; }, C = (e) => { if (e.length !== a) throw new Error("Invalid token length"); const n = Buffer.allocUnsafe(a * 2); e.copy(n); const l = k(a); return l.copy(n, a), o(n.subarray(0, a), l), n; }, S = (e) => { if (e.length !== a * 2) throw new Error("Invalid token length"); const n = e.subarray(0, a), l = e.subarray(a); return o(n, l), n; }, v = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS", "TRACE"]), B = (e) => { e.throw( 400, "The calling origin is not allowed to perform this request", { name: "CsrfError" } ); }, i = (e) => { e.throw( 400, "The CSRF token in the cookie doesn't match the one received in a header", { name: "CsrfError" } ); }, R = (e) => { const n = (e == null ? void 0 : e.cookieName) ?? "csrf_token", l = (e == null ? void 0 : e.headerName) ?? "X-CSRF-Token", f = (r) => { const t = r.get(l); return t ? t === "fetch" ? "fetch" : Buffer.from(t, "base64") : null; }, u = (r, t) => { r.set(l, C(t).toString("base64")); }, d = (r, t) => { r.cookies.set( n, t.toString("base64"), { path: "/", ...e == null ? void 0 : e.cookieOptions, httpOnly: !0, signed: !1 } ); }, T = (r) => { const t = b(); return d(r, t), t; }, g = (r) => { let s = Buffer.from(r.cookies.get(n) ?? "", "base64").subarray(0, a), c = !1; return s.length !== a && (s = T(r), c = !0), [s, c]; }; return async (r, t) => { (e != null && e.disableWithoutOrigin || e != null && e.allowedOrigins) && r.vary("Origin"), r.vary("Cookie"); const s = r.get("Origin"); if (!s && (e != null && e.disableWithoutOrigin)) return t(); if (e != null && e.allowedOrigins && !e.allowedOrigins.includes(s)) return B(r); const c = f(r); if (c === "fetch") { const [w] = g(r); u(r, w); } if (v.has(r.method)) return t(); const [h, m] = g(r); return m || !Buffer.isBuffer(c) || !O(h, c) ? (u(r, h), i(r)) : t(); }; }; export { R as csrfMiddleware };