UNPKG

@worker-tools/middleware

Version:

A suite of standalone HTTP server middlewares for Worker Runtimes.

86 lines 3.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.storageSession = exports.cookieSession = void 0; const web_uuid_1 = require("web-uuid"); const base64_encoding_1 = require("base64-encoding"); const immer_1 = require("immer"); const msgpackr_1 = require("msgpackr"); (0, immer_1.enableMapSet)(); const stringifySessionCookie = (value) => new base64_encoding_1.Base64Encoder({ url: true }).encode(new msgpackr_1.Encoder({ structuredClone: true }).encode(value)); const parseSessionCookie = (value) => new msgpackr_1.Decoder({ structuredClone: true }).decode(new base64_encoding_1.Base64Decoder().decode(value)); /** * Cookie session middleware for worker runtimes. * * Requires a cookie store, preferably encrypted or signed. * * Important: This will serialize the entire session data and store it in a cookie. It is sent with every request! * Only applicable for small session objects. Use `storageSession` for a traditional, KV store-backed session. */ function cookieSession(options = {}) { return async (ax) => { const ctx = await ax; const { cookieStore, cookies } = ctx; const { defaultSession, cookieName = 'obj', expirationTtl = 5 * 60 } = options; const cookieVal = cookies[cookieName]; const original = cookieVal ? parseSessionCookie(cookieVal) : defaultSession !== null && defaultSession !== void 0 ? defaultSession : {}; const session = (0, immer_1.createDraft)(original); const newContext = Object.assign(ctx, { session, cookieSession: session }); ctx.effects.push(() => { const next = (0, immer_1.finishDraft)(session); if (next !== original) { cookieStore.set({ name: cookieName, value: stringifySessionCookie(next), expires: new Date(Date.now() + expirationTtl * 1000), sameSite: 'lax', httpOnly: true, }); } }); return newContext; }; } exports.cookieSession = cookieSession; /** * Session middleware for worker runtimes. * * Need to provide a `StorageArea` to persist the session between requests. * See `@worker-tools/kv-storage`. * */ // FIXME: Will "block" until session object is retrieved from KV => provide "unyielding" version that returns a promise? function storageSession(options) { return async (ax) => { var _a, _b; const ctx = await ax; const { cookies, cookieStore } = ctx; const { storage, defaultSession, cookieName = 'sid', expirationTtl = 5 * 60 } = options; const cookieVal = cookies[cookieName]; const sid = cookieVal ? new web_uuid_1.WebUUID(cookieVal) : web_uuid_1.WebUUID.v4(); const original = (_b = (_a = (await storage.get(sid))) !== null && _a !== void 0 ? _a : defaultSession) !== null && _b !== void 0 ? _b : {}; const session = (0, immer_1.createDraft)(original); const newContext = Object.assign(ctx, { session, storageSession: session }); ctx.waitUntil((async () => { await ctx.handled; await ctx.flushed; const next = (0, immer_1.finishDraft)(session); if (next !== original) { await storage.set(sid, next, { expirationTtl }); } })()); if (!cookieVal) { ctx.effects.push(() => { cookieStore.set({ name: cookieName, value: sid.id, expires: new Date(Date.now() + expirationTtl * 1000), sameSite: 'lax', httpOnly: true, }); }); } return newContext; }; } exports.storageSession = storageSession; //# sourceMappingURL=session.js.map