Skip to content

Commit 0bac9a9

Browse files
committed
refactor: simplify mocking & adjust tests for API changes
1 parent 7c4270a commit 0bac9a9

File tree

5 files changed

+68
-52
lines changed

5 files changed

+68
-52
lines changed

src/index.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ export function doubleCsrf({
5656
errorConfig: { statusCode = 403, message = "invalid csrf token", code = "ERR_BAD_CSRF_TOKEN" } = {},
5757
}: DoubleCsrfConfig): DoubleCsrfUtilities {
5858
const ignoredMethodsSet = new Set(ignoredMethods)
59-
const defaultCookieOptions: ResolvedCSRFCookieOptions = Object.assign({
60-
name: "__Host-otter.x-csrf-token",
61-
sameSite: "lax",
62-
path: "/",
63-
secure: true,
64-
httpOnly: true,
65-
signed: false,
66-
}, cookieOptions)
59+
const defaultCookieOptions: ResolvedCSRFCookieOptions = Object.assign(
60+
{
61+
name: "__Host-otter.x-csrf-token",
62+
sameSite: "lax",
63+
path: "/",
64+
secure: true,
65+
httpOnly: true,
66+
signed: false,
67+
},
68+
cookieOptions,
69+
)
6770

6871
const invalidCsrfTokenError = new ClientError(message, {
6972
statusCode: statusCode,
@@ -128,7 +131,7 @@ export function doubleCsrf({
128131
})
129132
const cookieContent = `${csrfToken}${delimiter}${csrfTokenHash}`
130133

131-
setSecretCookie(req, res, cookieContent, Object.assign({}, defaultCookieOptions, cookieOptions))
134+
setSecretCookie(req, res, cookieContent, Object.assign({}, defaultCookieOptions, cookieOptions))
132135

133136
return csrfToken
134137
}

src/types.ts

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,45 @@ export type CSRFRequest = IncomingMessage & {
1111

1212
export type Response = ServerResponse
1313

14-
type CookieSigningOptions = ({
15-
/**
16-
* Whether to sign the anti-CSRF cookie.
17-
* @default false
18-
*/
19-
signed: true
20-
21-
/**
22-
* A function that returns a cookie-signing secret or an array of secrets.
23-
* The first secret should be the newest/preferred secret.
24-
* You do not need to use the request object, but it is available if you need it.
25-
*/
26-
getSigningSecret: CsrfSecretRetriever
27-
} | {
28-
/**
29-
* Whether to sign the anti-CSRF cookie.
30-
* @default false
31-
*/
32-
signed?: false | undefined
33-
34-
/**
35-
* A function that returns a cookie-signing secret or an array of secrets.
36-
* The first secret should be the newest/preferred secret.
37-
* You do not need to use the request object, but it is available if you need it.
38-
*/
39-
getSigningSecret?: undefined
40-
})
41-
42-
type ResolvedCookieSigningOptions = ({
43-
signed: true
44-
getSigningSecret: CsrfSecretRetriever
45-
} | {
46-
signed: false,
47-
getSigningSecret: undefined
48-
})
14+
type CookieSigningOptions =
15+
| {
16+
/**
17+
* Whether to sign the anti-CSRF cookie.
18+
* @default false
19+
*/
20+
signed: true
21+
22+
/**
23+
* A function that returns a cookie-signing secret or an array of secrets.
24+
* The first secret should be the newest/preferred secret.
25+
* You do not need to use the request object, but it is available if you need it.
26+
*/
27+
getSigningSecret: CsrfSecretRetriever
28+
}
29+
| {
30+
/**
31+
* Whether to sign the anti-CSRF cookie.
32+
* @default false
33+
*/
34+
signed?: false | undefined
35+
36+
/**
37+
* A function that returns a cookie-signing secret or an array of secrets.
38+
* The first secret should be the newest/preferred secret.
39+
* You do not need to use the request object, but it is available if you need it.
40+
*/
41+
getSigningSecret?: undefined
42+
}
43+
44+
type ResolvedCookieSigningOptions =
45+
| {
46+
signed: true
47+
getSigningSecret: CsrfSecretRetriever
48+
}
49+
| {
50+
signed: false
51+
getSigningSecret: undefined
52+
}
4953

5054
type ExtraCookieOptions = {
5155
/**

tests/doublecsrf.test.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { DoubleCsrfConfig } from "@/types"
33
/* eslint-disable @typescript-eslint/ban-ts-comment */
44
import { assert, describe, it } from "vitest"
55
import { createTestSuite } from "./testsuite"
6-
import { COOKIE_SECRET, HEADER_KEY } from "./utils/constants";
6+
import { COOKIE_SECRET, HEADER_KEY } from "./utils/constants"
77
import {
88
attachResponseValuesToRequest,
99
getMultipleSecrets,
@@ -29,7 +29,12 @@ createTestSuite("csrf-csrf signed, single secret", {
2929
createTestSuite("csrf-csrf signed with custom options, single secret", {
3030
getSecret: getSingleSecret,
3131
getSessionIdentifier: legacySessionIdentifier,
32-
cookieOptions: { name: "__Host.test-the-thing.token", signed: true, getSigningSecret: () => COOKIE_SECRET, sameSite: "strict" },
32+
cookieOptions: {
33+
name: "__Host.test-the-thing.token",
34+
signed: true,
35+
getSigningSecret: () => COOKIE_SECRET,
36+
sameSite: "strict",
37+
},
3338
size: 128,
3439
delimiter: "~",
3540
hmacAlgorithm: "sha512",
@@ -49,7 +54,12 @@ createTestSuite("csrf-csrf signed, multiple secrets", {
4954
createTestSuite("csrf-csrf signed with custom options, multiple secrets", {
5055
getSecret: getMultipleSecrets,
5156
getSessionIdentifier: legacySessionIdentifier,
52-
cookieOptions: { name: "__Host.test-the-thing.token", signed: true, getSigningSecret: () => COOKIE_SECRET, sameSite: "strict" },
57+
cookieOptions: {
58+
name: "__Host.test-the-thing.token",
59+
signed: true,
60+
getSigningSecret: () => COOKIE_SECRET,
61+
sameSite: "strict",
62+
},
5363
size: 128,
5464
errorConfig: {
5565
statusCode: 401,

tests/testsuite.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { sign } from "@otterhttp/cookie-signature"
33
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
44
import { assert, describe, expect, it } from "vitest"
55

6-
import { COOKIE_SECRET, HEADER_KEY, TEST_TOKEN } from "./utils/constants";
6+
import { COOKIE_SECRET, HEADER_KEY, TEST_TOKEN } from "./utils/constants"
77
import { getCookieFromRequest, getCookieFromResponse, switchSecret } from "./utils/helpers"
88
import { generateMocks, generateMocksWithToken, next } from "./utils/mock"
99
import type { Request, Response } from "./utils/mock-types"
@@ -63,9 +63,7 @@ export const createTestSuite: CreateTestSuite = (name, doubleCsrfOptions) => {
6363
describe("generateToken", () => {
6464
it("should attach both a token and its hash to the response and return a token", () => {
6565
const { mockRequest, decodedCookieValue, setCookie } = generateMocksWithTokenInternal()
66-
const cookieValue = signed
67-
? `s:${sign(decodedCookieValue as string, COOKIE_SECRET)}`
68-
: decodedCookieValue
66+
const cookieValue = signed ? `s:${sign(decodedCookieValue as string, COOKIE_SECRET)}` : decodedCookieValue
6967

7068
const expectedSetCookieValue = serializeCookie(cookieName, cookieValue as string, {
7169
path,

tests/utils/mock.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { IncomingMessage, ServerResponse } from "node:http"
2+
import type { Socket } from "node:net"
23
import { parse } from "@otterhttp/cookie"
34
import { cookieParser, signedCookie } from "@tinyhttp/cookie-parser"
45
import { assert } from "vitest"
@@ -11,7 +12,7 @@ import type { CsrfRequestValidator, CsrfTokenCreator } from "@/types.js"
1112

1213
// Create some request and response mocks
1314
export const generateMocks = () => {
14-
const mockRequest: Request = Object.assign(new IncomingMessage(undefined as any), {
15+
const mockRequest: Request = Object.assign(new IncomingMessage(undefined as unknown as Socket), {
1516
cookies: {},
1617
signedCookies: {},
1718
})

0 commit comments

Comments
 (0)