diff --git a/packages/core/src/api.ts b/packages/core/src/api.ts index c79868c5cb83..c79012ec103a 100644 --- a/packages/core/src/api.ts +++ b/packages/core/src/api.ts @@ -76,7 +76,7 @@ export class API { const dsn = this._dsnObject; const header = [`Sentry sentry_version=${SENTRY_API_VERSION}`]; header.push(`sentry_client=${clientName}/${clientVersion}`); - header.push(`sentry_key=${dsn.user}`); + header.push(`sentry_key=${dsn.publicKey}`); if (dsn.pass) { header.push(`sentry_secret=${dsn.pass}`); } @@ -143,7 +143,7 @@ export class API { const auth = { // We send only the minimum set of required information. See // https://github.com/getsentry/sentry-javascript/issues/2572. - sentry_key: dsn.user, + sentry_key: dsn.publicKey, sentry_version: SENTRY_API_VERSION, }; return urlEncode(auth); diff --git a/packages/types/src/dsn.ts b/packages/types/src/dsn.ts index c697c275e553..b9f757392533 100644 --- a/packages/types/src/dsn.ts +++ b/packages/types/src/dsn.ts @@ -5,8 +5,10 @@ export type DsnProtocol = 'http' | 'https'; export interface DsnComponents { /** Protocol used to connect to Sentry. */ protocol: DsnProtocol; + /** Public authorization key (deprecated, renamed to publicKey). */ + user?: string; /** Public authorization key. */ - user: string; + publicKey?: string; /** Private authorization key (deprecated, optional). */ pass?: string; /** Hostname of the Sentry instance. */ diff --git a/packages/utils/src/dsn.ts b/packages/utils/src/dsn.ts index 5188c6d929ad..011472e35234 100644 --- a/packages/utils/src/dsn.ts +++ b/packages/utils/src/dsn.ts @@ -12,8 +12,10 @@ const ERROR_MESSAGE = 'Invalid Dsn'; export class Dsn implements DsnComponents { /** Protocol used to connect to Sentry. */ public protocol!: DsnProtocol; - /** Public authorization key. */ + /** Public authorization key (deprecated, renamed to publicKey). */ public user!: string; + /** Public authorization key. */ + public publicKey!: string; /** Private authorization key (deprecated, optional). */ public pass!: string; /** Hostname of the Sentry instance. */ @@ -46,9 +48,9 @@ export class Dsn implements DsnComponents { * @param withPassword When set to true, the password will be included. */ public toString(withPassword: boolean = false): string { - const { host, path, pass, port, projectId, protocol, user } = this; + const { host, path, pass, port, projectId, protocol, publicKey } = this; return ( - `${protocol}://${user}${withPassword && pass ? `:${pass}` : ''}` + + `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` + `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}` ); } @@ -61,7 +63,7 @@ export class Dsn implements DsnComponents { throw new SentryError(ERROR_MESSAGE); } - const [protocol, user, pass = '', host, port = '', lastPath] = match.slice(1); + const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1); let path = ''; let projectId = lastPath; @@ -78,13 +80,19 @@ export class Dsn implements DsnComponents { } } - this._fromComponents({ host, pass, path, projectId, port, protocol: protocol as DsnProtocol, user }); + this._fromComponents({ host, pass, path, projectId, port, protocol: protocol as DsnProtocol, publicKey }); } /** Maps Dsn components into this instance. */ private _fromComponents(components: DsnComponents): void { + // TODO this is for backwards compatibility, and can be removed in a future version + if ('user' in components && !('publicKey' in components)) { + components.publicKey = components.user; + } + this.user = components.publicKey || ''; + this.protocol = components.protocol; - this.user = components.user; + this.publicKey = components.publicKey || ''; this.pass = components.pass || ''; this.host = components.host; this.port = components.port || ''; @@ -94,7 +102,7 @@ export class Dsn implements DsnComponents { /** Validates this Dsn and throws on error. */ private _validate(): void { - ['protocol', 'user', 'host', 'projectId'].forEach(component => { + ['protocol', 'publicKey', 'host', 'projectId'].forEach(component => { if (!this[component as keyof DsnComponents]) { throw new SentryError(`${ERROR_MESSAGE}: ${component} missing`); } diff --git a/packages/utils/test/dsn.test.ts b/packages/utils/test/dsn.test.ts index 6db6e4f96868..534346cf0067 100644 --- a/packages/utils/test/dsn.test.ts +++ b/packages/utils/test/dsn.test.ts @@ -10,10 +10,10 @@ describe('Dsn', () => { port: '1234', projectId: '123', protocol: 'https', - user: 'abc', + publicKey: 'abc', }); expect(dsn.protocol).toBe('https'); - expect(dsn.user).toBe('abc'); + expect(dsn.publicKey).toBe('abc'); expect(dsn.pass).toBe('xyz'); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe('1234'); @@ -26,10 +26,10 @@ describe('Dsn', () => { host: 'sentry.io', projectId: '123', protocol: 'https', - user: 'abc', + publicKey: 'abc', }); expect(dsn.protocol).toBe('https'); - expect(dsn.user).toBe('abc'); + expect(dsn.publicKey).toBe('abc'); expect(dsn.pass).toBe(''); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe(''); @@ -44,7 +44,7 @@ describe('Dsn', () => { host: '', projectId: '123', protocol: 'https', - user: 'abc', + publicKey: 'abc', }), ).toThrow(SentryError); expect( @@ -53,7 +53,7 @@ describe('Dsn', () => { host: 'sentry.io', projectId: '', protocol: 'https', - user: 'abc', + publicKey: 'abc', }), ).toThrow(SentryError); expect( @@ -62,7 +62,7 @@ describe('Dsn', () => { host: 'sentry.io', projectId: '123', protocol: '' as 'http', // Trick the type checker here - user: 'abc', + publicKey: 'abc', }), ).toThrow(SentryError); expect( @@ -71,7 +71,7 @@ describe('Dsn', () => { host: 'sentry.io', projectId: '123', protocol: 'https', - user: '', + publicKey: '', }), ).toThrow(SentryError); }); @@ -83,7 +83,7 @@ describe('Dsn', () => { host: 'sentry.io', projectId: '123', protocol: 'httpx' as 'http', // Trick the type checker here - user: 'abc', + publicKey: 'abc', }), ).toThrow(SentryError); expect( @@ -93,7 +93,7 @@ describe('Dsn', () => { port: 'xxx', projectId: '123', protocol: 'https', - user: 'abc', + publicKey: 'abc', }), ).toThrow(SentryError); }); @@ -103,7 +103,7 @@ describe('Dsn', () => { test('parses a valid full Dsn', () => { const dsn = new Dsn('https://abc:xyz@sentry.io:1234/123'); expect(dsn.protocol).toBe('https'); - expect(dsn.user).toBe('abc'); + expect(dsn.publicKey).toBe('abc'); expect(dsn.pass).toBe('xyz'); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe('1234'); @@ -114,7 +114,7 @@ describe('Dsn', () => { test('parses a valid partial Dsn', () => { const dsn = new Dsn('https://abc@sentry.io/123/321'); expect(dsn.protocol).toBe('https'); - expect(dsn.user).toBe('abc'); + expect(dsn.publicKey).toBe('abc'); expect(dsn.pass).toBe(''); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe(''); @@ -125,7 +125,7 @@ describe('Dsn', () => { test('with a long path', () => { const dsn = new Dsn('https://abc@sentry.io/sentry/custom/installation/321'); expect(dsn.protocol).toBe('https'); - expect(dsn.user).toBe('abc'); + expect(dsn.publicKey).toBe('abc'); expect(dsn.pass).toBe(''); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe(''); @@ -136,7 +136,7 @@ describe('Dsn', () => { test('with a query string', () => { const dsn = new Dsn('https://abc@sentry.io/321?sample.rate=0.1&other=value'); expect(dsn.protocol).toBe('https'); - expect(dsn.user).toBe('abc'); + expect(dsn.publicKey).toBe('abc'); expect(dsn.pass).toBe(''); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe('');