Skip to content

Commit 2af1fc2

Browse files
committed
Add allowPrivateKey config option
1 parent 40762d9 commit 2af1fc2

File tree

3 files changed

+91
-11
lines changed

3 files changed

+91
-11
lines changed

docs/config.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ Those configuration options are documented below:
215215
onFailure
216216
Callback to be invoked upon a failed request.
217217

218+
.. describe:: allowPrivateKey
219+
220+
By default, Raven.js will throw an error if configured with a Sentry DSN that contains a private key. When using Raven.js with a website/application accessed using a web browser over the web, you should only use your public DSN. But if you are using Raven.js in an environment like React Native or Electron, where your application is running "natively" on a device and not accessed at a web address, you may need to use your
221+
private DSN string. To do so, set ``allowPrivateKey: true`` during configuration.
222+
223+
218224
Putting it all together
219225
-----------------------
220226

src/raven.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ Raven.prototype = {
9797
}
9898
if (!dsn) return this;
9999

100-
var uri = this._parseDSN(dsn),
101-
lastSlash = uri.path.lastIndexOf('/'),
102-
path = uri.path.substr(1, lastSlash);
103-
104100
// merge in options
105101
if (options) {
106102
each(options, function(key, value){
@@ -113,6 +109,10 @@ Raven.prototype = {
113109
});
114110
}
115111

112+
var uri = this._parseDSN(dsn),
113+
lastSlash = uri.path.lastIndexOf('/'),
114+
path = uri.path.substr(1, lastSlash);
115+
116116
this._dsn = dsn;
117117

118118
// "Script error." is hard coded into browsers for errors that it can't read.
@@ -127,6 +127,7 @@ Raven.prototype = {
127127
this._globalOptions.includePaths = joinRegExp(this._globalOptions.includePaths);
128128

129129
this._globalKey = uri.user;
130+
this._globalSecret = uri.pass && uri.pass.substr(1);
130131
this._globalProject = uri.path.substr(lastSlash + 1);
131132

132133
this._globalServer = this._getGlobalServer(uri);
@@ -725,8 +726,10 @@ Raven.prototype = {
725726
throw new RavenConfigError('Invalid DSN: ' + str);
726727
}
727728

728-
if (dsn.pass)
729-
throw new RavenConfigError('Do not specify your private key in the DSN!');
729+
if (dsn.pass && !this._globalOptions.allowPrivateKey) {
730+
console.dir(this._globalOptions.allowPrivateKey)
731+
throw new RavenConfigError('Do not specify your private key in the DSN. See: http://bit.ly/raven-private-key');
732+
}
730733

731734
return dsn;
732735
},
@@ -990,14 +993,19 @@ Raven.prototype = {
990993

991994
if (!this.isSetup()) return;
992995

996+
var auth = {
997+
sentry_version: '7',
998+
sentry_client: 'raven-js/' + this.VERSION,
999+
sentry_key: this._globalKey
1000+
};
1001+
if (this._globalSecret) {
1002+
auth.sentry_secret = this._globalSecret;
1003+
}
1004+
9931005
var url = this._globalEndpoint;
9941006
(globalOptions.transport || this._makeRequest).call(this, {
9951007
url: url,
996-
auth: {
997-
sentry_version: '7',
998-
sentry_client: 'raven-js/' + this.VERSION,
999-
sentry_key: this._globalKey
1000-
},
1008+
auth: auth,
10011009
data: data,
10021010
options: globalOptions,
10031011
onSuccess: function success() {

test/raven.test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,51 @@ describe('globals', function() {
10471047
assert.isFunction(opts.onError);
10481048
});
10491049

1050+
it('should pass sentry_secret as part of auth params if specified', function () {
1051+
this.sinon.stub(Raven, 'isSetup').returns(true);
1052+
this.sinon.stub(Raven, '_makeRequest');
1053+
this.sinon.stub(Raven, '_getHttpData').returns({
1054+
url: 'http://localhost/?a=b',
1055+
headers: {'User-Agent': 'lolbrowser'}
1056+
});
1057+
1058+
Raven._globalEndpoint = 'http://localhost/store/';
1059+
Raven._globalOptions = {
1060+
projectId: 2,
1061+
logger: 'javascript',
1062+
maxMessageLength: 100,
1063+
release: 'abc123'
1064+
};;
1065+
Raven._globalSecret = 'def'; // <-- secret
1066+
1067+
Raven._send({message: 'bar'});
1068+
var args = Raven._makeRequest.lastCall.args;
1069+
assert.equal(args.length, 1);
1070+
var opts = args[0];
1071+
assert.equal(opts.url, 'http://localhost/store/');
1072+
assert.deepEqual(opts.data, {
1073+
project: '2',
1074+
release: 'abc123',
1075+
logger: 'javascript',
1076+
platform: 'javascript',
1077+
request: {
1078+
url: 'http://localhost/?a=b',
1079+
headers: {
1080+
'User-Agent': 'lolbrowser'
1081+
}
1082+
},
1083+
event_id: 'abc123',
1084+
message: 'bar',
1085+
extra: {'session:duration': 100},
1086+
});
1087+
assert.deepEqual(opts.auth, {
1088+
sentry_client: 'raven-js/2.1.0',
1089+
sentry_key: 'abc',
1090+
sentry_secret: 'def',
1091+
sentry_version: '7'
1092+
});
1093+
});
1094+
10501095
it('should call globalOptions.transport if specified', function() {
10511096
this.sinon.stub(Raven, 'isSetup').returns(true);
10521097
this.sinon.stub(Raven, '_getHttpData').returns({
@@ -1528,12 +1573,33 @@ describe('Raven (public API)', function() {
15281573
assert.equal(Raven, Raven.config(SENTRY_DSN, {foo: 'bar'}), 'it should return Raven');
15291574

15301575
assert.equal(Raven._globalKey, 'abc');
1576+
assert.equal(Raven._globalSecret, '');
15311577
assert.equal(Raven._globalEndpoint, 'http://example.com:80/api/2/store/');
15321578
assert.equal(Raven._globalOptions.foo, 'bar');
15331579
assert.equal(Raven._globalProject, '2');
15341580
assert.isTrue(Raven.isSetup());
15351581
});
15361582

1583+
it('throw an Error if the DSN contains a private/secret key', function () {
1584+
assert.throws(function () {
1585+
Raven.config('http://abc:[email protected]:80/2');
1586+
}, Error);
1587+
});
1588+
1589+
it('will NOT throw an Error if the DSN contains a private/secret key AND allowPrivateKey is true', function () {
1590+
assert.equal(
1591+
Raven,
1592+
Raven.config('http://abc:[email protected]:80/2', {allowPrivateKey: true}),
1593+
'it should return Raven'
1594+
);
1595+
1596+
assert.equal(Raven._globalKey, 'abc');
1597+
assert.equal(Raven._globalSecret, 'def');
1598+
assert.equal(Raven._globalEndpoint, 'http://example.com:80/api/2/store/');
1599+
assert.equal(Raven._globalProject, '2');
1600+
assert.isTrue(Raven.isSetup());
1601+
});
1602+
15371603
it('should work with a protocol relative DSN', function() {
15381604
Raven.config('//[email protected]/2');
15391605

0 commit comments

Comments
 (0)