because I got bored of customising my CV for every job
at main 82 lines 2.4 kB view raw
1import { Injectable } from "@nestjs/common"; 2import type { Response } from "express"; 3import { JwtConfigService } from "../config/jwt.config"; 4import { CookieService } from "../cookie/cookie.service"; 5 6@Injectable() 7export class AuthCookieService { 8 constructor( 9 private readonly cookieService: CookieService, 10 private readonly jwtConfig: JwtConfigService, 11 ) {} 12 13 private parseExpiryToSeconds(expiryString: string): number { 14 if (!expiryString || typeof expiryString !== "string") { 15 throw new Error( 16 `Invalid expiry string: ${JSON.stringify(expiryString)}. Expected format like "15m", "1h", "7d"`, 17 ); 18 } 19 20 const match = expiryString.match(/^(\d+)([smhd])$/); 21 if (!(match?.[1] && match[2])) { 22 throw new Error( 23 `Failed to parse expiry string: ${expiryString}. Expected format like "15m", "1h", "7d"`, 24 ); 25 } 26 27 const value = Number.parseInt(match[1], 10); 28 const unit = match[2]; 29 30 if (Number.isNaN(value) || value <= 0) { 31 throw new Error( 32 `Invalid expiry value: ${value}. Must be a positive number`, 33 ); 34 } 35 36 switch (unit) { 37 case "s": 38 return value; 39 case "m": 40 return value * 60; 41 case "h": 42 return value * 60 * 60; 43 case "d": 44 return value * 60 * 60 * 24; 45 default: 46 throw new Error(`Invalid expiry unit: ${unit}. Expected s, m, h, or d`); 47 } 48 } 49 50 setAuthCookies( 51 res: Response, 52 accessToken: string, 53 refreshToken: string, 54 ): void { 55 const accessTokenMaxAgeSeconds = this.parseExpiryToSeconds( 56 this.jwtConfig.getAccessTokenExpiry(), 57 ); 58 59 if (accessTokenMaxAgeSeconds <= 0) { 60 throw new Error("Invalid access token expiry"); 61 } 62 63 const accessTokenMaxAgeMs = accessTokenMaxAgeSeconds * 1000; 64 const refreshTokenMaxAgeMs = 60 * 60 * 24 * 7 * 1000; // 7 days 65 66 this.cookieService.setCookie(res, "access_token", accessToken, { 67 maxAge: accessTokenMaxAgeMs, 68 }); 69 70 this.cookieService.setCookie(res, "refresh_token", refreshToken, { 71 maxAge: refreshTokenMaxAgeMs, 72 path: "/api/auth/credentials/refresh", 73 }); 74 } 75 76 clearAuthCookies(res: Response): void { 77 this.cookieService.clearCookie(res, "access_token"); 78 this.cookieService.clearCookie(res, "refresh_token", { 79 path: "/api/auth/credentials/refresh", 80 }); 81 } 82}