diff --git a/README.md b/README.md index 56fd309..8919743 100644 --- a/README.md +++ b/README.md @@ -224,7 +224,7 @@ string; Default: "__Host-psifi.x-csrf-token"

-

Optional: The name of the httpOnly cookie that will be used to track CSRF protection. If you change this it is recommend that you continue to use the __Host- or __Secure- security prefix.

+

Optional: The name of the cookie that will be used to track CSRF protection. If you change this it is recommend that you continue to use the __Host- or __Secure- security prefix.

Change for development

@@ -353,6 +353,7 @@ Used to customise the error response statusCode, the contained erro request: Request, response: Response, { + cookieOptions?: CookieOptions, // overrides cookieOptions previously configured just for this call overwrite?: boolean, // Set to true to force a new token to be generated validateOnReuse?: boolean, // Set to false to generate a new token if token re-use is invalid } // optional diff --git a/src/index.ts b/src/index.ts index 289e60a..8450fd3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,7 @@ export function doubleCsrf({ sameSite = "lax", path = "/", secure = true, + httpOnly = true, ...remainingCookieOptions } = {}, size = 64, @@ -35,10 +36,11 @@ export function doubleCsrf({ } = {}, }: DoubleCsrfConfigOptions): DoubleCsrfUtilities { const ignoredMethodsSet = new Set(ignoredMethods); - const cookieOptions = { + const defaultCookieOptions = { sameSite, path, secure, + httpOnly, ...remainingCookieOptions, }; @@ -48,7 +50,10 @@ export function doubleCsrf({ const generateTokenAndHash = ( req: Request, - { overwrite, validateOnReuse }: GenerateCsrfTokenConfig, + { + overwrite, + validateOnReuse, + }: Omit, ) => { const getSecretResult = getSecret(req); const possibleSecrets = Array.isArray(getSecretResult) @@ -91,14 +96,21 @@ export function doubleCsrf({ const generateToken: CsrfTokenCreator = ( req: Request, res: Response, - { overwrite = false, validateOnReuse = true } = {}, + { + cookieOptions = defaultCookieOptions, + overwrite = false, + validateOnReuse = true, + } = {}, ) => { const { csrfToken, csrfTokenHash } = generateTokenAndHash(req, { overwrite, validateOnReuse, }); const cookieContent = `${csrfToken}|${csrfTokenHash}`; - res.cookie(cookieName, cookieContent, { ...cookieOptions, httpOnly: true }); + res.cookie(cookieName, cookieContent, { + ...defaultCookieOptions, + ...cookieOptions, + }); return csrfToken; }; diff --git a/src/types.ts b/src/types.ts index 68a023a..f232c91 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,7 +3,7 @@ import type { HttpError } from "http-errors"; export type SameSiteType = boolean | "lax" | "strict" | "none"; export type TokenRetriever = (req: Request) => string | null | undefined; -export type DoubleCsrfCookieOptions = Omit; +export type CsrfTokenCookieOverrides = Omit; declare module "http" { interface IncomingHttpHeaders { "x-csrf-token"?: string | undefined; @@ -48,7 +48,7 @@ export type CsrfCookieSetter = ( res: Response, name: string, value: string, - options: DoubleCsrfCookieOptions, + options: CookieOptions, ) => void; export type CsrfTokenCreator = ( req: Request, @@ -64,6 +64,7 @@ export type CsrfErrorConfigOptions = Partial; export type GenerateCsrfTokenConfig = { overwrite: boolean; validateOnReuse: boolean; + cookieOptions: CsrfTokenCookieOverrides; }; export type GenerateCsrfTokenOptions = Partial; export interface DoubleCsrfConfig { @@ -103,7 +104,7 @@ export interface DoubleCsrfConfig { * The options for HTTPOnly cookie that will be set on the response. * @default { sameSite: "lax", path: "/", secure: true } */ - cookieOptions: DoubleCsrfCookieOptions; + cookieOptions: CookieOptions; /** * The methods that will be ignored by the middleware.