because I got bored of customising my CV for every job
1import { Injectable } from "@nestjs/common";
2import { ConfigService } from "@nestjs/config";
3import type { Response } from "express";
4
5type CookieOptionsInput = {
6 httpOnly?: boolean;
7 secure?: boolean;
8 sameSite?: "lax" | "strict" | "none";
9 maxAge?: number;
10 expires?: Date;
11 path?: string;
12};
13
14type CookieOptions = {
15 httpOnly: boolean;
16 secure: boolean;
17 sameSite: "lax" | "strict";
18 maxAge?: number;
19 expires?: Date;
20 path: string;
21};
22
23@Injectable()
24export class CookieService {
25 constructor(private readonly configService: ConfigService) {}
26
27 private getCookieOptions(options?: CookieOptionsInput): CookieOptions {
28 const isDevelopment =
29 this.configService.get<string>("NODE_ENV") !== "production";
30 const isSecure = options?.secure ?? !isDevelopment;
31
32 const sameSiteOption = options?.sameSite;
33 const defaultSameSite = isDevelopment ? "lax" : "strict";
34 const sameSite =
35 sameSiteOption === "none"
36 ? defaultSameSite
37 : (sameSiteOption ?? defaultSameSite);
38
39 return {
40 httpOnly: options?.httpOnly ?? true,
41 secure: isSecure,
42 sameSite,
43 ...(options?.maxAge !== undefined && { maxAge: options.maxAge }),
44 ...(options?.expires !== undefined && { expires: options.expires }),
45 path: options?.path ?? "/",
46 };
47 }
48
49 setCookie(
50 res: Response,
51 name: string,
52 value: string,
53 options?: CookieOptionsInput,
54 ): void {
55 const cookieOptions = this.getCookieOptions(options);
56 res.cookie(name, value, cookieOptions);
57 }
58
59 clearCookie(res: Response, name: string, options?: CookieOptionsInput): void {
60 const clearOptions = this.getCookieOptions({
61 ...options,
62 maxAge: 0,
63 expires: new Date(0),
64 });
65
66 res.clearCookie(name, clearOptions);
67 res.cookie(name, "", clearOptions);
68 }
69}