From 9db98e02b903cefd06ed942f59d2a815a54ceb21 Mon Sep 17 00:00:00 2001 From: Brad Date: Sun, 21 May 2023 16:59:45 -0500 Subject: [PATCH] create setCookie function to add a Set-Cookie header on a response --- src/setCookie.spec.ts | 35 +++++++++++++++++++++++++++++++++++ src/setCookie.ts | 24 ++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/setCookie.spec.ts create mode 100644 src/setCookie.ts diff --git a/src/setCookie.spec.ts b/src/setCookie.spec.ts new file mode 100644 index 00000000..29851686 --- /dev/null +++ b/src/setCookie.spec.ts @@ -0,0 +1,35 @@ +import 'isomorphic-fetch' +import { describe, expect, it } from 'vitest' +import { status } from './status' +import {setCookie} from "./setCookie"; + +describe('setCookie("name", "value"): Response', () => { + it('creates a response with the set-cookie header', async () => { + const response = status(200) + setCookie(response, "name", "value") + expect(response.headers.get("set-cookie")).toBe("name=value") + }) + it('creates a response with the set-cookie header using options', async () => { + const response = status(200) + setCookie(response, "name", "value", { + httpOnly: true, + secure: true, + }) + expect(response.headers.get("set-cookie")).toBe("name=value; HttpOnly; Secure") + }) + it('creates a response with the set-cookie header using all options', async () => { + const response = status(200) + const now = new Date(); + setCookie(response, "name", "value", { + httpOnly: true, + secure: true, + expires: now, + maxAge: 1000, + path: "/", + domain: "itty.dev", + partitioned: true, + sameSite: "Strict" + }) + expect(response.headers.get("set-cookie")).toBe(`name=value; Domain=itty.dev; Path=/; HttpOnly; Secure; Expires=${now.toUTCString()}; Max-Age=1000; Partitioned; SameSite=Strict`) + }) +}) diff --git a/src/setCookie.ts b/src/setCookie.ts new file mode 100644 index 00000000..29102d84 --- /dev/null +++ b/src/setCookie.ts @@ -0,0 +1,24 @@ +type CookieOptions = { + domain?: string; + path?: string; + expires?: Date; + httpOnly?: boolean; + maxAge?: number; + partitioned?: boolean; + secure?: boolean; + sameSite?: "Strict" | "Lax" | "None"; +} + +export const setCookie = (response: Response, name: string, value: string, options?: CookieOptions): Response => { + response.headers.append("Set-Cookie", `${name}=${value}\ +${options?.domain ? `; Domain=${options.domain}`: ""}\ +${options?.path ? `; Path=${options?.path}`: ""}\ +${options?.httpOnly ? `; HttpOnly`: ""}\ +${options?.secure ? `; Secure`: ""}\ +${options?.expires? `; Expires=${options.expires.toUTCString()}`: ""}\ +${options?.maxAge? `; Max-Age=${options.maxAge}`: ""}\ +${options?.partitioned? `; Partitioned`: ""}\ +${options?.sameSite? `; SameSite=${options.sameSite}`: ""}\ + `) + return response; +}