Skip to content

Commit

Permalink
Merge pull request #9551 from getsentry/prepare-release/7.80.1
Browse files Browse the repository at this point in the history
meta(changelog): Update changelog for 7.80.1
  • Loading branch information
mydea committed Nov 14, 2023
2 parents e4ff63b + 4d9e57f commit 848335f
Show file tree
Hide file tree
Showing 48 changed files with 666 additions and 250 deletions.
20 changes: 17 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 7.80.1

- fix(astro): Adjust Vite plugin config to upload server source maps (#9541)
- fix(nextjs): Add tracing extensions in all serverside wrappers (#9537)
- fix(nextjs): Fix serverside transaction names on Windows (#9526)
- fix(node): Fix tRPC middleware typing (#9540)
- fix(replay): Add additional safeguards for capturing network bodies (#9506)
- fix(tracing): Update prisma span to be `db.prisma` (#9512)

## 7.80.0

- feat(astro): Add distributed tracing via `<meta>` tags (#9483)
Expand Down Expand Up @@ -32,7 +41,7 @@ This was possible by extensive use of tree shaking and a host of small changes t

By using [tree shaking](https://docs.sentry.io/platforms/javascript/configuration/tree-shaking/) it is possible to shave up to 10 additional KB off the bundle.

#### Other Changes
### Other Changes

- feat(astro): Add Sentry middleware (#9445)
- feat(feedback): Add "outline focus" and "foreground hover" vars (#9462)
Expand All @@ -52,13 +61,18 @@ By using [tree shaking](https://docs.sentry.io/platforms/javascript/configuratio

## 7.77.0

### Security Fixes

- fix(nextjs): Match only numbers as orgid in tunnelRoute (#9416) (CVE-2023-46729)
- fix(nextjs): Strictly validate tunnel target parameters (#9415) (CVE-2023-46729)

### Other Changes

- feat: Move LinkedErrors integration to @sentry/core (#9404)
- feat(remix): Update sentry-cli version to ^2.21.2 (#9401)
- feat(replay): Allow to treeshake & configure compression worker URL (#9409)
- fix(angular-ivy): Adjust package entry points to support Angular 17 with SSR config (#9412)
- fix(feedback): Fixing feedback import (#9403)
- fix(nextjs): Match only numbers as orgid in tunnelRoute (#9416)
- fix(nextjs): Strictly validate tunnel target parameters (#9415)
- fix(utils): Avoid keeping a reference of last used event (#9387)

## 7.76.0
Expand Down
23 changes: 21 additions & 2 deletions packages/astro/src/integration/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-console */
import { sentryVitePlugin } from '@sentry/vite-plugin';
import type { AstroIntegration } from 'astro';
import type { AstroConfig, AstroIntegration } from 'astro';
import * as fs from 'fs';
import * as path from 'path';

Expand All @@ -13,7 +13,8 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => {
return {
name: PKG_NAME,
hooks: {
'astro:config:setup': async ({ updateConfig, injectScript }) => {
// eslint-disable-next-line complexity
'astro:config:setup': async ({ updateConfig, injectScript, config }) => {
// The third param here enables loading of all env vars, regardless of prefix
// see: https://main.vitejs.dev/config/#using-environment-variables-in-config

Expand All @@ -40,6 +41,10 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => {
project: uploadOptions.project ?? env.SENTRY_PROJECT,
authToken: uploadOptions.authToken ?? env.SENTRY_AUTH_TOKEN,
telemetry: uploadOptions.telemetry ?? true,
sourcemaps: {
assets: [getSourcemapsAssetsGlob(config)],
},
debug: options.debug ?? false,
}),
],
},
Expand Down Expand Up @@ -79,3 +84,17 @@ function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined {
.map(ext => path.resolve(path.join(process.cwd(), `sentry.${type}.config.${ext}`)))
.find(filename => fs.existsSync(filename));
}

function getSourcemapsAssetsGlob(config: AstroConfig): string {
// paths are stored as "file://" URLs
const outDirPathname = config.outDir && path.resolve(config.outDir.pathname);
const rootDirName = path.resolve((config.root && config.root.pathname) || process.cwd());

if (outDirPathname) {
const relativePath = path.relative(rootDirName, outDirPathname);
return `${relativePath}/**/*`;
}

// fallback to default output dir
return 'dist/**/*';
}
48 changes: 35 additions & 13 deletions packages/astro/test/integration/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ process.env = {
SENTRY_AUTH_TOKEN: 'my-token',
};

const updateConfig = vi.fn();
const injectScript = vi.fn();
const config = {
root: new URL('file://path/to/project'),
outDir: new URL('file://path/to/project/out'),
};

describe('sentryAstro integration', () => {
afterEach(() => {
vi.clearAllMocks();
Expand All @@ -28,12 +35,10 @@ describe('sentryAstro integration', () => {
const integration = sentryAstro({
sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false },
});
const updateConfig = vi.fn();
const injectScript = vi.fn();

expect(integration.hooks['astro:config:setup']).toBeDefined();
// @ts-expect-error - the hook exists and we only need to pass what we actually use
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });

expect(updateConfig).toHaveBeenCalledTimes(1);
expect(updateConfig).toHaveBeenCalledWith({
Expand All @@ -51,32 +56,52 @@ describe('sentryAstro integration', () => {
org: 'my-org',
project: 'my-project',
telemetry: false,
debug: false,
sourcemaps: {
assets: ['out/**/*'],
},
});
});

it('falls back to default output dir, if out and root dir are not available', async () => {
const integration = sentryAstro({
sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false },
});
// @ts-expect-error - the hook exists and we only need to pass what we actually use
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config: {} });

expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1);
expect(sentryVitePluginSpy).toHaveBeenCalledWith({
authToken: 'my-token',
org: 'my-org',
project: 'my-project',
telemetry: false,
debug: false,
sourcemaps: {
assets: ['dist/**/*'],
},
});
});

it("doesn't enable source maps if `sourceMapsUploadOptions.enabled` is `false`", async () => {
const integration = sentryAstro({
sourceMapsUploadOptions: { enabled: false },
});
const updateConfig = vi.fn();
const injectScript = vi.fn();

expect(integration.hooks['astro:config:setup']).toBeDefined();
// @ts-expect-error - the hook exists and we only need to pass what we actually use
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });

expect(updateConfig).toHaveBeenCalledTimes(0);
expect(sentryVitePluginSpy).toHaveBeenCalledTimes(0);
});

it('injects client and server init scripts', async () => {
const integration = sentryAstro({});
const updateConfig = vi.fn();
const injectScript = vi.fn();

expect(integration.hooks['astro:config:setup']).toBeDefined();
// @ts-expect-error - the hook exists and we only need to pass what we actually use
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });

expect(injectScript).toHaveBeenCalledTimes(2);
expect(injectScript).toHaveBeenCalledWith('page', expect.stringContaining('Sentry.init'));
Expand All @@ -89,12 +114,9 @@ describe('sentryAstro integration', () => {
serverInitPath: 'my-server-init-path.js',
});

const updateConfig = vi.fn();
const injectScript = vi.fn();

expect(integration.hooks['astro:config:setup']).toBeDefined();
// @ts-expect-error - the hook exists and we only need to pass what we actually use
await integration.hooks['astro:config:setup']({ updateConfig, injectScript });
await integration.hooks['astro:config:setup']({ updateConfig, injectScript, config });

expect(injectScript).toHaveBeenCalledTimes(2);
expect(injectScript).toHaveBeenCalledWith('page', expect.stringContaining('my-client-init-path.js'));
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"dependencies": {
"@babel/preset-typescript": "^7.16.7",
"@playwright/test": "^1.31.1",
"axios": "1.3.4",
"axios": "1.6.0",
"babel-loader": "^8.2.2",
"html-webpack-plugin": "^5.5.0",
"pako": "^2.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ sentryTest('captures Breadcrumb for clicks & debounces them for a second', async
await page.waitForTimeout(1000);
await page.click('#button2');

await page.evaluate('Sentry.captureException("test exception")');

const eventData = await promise;
const [eventData] = await Promise.all([promise, page.evaluate('Sentry.captureException("test exception")')]);

expect(eventData.exception?.values).toHaveLength(1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ sentryTest('captures request headers', async ({ getLocalTestPath, page, browserN
/* eslint-enable */
});

const request = await requestPromise;
const [request, replayReq1] = await Promise.all([requestPromise, replayRequestPromise1]);
const eventData = envelopeRequestParser(request);

expect(eventData.exception?.values).toHaveLength(1);
Expand All @@ -71,7 +71,6 @@ sentryTest('captures request headers', async ({ getLocalTestPath, page, browserN
},
});

const replayReq1 = await replayRequestPromise1;
const { performanceSpans: performanceSpans1 } = getCustomRecordingEvents(replayReq1);
expect(performanceSpans1.filter(span => span.op === 'resource.xhr')).toEqual([
{
Expand Down Expand Up @@ -142,7 +141,8 @@ sentryTest(
/* eslint-enable */
});

const request = await requestPromise;
const [request, replayReq1] = await Promise.all([requestPromise, replayRequestPromise1]);

const eventData = envelopeRequestParser(request);

expect(eventData.exception?.values).toHaveLength(1);
Expand All @@ -159,7 +159,6 @@ sentryTest(
},
});

const replayReq1 = await replayRequestPromise1;
const { performanceSpans: performanceSpans1 } = getCustomRecordingEvents(replayReq1);
expect(performanceSpans1.filter(span => span.op === 'resource.xhr')).toEqual([
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,24 @@ sentryTest(
const url = await getLocalTestPath({ testDir: __dirname });

await page.goto(url);
const fullSnapshot = getFullRecordingSnapshots(await reqPromise0);

const text = 'test';

const [req0] = await Promise.all([reqPromise0, page.locator('#input').fill(text)]);
await forceFlushReplay();

const fullSnapshot = getFullRecordingSnapshots(req0);
const stringifiedSnapshot = JSON.stringify(fullSnapshot);
expect(stringifiedSnapshot.includes('Submit form')).toBe(false);
expect(stringifiedSnapshot.includes('Unmasked button')).toBe(true);

const text = 'test';

await page.locator('#input').fill(text);
const [req1] = await Promise.all([reqPromise1, page.locator('#input-unmasked').fill(text)]);
await forceFlushReplay();

const snapshots = getIncrementalRecordingSnapshots(await reqPromise1).filter(isInputMutation);
const snapshots = getIncrementalRecordingSnapshots(req1).filter(isInputMutation);
const lastSnapshot = snapshots[snapshots.length - 1];
expect(lastSnapshot.data.text).toBe('*'.repeat(text.length));

await page.locator('#input-unmasked').fill(text);
await forceFlushReplay();
const snapshots2 = getIncrementalRecordingSnapshots(await reqPromise2).filter(isInputMutation);
const lastSnapshot2 = snapshots2[snapshots2.length - 1];
expect(lastSnapshot2.data.text).toBe(text);
Expand Down Expand Up @@ -120,18 +122,18 @@ sentryTest(

await page.goto(url);

await reqPromise0;

const text = 'test';

await page.locator('#textarea').fill(text);
await Promise.all([reqPromise0, page.locator('#textarea').fill(text)]);
await forceFlushReplay();

const [req1] = await Promise.all([reqPromise1, page.locator('#textarea-unmasked').fill(text)]);
await forceFlushReplay();
const snapshots = getIncrementalRecordingSnapshots(await reqPromise1).filter(isInputMutation);

const snapshots = getIncrementalRecordingSnapshots(req1).filter(isInputMutation);
const lastSnapshot = snapshots[snapshots.length - 1];
expect(lastSnapshot.data.text).toBe('*'.repeat(text.length));

await page.locator('#textarea-unmasked').fill(text);
await forceFlushReplay();
const snapshots2 = getIncrementalRecordingSnapshots(await reqPromise2).filter(isInputMutation);
const lastSnapshot2 = snapshots2[snapshots2.length - 1];
expect(lastSnapshot2.data.text).toBe(text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
},
"devDependencies": {
"@playwright/test": "1.26.1",
"axios": "1.1.2",
"axios": "1.6.0",
"serve": "14.0.1"
},
"volta": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
},
"devDependencies": {
"@playwright/test": "1.26.1",
"axios": "1.1.2",
"axios": "1.6.0",
"serve": "14.0.1"
},
"volta": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
},
"devDependencies": {
"@playwright/test": "1.26.1",
"axios": "1.1.2",
"axios": "1.6.0",
"serve": "14.0.1"
},
"volta": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
},
"devDependencies": {
"@playwright/test": "1.26.1",
"axios": "1.1.2",
"axios": "1.6.0",
"serve": "14.0.1"
},
"volta": {
Expand Down
4 changes: 3 additions & 1 deletion packages/feedback/src/sendFeedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ interface SendFeedbackParams {
name?: string;
email?: string;
url?: string;
source?: string;
}

/**
* Public API to send a Feedback item to Sentry
*/
export function sendFeedback(
{ name, email, message, url = getLocationHref() }: SendFeedbackParams,
{ name, email, message, source = 'api', url = getLocationHref() }: SendFeedbackParams,
{ includeReplay = true }: SendFeedbackOptions = {},
): ReturnType<typeof sendFeedbackRequest> {
const client = getCurrentHub().getClient<BrowserClient>();
Expand All @@ -37,6 +38,7 @@ export function sendFeedback(
message,
url,
replay_id: replayId,
source,
},
});
}
1 change: 1 addition & 0 deletions packages/feedback/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface SendFeedbackData {
email?: string;
replay_id?: string;
name?: string;
source?: string;
};
}

Expand Down
2 changes: 1 addition & 1 deletion packages/feedback/src/util/handleFeedbackSubmit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export async function handleFeedbackSubmit(
dialog.hideError();

try {
const resp = await sendFeedback(feedback, options);
const resp = await sendFeedback({ ...feedback, source: 'widget' }, options);

// Success!
return resp;
Expand Down
3 changes: 2 additions & 1 deletion packages/feedback/src/util/sendFeedbackRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { prepareFeedbackEvent } from './prepareFeedbackEvent';
* Send feedback using transport
*/
export async function sendFeedbackRequest({
feedback: { message, email, name, replay_id, url },
feedback: { message, email, name, source, replay_id, url },
}: SendFeedbackData): Promise<void | TransportMakeRequestResponse> {
const hub = getCurrentHub();
const client = hub.getClient();
Expand All @@ -28,6 +28,7 @@ export async function sendFeedbackRequest({
message,
replay_id,
url,
source,
},
},
type: 'feedback',
Expand Down

0 comments on commit 848335f

Please sign in to comment.