UNPKG

kequapp

Version:

A minimal, zero-magic Node web framework built on native APIs

73 lines (72 loc) 2.54 kB
import Ex from "../built-in/tools/ex.js"; export default function createCookies(req, res) { const result = {}; let values; function get(key) { setup(); return values[key]; } function set(key, value, options) { setup(); validateCookieName(key); const attrs = [`${key}=${encodeURIComponent(value)}`]; if (options) { if (options.expires !== undefined) attrs.push(`Expires=${formatExpires(options.expires)}`); if (options.maxAge !== undefined) attrs.push(`Max-Age=${options.maxAge}`); if (options.domain !== undefined) attrs.push(`Domain=${options.domain}`); if (options.path !== undefined) attrs.push(`Path=${options.path}`); if (options.secure) attrs.push('Secure'); if (options.httpOnly) attrs.push('HttpOnly'); if (options.partitioned) attrs.push('Partitioned'); if (options.sameSite !== undefined) attrs.push(`SameSite=${options.sameSite}`); } result[key] = attrs.join('; '); values[key] = value; res.setHeader('Set-Cookie', Object.values(result)); } function remove(key) { setup(); set(key, '', { maxAge: 0 }); delete values[key]; } function setup() { if (values === undefined) values = parseCookieHeader(req.headers.cookie); } return { get, set, remove }; } function parseCookieHeader(cookie) { const result = {}; if (cookie !== undefined) { for (const part of cookie.split(/; */)) { const [key, value] = part.split('='); if (key) { result[key] = decodeURIComponent(value ?? ''); } } } return result; } function validateCookieName(name) { if (name.includes(';')) throw Ex.InternalServerError(`Cookie name "${name}" contains invalid character ";"`); if (name.includes('=')) throw Ex.InternalServerError(`Cookie name "${name}" contains invalid character "="`); if (name.includes(',')) throw Ex.InternalServerError(`Cookie name "${name}" contains invalid character ","`); if (name.includes(' ')) throw Ex.InternalServerError(`Cookie name "${name}" contains invalid character " "`); } function formatExpires(expires) { if (expires instanceof Date) return expires.toUTCString(); return expires; }