Skip to content

Commit 003e611

Browse files
committed
Add test
1 parent e214d08 commit 003e611

File tree

9 files changed

+110
-115
lines changed

9 files changed

+110
-115
lines changed

dev-packages/node-integration-tests/suites/reporting-api/index.html

Lines changed: 0 additions & 9 deletions
This file was deleted.

dev-packages/node-integration-tests/suites/reporting-api/localhost-key.pem

Lines changed: 0 additions & 27 deletions
This file was deleted.

dev-packages/node-integration-tests/suites/reporting-api/localhost.pem

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
import * as https from 'https';
2-
import { loggingTransport } from '@sentry-internal/node-integration-tests';
1+
import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests';
32
import { defaultStackParser as browserStackParser } from '@sentry/browser';
43
import { handleReportingApi } from '@sentry/core';
54
import * as Sentry from '@sentry/node';
65

7-
const __dirname = new URL('.', import.meta.url).pathname;
8-
96
Sentry.init({
10-
debug: true,
117
dsn: 'https://[email protected]/1337',
128
release: '1.0',
139
transport: loggingTransport,
1410
});
1511

16-
import { readFileSync } from 'fs';
17-
import { join } from 'path';
1812
import express from 'express';
1913

2014
const app = express();
@@ -26,33 +20,38 @@ app.post('/reporting-api', async (req, res) => {
2620
res.sendStatus(200);
2721
});
2822

29-
const port = 9000;
30-
31-
app.get('/', (req, res) => {
32-
const file = readFileSync(join(__dirname, 'index.html'), { encoding: 'utf-8' });
33-
34-
res.setHeader('Content-Type', 'text/html');
35-
res.setHeader(
36-
'Reporting-Endpoints',
37-
`csp-endpoint="https://localhost:${port}/reporting-api", default="https://localhost:${port}/reporting-api"`,
38-
);
39-
res.setHeader('Content-Security-Policy', "default-src 'self'; report-to csp-endpoint");
40-
res.setHeader(
41-
'Origin-Trial',
42-
'ApD+E2izWNtaaRBeZ5BXu46aV0l1MSUzJTPERkU3yf+53pAOHj3rARpjb08itVJklPYx7iNEv5//s2dtXUFIvgMAAABzeyJvcmlnaW4iOiJodHRwczovL2xvY2FsaG9zdDo5MDAwIiwiZmVhdHVyZSI6IkRvY3VtZW50UG9saWN5SW5jbHVkZUpTQ2FsbFN0YWNrc0luQ3Jhc2hSZXBvcnRzIiwiZXhwaXJ5IjoxNzQyMzQyMzk5fQ==',
43-
);
44-
res.setHeader('Document-Policy', 'include-js-call-stacks-in-crash-reports');
45-
res.send(file);
46-
});
47-
48-
const options = {
49-
key: readFileSync(join(__dirname, 'localhost-key.pem')),
50-
cert: readFileSync(join(__dirname, 'localhost.pem')),
51-
};
52-
53-
const server = https.createServer(options, app);
54-
55-
server.listen(port, () => {
56-
// eslint-disable-next-line no-console
57-
console.log(`{"port":${port}}`);
58-
});
23+
startExpressServerAndSendPortToRunner(app);
24+
25+
// Below is to support testing with a browser. We don't test this yet because we don't want to add the overhead of
26+
// installing playwright to the node-integration-tests. We should consider this in the future.
27+
28+
// const port = 9000;
29+
30+
// app.get('/', (req, res) => {
31+
// const file = readFileSync(join(__dirname, 'index.html'), { encoding: 'utf-8' });
32+
33+
// res.setHeader('Content-Type', 'text/html');
34+
// res.setHeader(
35+
// 'Reporting-Endpoints',
36+
// `csp-endpoint="https://localhost:${port}/reporting-api", default="https://localhost:${port}/reporting-api"`,
37+
// );
38+
// res.setHeader('Content-Security-Policy', "default-src 'self'; report-to csp-endpoint");
39+
// res.setHeader('Document-Policy', 'include-js-call-stacks-in-crash-reports');
40+
// res.setHeader(
41+
// 'Origin-Trial',
42+
// 'ApD+E2izWNtaaRBeZ5BXu46aV0l1MSUzJTPERkU3yf+53pAOHj3rARpjb08itVJklPYx7iNEv5//s2dtXUFIvgMAAABzeyJvcmlnaW4iOiJodHRwczovL2xvY2FsaG9zdDo5MDAwIiwiZmVhdHVyZSI6IkRvY3VtZW50UG9saWN5SW5jbHVkZUpTQ2FsbFN0YWNrc0luQ3Jhc2hSZXBvcnRzIiwiZXhwaXJ5IjoxNzQyMzQyMzk5fQ==',
43+
// );
44+
// res.send(file);
45+
// });
46+
47+
// const options = {
48+
// key: readFileSync(join(__dirname, 'localhost-key.pem')),
49+
// cert: readFileSync(join(__dirname, 'localhost.pem')),
50+
// };
51+
52+
// const server = https.createServer(options, app);
53+
54+
// server.listen(port, () => {
55+
// // eslint-disable-next-line no-console
56+
// console.log(`{"port":${port}}`);
57+
// });
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { cleanupChildProcesses, createRunner } from '../../utils/runner';
2+
3+
describe('Reporting API', () => {
4+
afterAll(() => {
5+
cleanupChildProcesses();
6+
});
7+
8+
test('should forward Reporting API requests as raw CSP envelopes', done => {
9+
const runner = createRunner(__dirname, 'server.mjs')
10+
.expect({
11+
raw_security: {
12+
'csp-report': {
13+
'document-uri': 'https://localhost:9000/',
14+
referrer: '',
15+
'blocked-uri': 'https://example.com/script.js',
16+
'effective-directive': 'script-src-elem',
17+
'original-policy': "default-src 'self'; report-to csp-endpoint",
18+
disposition: 'enforce',
19+
'status-code': 200,
20+
status: '200',
21+
sample: '',
22+
},
23+
},
24+
})
25+
.start(done);
26+
27+
runner.makeRequest(
28+
'post',
29+
'/reporting-api',
30+
{ 'Content-Type': 'application/reports+json' },
31+
JSON.stringify([
32+
{
33+
age: 0,
34+
body: {
35+
blockedURL: 'https://example.com/script.js',
36+
disposition: 'enforce',
37+
documentURL: 'https://localhost:9000/',
38+
effectiveDirective: 'script-src-elem',
39+
originalPolicy: "default-src 'self'; report-to csp-endpoint",
40+
referrer: '',
41+
sample: '',
42+
statusCode: 200,
43+
},
44+
type: 'csp-violation',
45+
url: 'https://localhost:9000/',
46+
user_agent:
47+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
48+
},
49+
]),
50+
);
51+
});
52+
});

