@@ -15,7 +15,9 @@ var defaults = {
15
15
log : true ,
16
16
dom : true ,
17
17
navigation : true ,
18
- connectivity : true
18
+ connectivity : true ,
19
+ contentSecurityPolicy : true ,
20
+ errorOnContentSecurityPolicy : false
19
21
} ;
20
22
21
23
function replace ( obj , name , replacement , replacements , type ) {
@@ -89,7 +91,8 @@ function Instrumenter(options, telemeter, rollbar, _window, _document) {
89
91
} ;
90
92
this . eventRemovers = {
91
93
dom : [ ] ,
92
- connectivity : [ ]
94
+ connectivity : [ ] ,
95
+ contentsecuritypolicy : [ ]
93
96
} ;
94
97
95
98
this . _location = this . _window . location ;
@@ -117,6 +120,7 @@ Instrumenter.prototype.configure = function(options) {
117
120
}
118
121
} ;
119
122
123
+ // eslint-disable-next-line complexity
120
124
Instrumenter . prototype . instrument = function ( oldSettings ) {
121
125
if ( this . autoInstrument . network && ! ( oldSettings && oldSettings . network ) ) {
122
126
this . instrumentNetwork ( ) ;
@@ -147,6 +151,12 @@ Instrumenter.prototype.instrument = function(oldSettings) {
147
151
} else if ( ! this . autoInstrument . connectivity && oldSettings && oldSettings . connectivity ) {
148
152
this . deinstrumentConnectivity ( ) ;
149
153
}
154
+
155
+ if ( this . autoInstrument . contentSecurityPolicy && ! ( oldSettings && oldSettings . contentSecurityPolicy ) ) {
156
+ this . instrumentContentSecurityPolicy ( ) ;
157
+ } else if ( ! this . autoInstrument . contentSecurityPolicy && oldSettings && oldSettings . contentSecurityPolicy ) {
158
+ this . deinstrumentContentSecurityPolicy ( ) ;
159
+ }
150
160
} ;
151
161
152
162
Instrumenter . prototype . deinstrumentNetwork = function ( ) {
@@ -694,6 +704,43 @@ Instrumenter.prototype.instrumentConnectivity = function() {
694
704
}
695
705
} ;
696
706
707
+ Instrumenter . prototype . handleCspEvent = function ( cspEvent ) {
708
+ var message = 'Security Policy Violation: ' +
709
+ 'blockedURI: ' + cspEvent . blockedURI + ', ' +
710
+ 'violatedDirective: ' + cspEvent . violatedDirective + ', ' +
711
+ 'effectiveDirective: ' + cspEvent . effectiveDirective + ', ' ;
712
+
713
+ if ( cspEvent . sourceFile ) {
714
+ message += 'location: ' + cspEvent . sourceFile + ', ' +
715
+ 'line: ' + cspEvent . lineNumber + ', ' +
716
+ 'col: ' + cspEvent . columnNumber + ', ' ;
717
+ }
718
+
719
+ message += 'originalPolicy: ' + cspEvent . originalPolicy ;
720
+
721
+ this . telemeter . captureLog ( message , 'error' ) ;
722
+ this . handleCspError ( message ) ;
723
+ }
724
+
725
+ Instrumenter . prototype . handleCspError = function ( message ) {
726
+ if ( this . autoInstrument . errorOnContentSecurityPolicy ) {
727
+ this . rollbar . error ( message ) ;
728
+ }
729
+ }
730
+
731
+ Instrumenter . prototype . deinstrumentContentSecurityPolicy = function ( ) {
732
+ if ( ! ( 'addEventListener' in this . _window ) ) { return ; }
733
+
734
+ this . removeListeners ( 'contentsecuritypolicy' ) ;
735
+ } ;
736
+
737
+ Instrumenter . prototype . instrumentContentSecurityPolicy = function ( ) {
738
+ if ( ! ( 'addEventListener' in this . _window ) ) { return ; }
739
+
740
+ var cspHandler = this . handleCspEvent . bind ( this ) ;
741
+ this . addListener ( 'contentsecuritypolicy' , this . _window , 'securitypolicyviolation' , null , cspHandler , false ) ;
742
+ } ;
743
+
697
744
Instrumenter . prototype . addListener = function ( section , obj , type , altType , handler , capture ) {
698
745
if ( obj . addEventListener ) {
699
746
obj . addEventListener ( type , handler , capture ) ;
0 commit comments