diff --git a/e2e/scripts/mockTests.ts b/e2e/scripts/mockTests.ts index cc3f69e6..0fb4e654 100644 --- a/e2e/scripts/mockTests.ts +++ b/e2e/scripts/mockTests.ts @@ -1,5 +1,6 @@ import { execSync } from 'child_process' import { readTestInfo } from '../shared/testInfo' +import pkg from '../../package.json' async function main() { let hasError = false @@ -16,13 +17,19 @@ async function main() { const resultPath = `${info.routePrefix}/${info.getResultPath}` const host = info.functionAppUrl + const agentUrl = new URL(host) + agentUrl.pathname = agentPath + + const resultUrl = new URL(host) + resultUrl.pathname = resultPath + console.info('Running mock server for', host) console.info('Agent download path:', agentPath) console.info('Get result path:', resultPath) try { execSync( - `npm exec -y "git+https://github.com/fingerprintjs/dx-team-mock-for-proxy-integrations-e2e-tests.git" -- --api-url="https://${apiUrl}" --host="${host}" --cdn-proxy-path="${agentPath}" --ingress-proxy-path="${resultPath}"`, + `npm exec -y "git+https://github.com/fingerprintjs/dx-team-mock-for-proxy-integrations-e2e-tests.git" -- --api-url="https://${apiUrl}" --cdn-proxy-url="${agentUrl.toString()}" --ingress-proxy-url="${resultUrl.toString()}" --traffic-name="fingerprint-pro-azure" --integration-version=${pkg.version}`, { stdio: 'inherit', } diff --git a/proxy/handlers/agent.test.ts b/proxy/handlers/agent.test.ts index 7da233d2..d105050a 100644 --- a/proxy/handlers/agent.test.ts +++ b/proxy/handlers/agent.test.ts @@ -64,6 +64,23 @@ describe('Agent Endpoint', () => { }) }) + test('Call with custom query parameters', async () => { + const req = mockRequestGet('https://fp.domain.com', 'fpjs/agent', { + apiKey: 'ujKG34hUYKLJKJ1F', + version: '5', + customQuery: '123', + }) + const ctx = mockContext(req) + + await proxy(ctx, req) + + const [url] = requestSpy.mock.calls[0] + + expect(url.toString()).toEqual( + `https://${origin}/v5/ujKG34hUYKLJKJ1F?apiKey=ujKG34hUYKLJKJ1F&version=5&customQuery=123&ii=fingerprint-pro-azure%2F__azure_function_version__%2Fprocdn` + ) + }) + test('Call with version', async () => { const req = mockRequestGet('https://fp.domain.com', 'fpjs/agent', { apiKey: 'ujKG34hUYKLJKJ1F', @@ -76,7 +93,7 @@ describe('Agent Endpoint', () => { const [url] = requestSpy.mock.calls[0] expect(url.toString()).toEqual( - `https://${origin}/v5/ujKG34hUYKLJKJ1F?ii=fingerprint-pro-azure%2F__azure_function_version__%2Fprocdn` + `https://${origin}/v5/ujKG34hUYKLJKJ1F?apiKey=ujKG34hUYKLJKJ1F&version=5&ii=fingerprint-pro-azure%2F__azure_function_version__%2Fprocdn` ) }) @@ -93,7 +110,7 @@ describe('Agent Endpoint', () => { const [url] = requestSpy.mock.calls[0] expect(url.toString()).toEqual( - `https://${origin}/v5/ujKG34hUYKLJKJ1F/loader_v3.6.5.js?ii=fingerprint-pro-azure%2F__azure_function_version__%2Fprocdn` + `https://${origin}/v5/ujKG34hUYKLJKJ1F/loader_v3.6.5.js?apiKey=ujKG34hUYKLJKJ1F&version=5&loaderVersion=3.6.5&ii=fingerprint-pro-azure%2F__azure_function_version__%2Fprocdn` ) }) @@ -214,7 +231,7 @@ describe('Agent Endpoint', () => { }) }) - test('Req body and headers are the same, expect cookies, which should include only _iidt cookie', async () => { + test('Req body and headers are the same, expect cookies, which should be omitted', async () => { const req = mockRequestGet('https://fp.domain.com', 'fpjs/agent', { apiKey: 'ujKG34hUYKLJKJ1F', version: '5', @@ -242,7 +259,7 @@ describe('Agent Endpoint', () => { expect(options.headers).toEqual({ ...req.headers, - cookie: '_iidt=GlMQaHMfzYvomxCuA7Uymy7ArmjH04jPkT+enN7j/Xk8tJG+UYcQV+Qw60Ry4huw9bmDoO/smyjQp5vLCuSf8t4Jow==', + cookie: undefined, }) }) diff --git a/proxy/handlers/agent.ts b/proxy/handlers/agent.ts index 63cfd5aa..2f6e290c 100644 --- a/proxy/handlers/agent.ts +++ b/proxy/handlers/agent.ts @@ -2,7 +2,7 @@ import { HttpRequest, Logger } from '@azure/functions' import { config } from '../utils/config' import * as https from 'https' import { filterRequestHeaders, updateResponseHeadersForAgentDownload } from '../utils/headers' -import { HttpResponseSimple } from '@azure/functions/types/http' +import { HttpRequestQuery, HttpResponseSimple } from '@azure/functions/types/http' import { addTrafficMonitoringSearchParamsForProCDN } from '../utils/traffic' import { IntegrationError } from '../errors/IntegrationError' @@ -14,6 +14,12 @@ export interface DownloadAgentParams { const DEFAULT_VERSION = '3' +function copySearchParams(query: HttpRequestQuery, newURL: URL): void { + const params = new URLSearchParams(query) + + newURL.search = params.toString() +} + export async function downloadAgent({ httpRequest, logger, path }: DownloadAgentParams): Promise { const apiKey = httpRequest.query.apiKey const version = httpRequest.query.version ?? DEFAULT_VERSION @@ -30,6 +36,8 @@ export async function downloadAgent({ httpRequest, logger, path }: DownloadAgent } const url = new URL(`https://${config.fpcdn}`) + copySearchParams(httpRequest.query, url) + url.pathname = getEndpoint(apiKey, version, loaderVersion) addTrafficMonitoringSearchParamsForProCDN(url) @@ -37,6 +45,8 @@ export async function downloadAgent({ httpRequest, logger, path }: DownloadAgent const headers = filterRequestHeaders(httpRequest.headers) + delete headers['cookie'] + return new Promise((resolve) => { const data: any[] = [] diff --git a/proxy/handlers/ingress.test.ts b/proxy/handlers/ingress.test.ts index c28a1396..d56c4834 100644 --- a/proxy/handlers/ingress.test.ts +++ b/proxy/handlers/ingress.test.ts @@ -114,6 +114,23 @@ describe('Result Endpoint', function () { expect(options.headers.cookie).toBe('_iidt=7A03Gwg') }) + test('Cookies are undefined if _iidt is not est', async () => { + const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId') + + req.headers.cookie = '_vid_t=gEFRuIQlzYmv692/UL4GLA==' + + mockSuccessfulResponse({ + checkRequestUrl: (url) => { + expect(url.toString()).toBe(`${defaultOrigin}/${search}`) + }, + }) + + await proxy(mockContext(req), req) + + const [, options] = requestSpy.mock.calls[0] + expect(options.headers.cookie).toBeFalsy() + }) + test('Request body and headers are not modified, expect strict-transport-security and transfer-encoding', async () => { const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId') const resHeaders = { diff --git a/proxy/handlers/ingress.ts b/proxy/handlers/ingress.ts index c1200c81..430c7699 100644 --- a/proxy/handlers/ingress.ts +++ b/proxy/handlers/ingress.ts @@ -42,6 +42,11 @@ export function handleIngress({ const headers = prepareHeadersForIngressAPI(httpRequest, preSharedSecret, logger) + // No need to send cookies for browser cache request + if (suffix) { + delete headers['cookie'] + } + return new Promise((resolve) => { const data: any[] = [] diff --git a/proxy/utils/headers.ts b/proxy/utils/headers.ts index c51e0baa..05b3e5a6 100644 --- a/proxy/utils/headers.ts +++ b/proxy/utils/headers.ts @@ -21,12 +21,15 @@ export function filterRequestHeaders(headers: HttpRequestHeaders) { let headerValue = value if (headerName === 'cookie') { - headerValue = headerValue.split(/; */).join('; ') - headerValue = filterCookie(headerValue, (key) => key === FPJS_COOKIE_NAME) - } - result[headerName] = headerValue + // Only set cookie header if there are relevant cookies + if (headerValue) { + result[headerName] = headerValue + } + } else { + result[headerName] = headerValue + } } return result