dev-packages/node-integration-tests/utils/runner.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { join } from 'path';
44
import { SDK_VERSION } from '@sentry/node';
55
import type {
66
ClientReport,
7+
DeprecatedCSPReport,
78
Envelope,
89
EnvelopeItemType,
910
Event,
@@ -165,6 +166,9 @@ type Expected =
165166
}
166167
| {
167168
client_report: Partial<ClientReport> | ((event: ClientReport) => void);
169+
}
170+
| {
171+
raw_security: Partial<DeprecatedCSPReport> | ((event: DeprecatedCSPReport) => void);
168172
};
169173

170174
type ExpectedEnvelopeHeader =
@@ -265,6 +269,7 @@ export function createRunner(...paths: string[]) {
265269
}
266270
}
267271

272+
// eslint-disable-next-line complexity
268273
function newEnvelope(envelope: Envelope): void {
269274
for (const item of envelope[1]) {
270275
const envelopeItemType = item[0].type;
@@ -360,6 +365,17 @@ export function createRunner(...paths: string[]) {
360365

361366
expectCallbackCalled();
362367
}
368+
369+
if ('raw_security' in expected) {
370+
const rawSecurity = item[1] as DeprecatedCSPReport;
371+
if (typeof expected.raw_security === 'function') {
372+
expected.raw_security(rawSecurity);
373+
} else {
374+
expect(rawSecurity).toMatchObject(expected.raw_security);
375+
}
376+
377+
expectCallbackCalled();
378+
}
363379
} catch (e) {
364380
complete(e as Error);
365381
}

packages/core/src/envelope.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,10 @@ export function createSpanEnvelope(spans: [SentrySpan, ...SentrySpan[]], client?
146146
function convertToDeprecatedPayload(report: CSPReportPayload): DeprecatedCSPReport {
147147
return {
148148
'csp-report': {
149-
'document-uri': report.documentURI,
149+
'document-uri': report.documentURI || report.documentURL,
150150
referrer: report.referrer,
151-
'blocked-uri': report.blockedURI,
151+
'blocked-uri': report.blockedURI || report.blockedURL,
152152
'effective-directive': report.effectiveDirective,
153-
'violated-directive': report.effectiveDirective,
154153
'original-policy': report.originalPolicy,
155154
disposition: report.disposition,
156155
'status-code': report.statusCode,

packages/core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,4 @@ export { getCurrentHubShim, getCurrentHub } from './getCurrentHubShim';
114114

115115
export { SDK_VERSION } from '@sentry/utils';
116116

117-
export { handleReportingApi, handlerReportingApiRequest } from './reporting';
117+
export { handleReportingApi } from './reporting';

packages/core/src/reporting.ts

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,6 @@ import type { Event, Report, StackParser } from '@sentry/types';
22
import { getClient } from './currentScopes';
33
import { createRawSecurityEnvelope } from './envelope';
44

5-
/** Handles Requests from the Reporting API */
6-
export async function handlerReportingApiRequest(
7-
request: Request,
8-
browserStackParser?: StackParser,
9-
client = getClient(),
10-
): Promise<Response> {
11-
if (request.method !== 'POST') {
12-
return new Response('Expected POST', { status: 405 });
13-
}
14-
15-
if (request.headers.get('Content-Type') !== 'application/reports+json') {
16-
return new Response('Expected "application/reports+json" Content-Type', { status: 415 });
17-
}
18-
const reports = await request.json();
19-
await handleReportingApi(reports, browserStackParser, client);
20-
return new Response(undefined, { status: 200 });
21-
}
22-
235
/** Handles Reports from the Reporting API */
246
export async function handleReportingApi(
257
reports: Report[],
@@ -56,18 +38,17 @@ export async function handleReportingApi(
5638
event.message = 'Crashed: Unresponsive';
5739
}
5840

59-
if (report.body.stack) {
41+
if (report.body.stack && browserStackParser) {
6042
event.exception = {
6143
values: [
6244
{
6345
type: 'Crashed',
6446
value: event.message,
65-
stacktrace: {
66-
...(browserStackParser && report.body.stack && { frames: browserStackParser(report.body.stack) }),
67-
},
47+
stacktrace: { frames: browserStackParser(report.body.stack) },
6848
},
6949
],
7050
};
51+
7152
delete event.message;
7253
}
7354

0 commit comments

Comments
 (0)