| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | |
| 5 /** | 4 /** |
| 6 * @constructor | |
| 7 * @extends {WebInspector.PanelWithSidebar} | |
| 8 * @implements {WebInspector.TargetManager.Observer} | 5 * @implements {WebInspector.TargetManager.Observer} |
| 6 * @unrestricted |
| 9 */ | 7 */ |
| 10 WebInspector.SecurityPanel = function() | 8 WebInspector.SecurityPanel = class extends WebInspector.PanelWithSidebar { |
| 11 { | 9 constructor() { |
| 12 WebInspector.PanelWithSidebar.call(this, "security"); | 10 super('security'); |
| 13 | 11 |
| 14 this._mainView = new WebInspector.SecurityMainView(this); | 12 this._mainView = new WebInspector.SecurityMainView(this); |
| 15 | 13 |
| 16 this._sidebarMainViewElement = new WebInspector.SecurityPanelSidebarTreeElem
ent(WebInspector.UIString("Overview"), this._setVisibleView.bind(this, this._mai
nView), "security-main-view-sidebar-tree-item", "lock-icon"); | 14 this._sidebarMainViewElement = new WebInspector.SecurityPanelSidebarTreeElem
ent( |
| 17 this._sidebarTree = new WebInspector.SecurityPanelSidebarTree(this._sidebarM
ainViewElement, this.showOrigin.bind(this)); | 15 WebInspector.UIString('Overview'), this._setVisibleView.bind(this, this.
_mainView), |
| 16 'security-main-view-sidebar-tree-item', 'lock-icon'); |
| 17 this._sidebarTree = |
| 18 new WebInspector.SecurityPanelSidebarTree(this._sidebarMainViewElement,
this.showOrigin.bind(this)); |
| 18 this.panelSidebarElement().appendChild(this._sidebarTree.element); | 19 this.panelSidebarElement().appendChild(this._sidebarTree.element); |
| 19 | 20 |
| 20 /** @type {!Map<!NetworkAgent.LoaderId, !WebInspector.NetworkRequest>} */ | 21 /** @type {!Map<!NetworkAgent.LoaderId, !WebInspector.NetworkRequest>} */ |
| 21 this._lastResponseReceivedForLoaderId = new Map(); | 22 this._lastResponseReceivedForLoaderId = new Map(); |
| 22 | 23 |
| 23 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa
nel.OriginState>} */ | 24 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa
nel.OriginState>} */ |
| 24 this._origins = new Map(); | 25 this._origins = new Map(); |
| 25 | 26 |
| 26 /** @type {!Map<!WebInspector.NetworkLogView.MixedContentFilterValues, numbe
r>} */ | 27 /** @type {!Map<!WebInspector.NetworkLogView.MixedContentFilterValues, numbe
r>} */ |
| 27 this._filterRequestCounts = new Map(); | 28 this._filterRequestCounts = new Map(); |
| 28 | 29 |
| 29 /** @type {!Map<!WebInspector.Target, !Array<!WebInspector.EventTarget.Event
Descriptor>>}*/ | 30 /** @type {!Map<!WebInspector.Target, !Array<!WebInspector.EventTarget.Event
Descriptor>>}*/ |
| 30 this._eventListeners = new Map(); | 31 this._eventListeners = new Map(); |
| 31 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili
ty.Network); | 32 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili
ty.Network); |
| 33 } |
| 34 |
| 35 /** |
| 36 * @return {!WebInspector.SecurityPanel} |
| 37 */ |
| 38 static _instance() { |
| 39 return /** @type {!WebInspector.SecurityPanel} */ (self.runtime.sharedInstan
ce(WebInspector.SecurityPanel)); |
| 40 } |
| 41 |
| 42 /** |
| 43 * @param {string} text |
| 44 * @param {!WebInspector.SecurityPanel} panel |
| 45 * @return {!Element} |
| 46 */ |
| 47 static createCertificateViewerButton(text, panel) { |
| 48 /** |
| 49 * @param {!Event} e |
| 50 */ |
| 51 function showCertificateViewer(e) { |
| 52 e.consume(); |
| 53 panel.showCertificateViewer(); |
| 54 } |
| 55 |
| 56 return createTextButton(text, showCertificateViewer, 'security-certificate-b
utton'); |
| 57 } |
| 58 |
| 59 /** |
| 60 * @param {string} text |
| 61 * @param {string} origin |
| 62 * @return {!Element} |
| 63 */ |
| 64 static createCertificateViewerButton2(text, origin) { |
| 65 /** |
| 66 * @param {!Event} e |
| 67 */ |
| 68 function showCertificateViewer(e) { |
| 69 function certificateCallback(names) { |
| 70 InspectorFrontendHost.showCertificateViewer(names); |
| 71 } |
| 72 |
| 73 e.consume(); |
| 74 WebInspector.multitargetNetworkManager.getCertificate(origin, certificateC
allback); |
| 75 } |
| 76 |
| 77 return createTextButton(text, showCertificateViewer, 'security-certificate-b
utton'); |
| 78 } |
| 79 |
| 80 /** |
| 81 * @param {!SecurityAgent.SecurityState} securityState |
| 82 */ |
| 83 setRanInsecureContentStyle(securityState) { |
| 84 this._ranInsecureContentStyle = securityState; |
| 85 } |
| 86 |
| 87 /** |
| 88 * @param {!SecurityAgent.SecurityState} securityState |
| 89 */ |
| 90 setDisplayedInsecureContentStyle(securityState) { |
| 91 this._displayedInsecureContentStyle = securityState; |
| 92 } |
| 93 |
| 94 /** |
| 95 * @param {!SecurityAgent.SecurityState} newSecurityState |
| 96 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations |
| 97 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus |
| 98 * @param {boolean} schemeIsCryptographic |
| 99 */ |
| 100 _updateSecurityState(newSecurityState, explanations, insecureContentStatus, sc
hemeIsCryptographic) { |
| 101 this._sidebarMainViewElement.setSecurityState(newSecurityState); |
| 102 this._mainView.updateSecurityState(newSecurityState, explanations, insecureC
ontentStatus, schemeIsCryptographic); |
| 103 } |
| 104 |
| 105 /** |
| 106 * @param {!WebInspector.Event} event |
| 107 */ |
| 108 _onSecurityStateChanged(event) { |
| 109 var data = /** @type {!WebInspector.PageSecurityState} */ (event.data); |
| 110 var securityState = /** @type {!SecurityAgent.SecurityState} */ (data.securi
tyState); |
| 111 var explanations = /** @type {!Array<!SecurityAgent.SecurityStateExplanation
>} */ (data.explanations); |
| 112 var insecureContentStatus = /** @type {?SecurityAgent.InsecureContentStatus}
*/ (data.insecureContentStatus); |
| 113 var schemeIsCryptographic = /** @type {boolean} */ (data.schemeIsCryptograph
ic); |
| 114 this._updateSecurityState(securityState, explanations, insecureContentStatus
, schemeIsCryptographic); |
| 115 } |
| 116 |
| 117 selectAndSwitchToMainView() { |
| 118 // The sidebar element will trigger displaying the main view. Rather than ma
king a redundant call to display the main view, we rely on this. |
| 119 this._sidebarMainViewElement.select(); |
| 120 } |
| 121 /** |
| 122 * @param {!WebInspector.SecurityPanel.Origin} origin |
| 123 */ |
| 124 showOrigin(origin) { |
| 125 var originState = this._origins.get(origin); |
| 126 if (!originState.originView) |
| 127 originState.originView = new WebInspector.SecurityOriginView(this, origin,
originState); |
| 128 |
| 129 this._setVisibleView(originState.originView); |
| 130 } |
| 131 |
| 132 /** |
| 133 * @override |
| 134 */ |
| 135 wasShown() { |
| 136 super.wasShown(); |
| 137 if (!this._visibleView) |
| 138 this.selectAndSwitchToMainView(); |
| 139 } |
| 140 |
| 141 /** |
| 142 * @override |
| 143 */ |
| 144 focus() { |
| 145 this._sidebarTree.focus(); |
| 146 } |
| 147 |
| 148 /** |
| 149 * @param {!WebInspector.VBox} view |
| 150 */ |
| 151 _setVisibleView(view) { |
| 152 if (this._visibleView === view) |
| 153 return; |
| 154 |
| 155 if (this._visibleView) |
| 156 this._visibleView.detach(); |
| 157 |
| 158 this._visibleView = view; |
| 159 |
| 160 if (view) |
| 161 this.splitWidget().setMainWidget(view); |
| 162 } |
| 163 |
| 164 /** |
| 165 * @param {!WebInspector.Event} event |
| 166 */ |
| 167 _onResponseReceived(event) { |
| 168 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data); |
| 169 if (request.resourceType() === WebInspector.resourceTypes.Document) |
| 170 this._lastResponseReceivedForLoaderId.set(request.loaderId, request); |
| 171 } |
| 172 |
| 173 /** |
| 174 * @param {!WebInspector.NetworkRequest} request |
| 175 */ |
| 176 _processRequest(request) { |
| 177 var origin = WebInspector.ParsedURL.extractOrigin(request.url); |
| 178 |
| 179 if (!origin) { |
| 180 // We don't handle resources like data: URIs. Most of them don't affect th
e lock icon. |
| 181 return; |
| 182 } |
| 183 |
| 184 var securityState = /** @type {!SecurityAgent.SecurityState} */ (request.sec
urityState()); |
| 185 |
| 186 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.Blocka
ble && this._ranInsecureContentStyle) |
| 187 securityState = this._ranInsecureContentStyle; |
| 188 else if ( |
| 189 request.mixedContentType === NetworkAgent.RequestMixedContentType.Option
allyBlockable && |
| 190 this._displayedInsecureContentStyle) |
| 191 securityState = this._displayedInsecureContentStyle; |
| 192 |
| 193 if (this._origins.has(origin)) { |
| 194 var originState = this._origins.get(origin); |
| 195 var oldSecurityState = originState.securityState; |
| 196 originState.securityState = this._securityStateMin(oldSecurityState, secur
ityState); |
| 197 if (oldSecurityState !== originState.securityState) { |
| 198 this._sidebarTree.updateOrigin(origin, securityState); |
| 199 if (originState.originView) |
| 200 originState.originView.setSecurityState(securityState); |
| 201 } |
| 202 } else { |
| 203 // TODO(lgarron): Store a (deduplicated) list of different security detail
s we have seen. https://crbug.com/503170 |
| 204 var originState = {}; |
| 205 originState.securityState = securityState; |
| 206 |
| 207 var securityDetails = request.securityDetails(); |
| 208 if (securityDetails) { |
| 209 originState.securityDetails = securityDetails; |
| 210 } |
| 211 |
| 212 this._origins.set(origin, originState); |
| 213 |
| 214 this._sidebarTree.addOrigin(origin, securityState); |
| 215 |
| 216 // Don't construct the origin view yet (let it happen lazily). |
| 217 } |
| 218 } |
| 219 |
| 220 /** |
| 221 * @param {!WebInspector.Event} event |
| 222 */ |
| 223 _onRequestFinished(event) { |
| 224 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data); |
| 225 this._updateFilterRequestCounts(request); |
| 226 this._processRequest(request); |
| 227 } |
| 228 |
| 229 /** |
| 230 * @param {!WebInspector.NetworkRequest} request |
| 231 */ |
| 232 _updateFilterRequestCounts(request) { |
| 233 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.None) |
| 234 return; |
| 235 |
| 236 /** @type {!WebInspector.NetworkLogView.MixedContentFilterValues} */ |
| 237 var filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.All; |
| 238 if (request.wasBlocked()) |
| 239 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Blocked; |
| 240 else if (request.mixedContentType === NetworkAgent.RequestMixedContentType.B
lockable) |
| 241 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.BlockOver
ridden; |
| 242 else if (request.mixedContentType === NetworkAgent.RequestMixedContentType.O
ptionallyBlockable) |
| 243 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Displayed
; |
| 244 |
| 245 if (!this._filterRequestCounts.has(filterKey)) |
| 246 this._filterRequestCounts.set(filterKey, 1); |
| 247 else |
| 248 this._filterRequestCounts.set(filterKey, this._filterRequestCounts.get(fil
terKey) + 1); |
| 249 |
| 250 this._mainView.refreshExplanations(); |
| 251 } |
| 252 |
| 253 /** |
| 254 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey |
| 255 * @return {number} |
| 256 */ |
| 257 filterRequestCount(filterKey) { |
| 258 return this._filterRequestCounts.get(filterKey) || 0; |
| 259 } |
| 260 |
| 261 showCertificateViewer() { |
| 262 var securityModel = WebInspector.SecurityModel.fromTarget(this._target); |
| 263 securityModel.showCertificateViewer(); |
| 264 } |
| 265 |
| 266 /** |
| 267 * @param {!SecurityAgent.SecurityState} stateA |
| 268 * @param {!SecurityAgent.SecurityState} stateB |
| 269 * @return {!SecurityAgent.SecurityState} |
| 270 */ |
| 271 _securityStateMin(stateA, stateB) { |
| 272 return WebInspector.SecurityModel.SecurityStateComparator(stateA, stateB) <
0 ? stateA : stateB; |
| 273 } |
| 274 |
| 275 /** |
| 276 * @override |
| 277 * @param {!WebInspector.Target} target |
| 278 */ |
| 279 targetAdded(target) { |
| 280 if (this._target) |
| 281 return; |
| 282 |
| 283 var listeners = []; |
| 284 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target); |
| 285 if (resourceTreeModel) { |
| 286 listeners = listeners.concat([ |
| 287 resourceTreeModel.addEventListener( |
| 288 WebInspector.ResourceTreeModel.Events.MainFrameNavigated, this._onMa
inFrameNavigated, this), |
| 289 resourceTreeModel.addEventListener( |
| 290 WebInspector.ResourceTreeModel.Events.InterstitialShown, this._onInt
erstitialShown, this), |
| 291 resourceTreeModel.addEventListener( |
| 292 WebInspector.ResourceTreeModel.Events.InterstitialHidden, this._onIn
terstitialHidden, this), |
| 293 ]); |
| 294 } |
| 295 |
| 296 var networkManager = WebInspector.NetworkManager.fromTarget(target); |
| 297 if (networkManager) { |
| 298 listeners = listeners.concat([ |
| 299 networkManager.addEventListener( |
| 300 WebInspector.NetworkManager.Events.ResponseReceived, this._onRespons
eReceived, this), |
| 301 networkManager.addEventListener( |
| 302 WebInspector.NetworkManager.Events.RequestFinished, this._onRequestF
inished, this), |
| 303 ]); |
| 304 } |
| 305 |
| 306 var securityModel = WebInspector.SecurityModel.fromTarget(target); |
| 307 if (securityModel) { |
| 308 listeners = listeners.concat([securityModel.addEventListener( |
| 309 WebInspector.SecurityModel.Events.SecurityStateChanged, this._onSecuri
tyStateChanged, this)]); |
| 310 } |
| 311 |
| 312 this._target = target; |
| 313 this._eventListeners.set(target, listeners); |
| 314 } |
| 315 |
| 316 /** |
| 317 * @override |
| 318 * @param {!WebInspector.Target} target |
| 319 */ |
| 320 targetRemoved(target) { |
| 321 if (this._target !== target) |
| 322 return; |
| 323 |
| 324 delete this._target; |
| 325 |
| 326 WebInspector.EventTarget.removeEventListeners(this._eventListeners.get(targe
t)); |
| 327 this._eventListeners.delete(target); |
| 328 } |
| 329 |
| 330 /** |
| 331 * @param {!WebInspector.Event} event |
| 332 */ |
| 333 _onMainFrameNavigated(event) { |
| 334 var frame = /** type {!PageAgent.Frame}*/ (event.data); |
| 335 var request = this._lastResponseReceivedForLoaderId.get(frame.loaderId); |
| 336 |
| 337 this.selectAndSwitchToMainView(); |
| 338 this._sidebarTree.clearOrigins(); |
| 339 this._origins.clear(); |
| 340 this._lastResponseReceivedForLoaderId.clear(); |
| 341 this._filterRequestCounts.clear(); |
| 342 // After clearing the filtered request counts, refresh the |
| 343 // explanations to reflect the new counts. |
| 344 this._mainView.refreshExplanations(); |
| 345 |
| 346 if (request) { |
| 347 var origin = WebInspector.ParsedURL.extractOrigin(request.url); |
| 348 this._sidebarTree.setMainOrigin(origin); |
| 349 this._processRequest(request); |
| 350 } |
| 351 } |
| 352 |
| 353 _onInterstitialShown() { |
| 354 // The panel might have been displaying the origin view on the |
| 355 // previously loaded page. When showing an interstitial, switch |
| 356 // back to the Overview view. |
| 357 this.selectAndSwitchToMainView(); |
| 358 this._sidebarTree.toggleOriginsList(true /* hidden */); |
| 359 } |
| 360 |
| 361 _onInterstitialHidden() { |
| 362 this._sidebarTree.toggleOriginsList(false /* hidden */); |
| 363 } |
| 32 }; | 364 }; |
| 33 | 365 |
| 34 /** @typedef {string} */ | 366 /** @typedef {string} */ |
| 35 WebInspector.SecurityPanel.Origin; | 367 WebInspector.SecurityPanel.Origin; |
| 36 | 368 |
| 37 /** | 369 /** |
| 38 * @typedef {Object} | 370 * @typedef {Object} |
| 39 * @property {!SecurityAgent.SecurityState} securityState - Current security sta
te of the origin. | 371 * @property {!SecurityAgent.SecurityState} securityState - Current security sta
te of the origin. |
| 40 * @property {?NetworkAgent.SecurityDetails} securityDetails - Security details
of the origin, if available. | 372 * @property {?NetworkAgent.SecurityDetails} securityDetails - Security details
of the origin, if available. |
| 41 * @property {?Promise<>} certificateDetailsPromise - Certificate details of the
origin. | 373 * @property {?Promise<>} certificateDetailsPromise - Certificate details of the
origin. |
| 42 * @property {?WebInspector.SecurityOriginView} originView - Current SecurityOri
ginView corresponding to origin. | 374 * @property {?WebInspector.SecurityOriginView} originView - Current SecurityOri
ginView corresponding to origin. |
| 43 */ | 375 */ |
| 44 WebInspector.SecurityPanel.OriginState; | 376 WebInspector.SecurityPanel.OriginState; |
| 45 | 377 |
| 46 WebInspector.SecurityPanel.prototype = { | |
| 47 /** | |
| 48 * @param {!SecurityAgent.SecurityState} securityState | |
| 49 */ | |
| 50 setRanInsecureContentStyle: function(securityState) | |
| 51 { | |
| 52 this._ranInsecureContentStyle = securityState; | |
| 53 }, | |
| 54 | |
| 55 /** | |
| 56 * @param {!SecurityAgent.SecurityState} securityState | |
| 57 */ | |
| 58 setDisplayedInsecureContentStyle: function(securityState) | |
| 59 { | |
| 60 this._displayedInsecureContentStyle = securityState; | |
| 61 }, | |
| 62 | |
| 63 /** | |
| 64 * @param {!SecurityAgent.SecurityState} newSecurityState | |
| 65 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations | |
| 66 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus | |
| 67 * @param {boolean} schemeIsCryptographic | |
| 68 */ | |
| 69 _updateSecurityState: function(newSecurityState, explanations, insecureConte
ntStatus, schemeIsCryptographic) | |
| 70 { | |
| 71 this._sidebarMainViewElement.setSecurityState(newSecurityState); | |
| 72 this._mainView.updateSecurityState(newSecurityState, explanations, insec
ureContentStatus, schemeIsCryptographic); | |
| 73 }, | |
| 74 | |
| 75 /** | |
| 76 * @param {!WebInspector.Event} event | |
| 77 */ | |
| 78 _onSecurityStateChanged: function(event) | |
| 79 { | |
| 80 var data = /** @type {!WebInspector.PageSecurityState} */ (event.data); | |
| 81 var securityState = /** @type {!SecurityAgent.SecurityState} */ (data.se
curityState); | |
| 82 var explanations = /** @type {!Array<!SecurityAgent.SecurityStateExplana
tion>} */ (data.explanations); | |
| 83 var insecureContentStatus = /** @type {?SecurityAgent.InsecureContentSta
tus} */ (data.insecureContentStatus); | |
| 84 var schemeIsCryptographic = /** @type {boolean} */ (data.schemeIsCryptog
raphic); | |
| 85 this._updateSecurityState(securityState, explanations, insecureContentSt
atus, schemeIsCryptographic); | |
| 86 }, | |
| 87 | |
| 88 selectAndSwitchToMainView: function() | |
| 89 { | |
| 90 // The sidebar element will trigger displaying the main view. Rather tha
n making a redundant call to display the main view, we rely on this. | |
| 91 this._sidebarMainViewElement.select(); | |
| 92 }, | |
| 93 /** | |
| 94 * @param {!WebInspector.SecurityPanel.Origin} origin | |
| 95 */ | |
| 96 showOrigin: function(origin) | |
| 97 { | |
| 98 var originState = this._origins.get(origin); | |
| 99 if (!originState.originView) | |
| 100 originState.originView = new WebInspector.SecurityOriginView(this, o
rigin, originState); | |
| 101 | |
| 102 this._setVisibleView(originState.originView); | |
| 103 }, | |
| 104 | |
| 105 wasShown: function() | |
| 106 { | |
| 107 WebInspector.Panel.prototype.wasShown.call(this); | |
| 108 if (!this._visibleView) | |
| 109 this.selectAndSwitchToMainView(); | |
| 110 }, | |
| 111 | |
| 112 /** | |
| 113 * @override | |
| 114 */ | |
| 115 focus: function() | |
| 116 { | |
| 117 this._sidebarTree.focus(); | |
| 118 }, | |
| 119 | |
| 120 /** | |
| 121 * @param {!WebInspector.VBox} view | |
| 122 */ | |
| 123 _setVisibleView: function(view) | |
| 124 { | |
| 125 if (this._visibleView === view) | |
| 126 return; | |
| 127 | |
| 128 if (this._visibleView) | |
| 129 this._visibleView.detach(); | |
| 130 | |
| 131 this._visibleView = view; | |
| 132 | |
| 133 if (view) | |
| 134 this.splitWidget().setMainWidget(view); | |
| 135 }, | |
| 136 | |
| 137 /** | |
| 138 * @param {!WebInspector.Event} event | |
| 139 */ | |
| 140 _onResponseReceived: function(event) | |
| 141 { | |
| 142 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data); | |
| 143 if (request.resourceType() === WebInspector.resourceTypes.Document) | |
| 144 this._lastResponseReceivedForLoaderId.set(request.loaderId, request)
; | |
| 145 }, | |
| 146 | |
| 147 /** | |
| 148 * @param {!WebInspector.NetworkRequest} request | |
| 149 */ | |
| 150 _processRequest: function(request) | |
| 151 { | |
| 152 var origin = WebInspector.ParsedURL.extractOrigin(request.url); | |
| 153 | |
| 154 if (!origin) { | |
| 155 // We don't handle resources like data: URIs. Most of them don't aff
ect the lock icon. | |
| 156 return; | |
| 157 } | |
| 158 | |
| 159 var securityState = /** @type {!SecurityAgent.SecurityState} */ (request
.securityState()); | |
| 160 | |
| 161 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.Bl
ockable && this._ranInsecureContentStyle) | |
| 162 securityState = this._ranInsecureContentStyle; | |
| 163 else if (request.mixedContentType === NetworkAgent.RequestMixedContentTy
pe.OptionallyBlockable && this._displayedInsecureContentStyle) | |
| 164 securityState = this._displayedInsecureContentStyle; | |
| 165 | |
| 166 if (this._origins.has(origin)) { | |
| 167 var originState = this._origins.get(origin); | |
| 168 var oldSecurityState = originState.securityState; | |
| 169 originState.securityState = this._securityStateMin(oldSecurityState,
securityState); | |
| 170 if (oldSecurityState !== originState.securityState) { | |
| 171 this._sidebarTree.updateOrigin(origin, securityState); | |
| 172 if (originState.originView) | |
| 173 originState.originView.setSecurityState(securityState); | |
| 174 } | |
| 175 } else { | |
| 176 // TODO(lgarron): Store a (deduplicated) list of different security
details we have seen. https://crbug.com/503170 | |
| 177 var originState = {}; | |
| 178 originState.securityState = securityState; | |
| 179 | |
| 180 var securityDetails = request.securityDetails(); | |
| 181 if (securityDetails) { | |
| 182 originState.securityDetails = securityDetails; | |
| 183 } | |
| 184 | |
| 185 this._origins.set(origin, originState); | |
| 186 | |
| 187 this._sidebarTree.addOrigin(origin, securityState); | |
| 188 | |
| 189 // Don't construct the origin view yet (let it happen lazily). | |
| 190 } | |
| 191 }, | |
| 192 | |
| 193 /** | |
| 194 * @param {!WebInspector.Event} event | |
| 195 */ | |
| 196 _onRequestFinished: function(event) | |
| 197 { | |
| 198 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data); | |
| 199 this._updateFilterRequestCounts(request); | |
| 200 this._processRequest(request); | |
| 201 }, | |
| 202 | |
| 203 /** | |
| 204 * @param {!WebInspector.NetworkRequest} request | |
| 205 */ | |
| 206 _updateFilterRequestCounts: function(request) | |
| 207 { | |
| 208 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.No
ne) | |
| 209 return; | |
| 210 | |
| 211 /** @type {!WebInspector.NetworkLogView.MixedContentFilterValues} */ | |
| 212 var filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.All
; | |
| 213 if (request.wasBlocked()) | |
| 214 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Blo
cked; | |
| 215 else if (request.mixedContentType === NetworkAgent.RequestMixedContentTy
pe.Blockable) | |
| 216 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Blo
ckOverridden; | |
| 217 else if (request.mixedContentType === NetworkAgent.RequestMixedContentTy
pe.OptionallyBlockable) | |
| 218 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Dis
played; | |
| 219 | |
| 220 if (!this._filterRequestCounts.has(filterKey)) | |
| 221 this._filterRequestCounts.set(filterKey, 1); | |
| 222 else | |
| 223 this._filterRequestCounts.set(filterKey, this._filterRequestCounts.g
et(filterKey) + 1); | |
| 224 | |
| 225 this._mainView.refreshExplanations(); | |
| 226 }, | |
| 227 | |
| 228 /** | |
| 229 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey | |
| 230 * @return {number} | |
| 231 */ | |
| 232 filterRequestCount: function(filterKey) | |
| 233 { | |
| 234 return this._filterRequestCounts.get(filterKey) || 0; | |
| 235 }, | |
| 236 | |
| 237 showCertificateViewer: function() | |
| 238 { | |
| 239 var securityModel = WebInspector.SecurityModel.fromTarget(this._target); | |
| 240 securityModel.showCertificateViewer(); | |
| 241 }, | |
| 242 | |
| 243 /** | |
| 244 * @param {!SecurityAgent.SecurityState} stateA | |
| 245 * @param {!SecurityAgent.SecurityState} stateB | |
| 246 * @return {!SecurityAgent.SecurityState} | |
| 247 */ | |
| 248 _securityStateMin: function(stateA, stateB) | |
| 249 { | |
| 250 return WebInspector.SecurityModel.SecurityStateComparator(stateA, stateB
) < 0 ? stateA : stateB; | |
| 251 }, | |
| 252 | |
| 253 /** | |
| 254 * @override | |
| 255 * @param {!WebInspector.Target} target | |
| 256 */ | |
| 257 targetAdded: function(target) | |
| 258 { | |
| 259 if (this._target) | |
| 260 return; | |
| 261 | |
| 262 var listeners = []; | |
| 263 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target
); | |
| 264 if (resourceTreeModel) { | |
| 265 listeners = listeners.concat([ | |
| 266 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode
l.Events.MainFrameNavigated, this._onMainFrameNavigated, this), | |
| 267 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode
l.Events.InterstitialShown, this._onInterstitialShown, this), | |
| 268 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode
l.Events.InterstitialHidden, this._onInterstitialHidden, this), | |
| 269 ]); | |
| 270 } | |
| 271 | |
| 272 var networkManager = WebInspector.NetworkManager.fromTarget(target); | |
| 273 if (networkManager) { | |
| 274 listeners = listeners.concat([ | |
| 275 networkManager.addEventListener(WebInspector.NetworkManager.Even
ts.ResponseReceived, this._onResponseReceived, this), | |
| 276 networkManager.addEventListener(WebInspector.NetworkManager.Even
ts.RequestFinished, this._onRequestFinished, this), | |
| 277 ]); | |
| 278 } | |
| 279 | |
| 280 var securityModel = WebInspector.SecurityModel.fromTarget(target); | |
| 281 if (securityModel) { | |
| 282 listeners = listeners.concat([ | |
| 283 securityModel.addEventListener(WebInspector.SecurityModel.Events
.SecurityStateChanged, this._onSecurityStateChanged, this) | |
| 284 ]); | |
| 285 } | |
| 286 | |
| 287 this._target = target; | |
| 288 this._eventListeners.set(target, listeners); | |
| 289 }, | |
| 290 | |
| 291 /** | |
| 292 * @override | |
| 293 * @param {!WebInspector.Target} target | |
| 294 */ | |
| 295 targetRemoved: function(target) | |
| 296 { | |
| 297 if (this._target !== target) | |
| 298 return; | |
| 299 | |
| 300 delete this._target; | |
| 301 | |
| 302 WebInspector.EventTarget.removeEventListeners(this._eventListeners.get(t
arget)); | |
| 303 this._eventListeners.delete(target); | |
| 304 }, | |
| 305 | |
| 306 /** | |
| 307 * @param {!WebInspector.Event} event | |
| 308 */ | |
| 309 _onMainFrameNavigated: function(event) | |
| 310 { | |
| 311 var frame = /** type {!PageAgent.Frame}*/ (event.data); | |
| 312 var request = this._lastResponseReceivedForLoaderId.get(frame.loaderId); | |
| 313 | |
| 314 this.selectAndSwitchToMainView(); | |
| 315 this._sidebarTree.clearOrigins(); | |
| 316 this._origins.clear(); | |
| 317 this._lastResponseReceivedForLoaderId.clear(); | |
| 318 this._filterRequestCounts.clear(); | |
| 319 // After clearing the filtered request counts, refresh the | |
| 320 // explanations to reflect the new counts. | |
| 321 this._mainView.refreshExplanations(); | |
| 322 | |
| 323 if (request) { | |
| 324 var origin = WebInspector.ParsedURL.extractOrigin(request.url); | |
| 325 this._sidebarTree.setMainOrigin(origin); | |
| 326 this._processRequest(request); | |
| 327 } | |
| 328 }, | |
| 329 | |
| 330 _onInterstitialShown: function() | |
| 331 { | |
| 332 // The panel might have been displaying the origin view on the | |
| 333 // previously loaded page. When showing an interstitial, switch | |
| 334 // back to the Overview view. | |
| 335 this.selectAndSwitchToMainView(); | |
| 336 this._sidebarTree.toggleOriginsList(true /* hidden */); | |
| 337 }, | |
| 338 | |
| 339 _onInterstitialHidden: function() | |
| 340 { | |
| 341 this._sidebarTree.toggleOriginsList(false /* hidden */); | |
| 342 }, | |
| 343 | |
| 344 __proto__: WebInspector.PanelWithSidebar.prototype | |
| 345 }; | |
| 346 | 378 |
| 347 /** | 379 /** |
| 348 * @return {!WebInspector.SecurityPanel} | 380 * @unrestricted |
| 349 */ | 381 */ |
| 350 WebInspector.SecurityPanel._instance = function() | 382 WebInspector.SecurityPanelSidebarTree = class extends TreeOutlineInShadow { |
| 351 { | 383 /** |
| 352 return /** @type {!WebInspector.SecurityPanel} */ (self.runtime.sharedInstan
ce(WebInspector.SecurityPanel)); | 384 * @param {!WebInspector.SecurityPanelSidebarTreeElement} mainViewElement |
| 353 }; | 385 * @param {function(!WebInspector.SecurityPanel.Origin)} showOriginInPanel |
| 354 | 386 */ |
| 355 /** | 387 constructor(mainViewElement, showOriginInPanel) { |
| 356 * @param {string} text | 388 super(); |
| 357 * @param {!WebInspector.SecurityPanel} panel | 389 this.registerRequiredCSS('security/sidebar.css'); |
| 358 * @return {!Element} | 390 this.registerRequiredCSS('security/lockIcon.css'); |
| 359 */ | |
| 360 WebInspector.SecurityPanel.createCertificateViewerButton = function(text, panel) | |
| 361 { | |
| 362 /** | |
| 363 * @param {!Event} e | |
| 364 */ | |
| 365 function showCertificateViewer(e) | |
| 366 { | |
| 367 e.consume(); | |
| 368 panel.showCertificateViewer(); | |
| 369 } | |
| 370 | |
| 371 return createTextButton(text, showCertificateViewer, "security-certificate-b
utton"); | |
| 372 }; | |
| 373 | |
| 374 /** | |
| 375 * @param {string} text | |
| 376 * @param {string} origin | |
| 377 * @return {!Element} | |
| 378 */ | |
| 379 WebInspector.SecurityPanel.createCertificateViewerButton2 = function(text, origi
n) | |
| 380 { | |
| 381 /** | |
| 382 * @param {!Event} e | |
| 383 */ | |
| 384 function showCertificateViewer(e) | |
| 385 { | |
| 386 function certificateCallback(names) | |
| 387 { | |
| 388 InspectorFrontendHost.showCertificateViewer(names); | |
| 389 } | |
| 390 | |
| 391 e.consume(); | |
| 392 WebInspector.multitargetNetworkManager.getCertificate(origin, certificat
eCallback); | |
| 393 } | |
| 394 | |
| 395 return createTextButton(text, showCertificateViewer, "security-certificate-b
utton"); | |
| 396 }; | |
| 397 | |
| 398 /** | |
| 399 * @constructor | |
| 400 * @extends {TreeOutlineInShadow} | |
| 401 * @param {!WebInspector.SecurityPanelSidebarTreeElement} mainViewElement | |
| 402 * @param {function(!WebInspector.SecurityPanel.Origin)} showOriginInPanel | |
| 403 */ | |
| 404 WebInspector.SecurityPanelSidebarTree = function(mainViewElement, showOriginInPa
nel) | |
| 405 { | |
| 406 TreeOutlineInShadow.call(this); | |
| 407 this.registerRequiredCSS("security/sidebar.css"); | |
| 408 this.registerRequiredCSS("security/lockIcon.css"); | |
| 409 this.appendChild(mainViewElement); | 391 this.appendChild(mainViewElement); |
| 410 | 392 |
| 411 this._showOriginInPanel = showOriginInPanel; | 393 this._showOriginInPanel = showOriginInPanel; |
| 412 this._mainOrigin = null; | 394 this._mainOrigin = null; |
| 413 | 395 |
| 414 /** @type {!Map<!WebInspector.SecurityPanelSidebarTree.OriginGroupName, !Tre
eElement>} */ | 396 /** @type {!Map<!WebInspector.SecurityPanelSidebarTree.OriginGroupName, !Tre
eElement>} */ |
| 415 this._originGroups = new Map(); | 397 this._originGroups = new Map(); |
| 416 | 398 |
| 417 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) { | 399 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) { |
| 418 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupN
ame[key]; | 400 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupNam
e[key]; |
| 419 var originGroup = new TreeElement(originGroupName, true); | 401 var originGroup = new TreeElement(originGroupName, true); |
| 420 originGroup.selectable = false; | 402 originGroup.selectable = false; |
| 421 originGroup.expand(); | 403 originGroup.expand(); |
| 422 originGroup.listItemElement.classList.add("security-sidebar-origins"); | 404 originGroup.listItemElement.classList.add('security-sidebar-origins'); |
| 423 this._originGroups.set(originGroupName, originGroup); | 405 this._originGroups.set(originGroupName, originGroup); |
| 424 this.appendChild(originGroup); | 406 this.appendChild(originGroup); |
| 425 } | 407 } |
| 426 this._clearOriginGroups(); | 408 this._clearOriginGroups(); |
| 427 | 409 |
| 428 // This message will be removed by clearOrigins() during the first new page
load after the panel was opened. | 410 // This message will be removed by clearOrigins() during the first new page
load after the panel was opened. |
| 429 var mainViewReloadMessage = new TreeElement(WebInspector.UIString("Reload to
view details")); | 411 var mainViewReloadMessage = new TreeElement(WebInspector.UIString('Reload to
view details')); |
| 430 mainViewReloadMessage.selectable = false; | 412 mainViewReloadMessage.selectable = false; |
| 431 mainViewReloadMessage.listItemElement.classList.add("security-main-view-relo
ad-message"); | 413 mainViewReloadMessage.listItemElement.classList.add('security-main-view-relo
ad-message'); |
| 432 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName
.MainOrigin).appendChild(mainViewReloadMessage); | 414 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName
.MainOrigin) |
| 415 .appendChild(mainViewReloadMessage); |
| 433 | 416 |
| 434 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa
nelSidebarTreeElement>} */ | 417 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa
nelSidebarTreeElement>} */ |
| 435 this._elementsByOrigin = new Map(); | 418 this._elementsByOrigin = new Map(); |
| 419 } |
| 420 |
| 421 /** |
| 422 * @param {boolean} hidden |
| 423 */ |
| 424 toggleOriginsList(hidden) { |
| 425 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) { |
| 426 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupNam
e[key]; |
| 427 var group = this._originGroups.get(originGroupName); |
| 428 if (group) |
| 429 group.hidden = hidden; |
| 430 } |
| 431 } |
| 432 |
| 433 /** |
| 434 * @param {!WebInspector.SecurityPanel.Origin} origin |
| 435 * @param {!SecurityAgent.SecurityState} securityState |
| 436 */ |
| 437 addOrigin(origin, securityState) { |
| 438 var originElement = new WebInspector.SecurityPanelSidebarTreeElement( |
| 439 origin, this._showOriginInPanel.bind(this, origin), 'security-sidebar-tr
ee-item', 'security-property'); |
| 440 originElement.listItemElement.title = origin; |
| 441 this._elementsByOrigin.set(origin, originElement); |
| 442 this.updateOrigin(origin, securityState); |
| 443 } |
| 444 |
| 445 /** |
| 446 * @param {!WebInspector.SecurityPanel.Origin} origin |
| 447 */ |
| 448 setMainOrigin(origin) { |
| 449 this._mainOrigin = origin; |
| 450 } |
| 451 |
| 452 /** |
| 453 * @param {!WebInspector.SecurityPanel.Origin} origin |
| 454 * @param {!SecurityAgent.SecurityState} securityState |
| 455 */ |
| 456 updateOrigin(origin, securityState) { |
| 457 var originElement = |
| 458 /** @type {!WebInspector.SecurityPanelSidebarTreeElement} */ (this._elem
entsByOrigin.get(origin)); |
| 459 originElement.setSecurityState(securityState); |
| 460 |
| 461 var newParent; |
| 462 if (origin === this._mainOrigin) { |
| 463 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTree.O
riginGroupName.MainOrigin); |
| 464 } else { |
| 465 switch (securityState) { |
| 466 case SecurityAgent.SecurityState.Secure: |
| 467 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTr
ee.OriginGroupName.Secure); |
| 468 break; |
| 469 case SecurityAgent.SecurityState.Unknown: |
| 470 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTr
ee.OriginGroupName.Unknown); |
| 471 break; |
| 472 default: |
| 473 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTr
ee.OriginGroupName.NonSecure); |
| 474 break; |
| 475 } |
| 476 } |
| 477 |
| 478 var oldParent = originElement.parent; |
| 479 if (oldParent !== newParent) { |
| 480 if (oldParent) { |
| 481 oldParent.removeChild(originElement); |
| 482 if (oldParent.childCount() === 0) |
| 483 oldParent.hidden = true; |
| 484 } |
| 485 newParent.appendChild(originElement); |
| 486 newParent.hidden = false; |
| 487 } |
| 488 } |
| 489 |
| 490 _clearOriginGroups() { |
| 491 for (var originGroup of this._originGroups.values()) { |
| 492 originGroup.removeChildren(); |
| 493 originGroup.hidden = true; |
| 494 } |
| 495 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName
.MainOrigin).hidden = false; |
| 496 } |
| 497 |
| 498 clearOrigins() { |
| 499 this._clearOriginGroups(); |
| 500 this._elementsByOrigin.clear(); |
| 501 } |
| 436 }; | 502 }; |
| 437 | 503 |
| 438 WebInspector.SecurityPanelSidebarTree.prototype = { | |
| 439 /** | |
| 440 * @param {boolean} hidden | |
| 441 */ | |
| 442 toggleOriginsList: function(hidden) | |
| 443 { | |
| 444 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) { | |
| 445 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGr
oupName[key]; | |
| 446 var group = this._originGroups.get(originGroupName); | |
| 447 if (group) | |
| 448 group.hidden = hidden; | |
| 449 } | |
| 450 }, | |
| 451 | |
| 452 /** | |
| 453 * @param {!WebInspector.SecurityPanel.Origin} origin | |
| 454 * @param {!SecurityAgent.SecurityState} securityState | |
| 455 */ | |
| 456 addOrigin: function(origin, securityState) | |
| 457 { | |
| 458 var originElement = new WebInspector.SecurityPanelSidebarTreeElement(ori
gin, this._showOriginInPanel.bind(this, origin), "security-sidebar-tree-item", "
security-property"); | |
| 459 originElement.listItemElement.title = origin; | |
| 460 this._elementsByOrigin.set(origin, originElement); | |
| 461 this.updateOrigin(origin, securityState); | |
| 462 }, | |
| 463 | |
| 464 /** | |
| 465 * @param {!WebInspector.SecurityPanel.Origin} origin | |
| 466 */ | |
| 467 setMainOrigin: function(origin) | |
| 468 { | |
| 469 this._mainOrigin = origin; | |
| 470 }, | |
| 471 | |
| 472 /** | |
| 473 * @param {!WebInspector.SecurityPanel.Origin} origin | |
| 474 * @param {!SecurityAgent.SecurityState} securityState | |
| 475 */ | |
| 476 updateOrigin: function(origin, securityState) | |
| 477 { | |
| 478 var originElement = /** @type {!WebInspector.SecurityPanelSidebarTreeEle
ment} */ (this._elementsByOrigin.get(origin)); | |
| 479 originElement.setSecurityState(securityState); | |
| 480 | |
| 481 var newParent; | |
| 482 if (origin === this._mainOrigin) { | |
| 483 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebar
Tree.OriginGroupName.MainOrigin); | |
| 484 } else { | |
| 485 switch (securityState) { | |
| 486 case SecurityAgent.SecurityState.Secure: | |
| 487 newParent = this._originGroups.get(WebInspector.SecurityPanelSid
ebarTree.OriginGroupName.Secure); | |
| 488 break; | |
| 489 case SecurityAgent.SecurityState.Unknown: | |
| 490 newParent = this._originGroups.get(WebInspector.SecurityPanelSid
ebarTree.OriginGroupName.Unknown); | |
| 491 break; | |
| 492 default: | |
| 493 newParent = this._originGroups.get(WebInspector.SecurityPanelSid
ebarTree.OriginGroupName.NonSecure); | |
| 494 break; | |
| 495 } | |
| 496 } | |
| 497 | |
| 498 var oldParent = originElement.parent; | |
| 499 if (oldParent !== newParent) { | |
| 500 if (oldParent) { | |
| 501 oldParent.removeChild(originElement); | |
| 502 if (oldParent.childCount() === 0) | |
| 503 oldParent.hidden = true; | |
| 504 } | |
| 505 newParent.appendChild(originElement); | |
| 506 newParent.hidden = false; | |
| 507 } | |
| 508 | |
| 509 }, | |
| 510 | |
| 511 _clearOriginGroups: function() | |
| 512 { | |
| 513 for (var originGroup of this._originGroups.values()) { | |
| 514 originGroup.removeChildren(); | |
| 515 originGroup.hidden = true; | |
| 516 } | |
| 517 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroup
Name.MainOrigin).hidden = false; | |
| 518 }, | |
| 519 | |
| 520 clearOrigins: function() | |
| 521 { | |
| 522 this._clearOriginGroups(); | |
| 523 this._elementsByOrigin.clear(); | |
| 524 }, | |
| 525 | |
| 526 __proto__: TreeOutlineInShadow.prototype | |
| 527 }; | |
| 528 | |
| 529 | |
| 530 /** | 504 /** |
| 531 * A mapping from Javascript key IDs to names (sidebar section titles). | 505 * A mapping from Javascript key IDs to names (sidebar section titles). |
| 532 * Note: The names are used as keys into a map, so they must be distinct from ea
ch other. | 506 * Note: The names are used as keys into a map, so they must be distinct from ea
ch other. |
| 533 * @enum {string} | 507 * @enum {string} |
| 534 */ | 508 */ |
| 535 WebInspector.SecurityPanelSidebarTree.OriginGroupName = { | 509 WebInspector.SecurityPanelSidebarTree.OriginGroupName = { |
| 536 MainOrigin: WebInspector.UIString("Main Origin"), | 510 MainOrigin: WebInspector.UIString('Main Origin'), |
| 537 NonSecure: WebInspector.UIString("Non-Secure Origins"), | 511 NonSecure: WebInspector.UIString('Non-Secure Origins'), |
| 538 Secure: WebInspector.UIString("Secure Origins"), | 512 Secure: WebInspector.UIString('Secure Origins'), |
| 539 Unknown: WebInspector.UIString("Unknown / Canceled") | 513 Unknown: WebInspector.UIString('Unknown / Canceled') |
| 540 }; | 514 }; |
| 541 | 515 |
| 542 | |
| 543 /** | 516 /** |
| 544 * @constructor | 517 * @unrestricted |
| 545 * @extends {TreeElement} | |
| 546 * @param {string} text | |
| 547 * @param {function()} selectCallback | |
| 548 * @param {string} className | |
| 549 * @param {string} cssPrefix | |
| 550 */ | 518 */ |
| 551 WebInspector.SecurityPanelSidebarTreeElement = function(text, selectCallback, cl
assName, cssPrefix) | 519 WebInspector.SecurityPanelSidebarTreeElement = class extends TreeElement { |
| 552 { | 520 /** |
| 553 TreeElement.call(this, "", false); | 521 * @param {string} text |
| 522 * @param {function()} selectCallback |
| 523 * @param {string} className |
| 524 * @param {string} cssPrefix |
| 525 */ |
| 526 constructor(text, selectCallback, className, cssPrefix) { |
| 527 super('', false); |
| 554 this._selectCallback = selectCallback; | 528 this._selectCallback = selectCallback; |
| 555 this._cssPrefix = cssPrefix; | 529 this._cssPrefix = cssPrefix; |
| 556 this.listItemElement.classList.add(className); | 530 this.listItemElement.classList.add(className); |
| 557 this._iconElement = this.listItemElement.createChild("div", "icon"); | 531 this._iconElement = this.listItemElement.createChild('div', 'icon'); |
| 558 this._iconElement.classList.add(this._cssPrefix); | 532 this._iconElement.classList.add(this._cssPrefix); |
| 559 this.listItemElement.createChild("span", "title").textContent = text; | 533 this.listItemElement.createChild('span', 'title').textContent = text; |
| 560 this.setSecurityState(SecurityAgent.SecurityState.Unknown); | 534 this.setSecurityState(SecurityAgent.SecurityState.Unknown); |
| 535 } |
| 536 |
| 537 /** |
| 538 * @param {!WebInspector.SecurityPanelSidebarTreeElement} a |
| 539 * @param {!WebInspector.SecurityPanelSidebarTreeElement} b |
| 540 * @return {number} |
| 541 */ |
| 542 static SecurityStateComparator(a, b) { |
| 543 return WebInspector.SecurityModel.SecurityStateComparator(a.securityState(),
b.securityState()); |
| 544 } |
| 545 |
| 546 /** |
| 547 * @param {!SecurityAgent.SecurityState} newSecurityState |
| 548 */ |
| 549 setSecurityState(newSecurityState) { |
| 550 if (this._securityState) |
| 551 this._iconElement.classList.remove(this._cssPrefix + '-' + this._securityS
tate); |
| 552 |
| 553 this._securityState = newSecurityState; |
| 554 this._iconElement.classList.add(this._cssPrefix + '-' + newSecurityState); |
| 555 } |
| 556 |
| 557 /** |
| 558 * @return {!SecurityAgent.SecurityState} |
| 559 */ |
| 560 securityState() { |
| 561 return this._securityState; |
| 562 } |
| 563 |
| 564 /** |
| 565 * @override |
| 566 * @return {boolean} |
| 567 */ |
| 568 onselect() { |
| 569 this._selectCallback(); |
| 570 return true; |
| 571 } |
| 561 }; | 572 }; |
| 562 | 573 |
| 563 WebInspector.SecurityPanelSidebarTreeElement.prototype = { | 574 |
| 575 /** |
| 576 * @unrestricted |
| 577 */ |
| 578 WebInspector.SecurityMainView = class extends WebInspector.VBox { |
| 579 /** |
| 580 * @param {!WebInspector.SecurityPanel} panel |
| 581 */ |
| 582 constructor(panel) { |
| 583 super(true); |
| 584 this.registerRequiredCSS('security/mainView.css'); |
| 585 this.registerRequiredCSS('security/lockIcon.css'); |
| 586 this.setMinimumSize(200, 100); |
| 587 |
| 588 this.contentElement.classList.add('security-main-view'); |
| 589 |
| 590 this._panel = panel; |
| 591 |
| 592 this._summarySection = this.contentElement.createChild('div', 'security-summ
ary'); |
| 593 |
| 594 // Info explanations should appear after all others. |
| 595 this._securityExplanationsMain = this.contentElement.createChild('div', 'sec
urity-explanation-list'); |
| 596 this._securityExplanationsExtra = |
| 597 this.contentElement.createChild('div', 'security-explanation-list securi
ty-explanations-extra'); |
| 598 |
| 599 // Fill the security summary section. |
| 600 this._summarySection.createChild('div', 'security-summary-section-title').te
xtContent = |
| 601 WebInspector.UIString('Security Overview'); |
| 602 |
| 603 var lockSpectrum = this._summarySection.createChild('div', 'lock-spectrum'); |
| 604 lockSpectrum.createChild('div', 'lock-icon lock-icon-secure').title = WebIns
pector.UIString('Secure'); |
| 605 lockSpectrum.createChild('div', 'lock-icon lock-icon-neutral').title = WebIn
spector.UIString('Not Secure'); |
| 606 lockSpectrum.createChild('div', 'lock-icon lock-icon-insecure').title = |
| 607 WebInspector.UIString('Not Secure (Broken)'); |
| 608 |
| 609 this._summarySection.createChild('div', 'triangle-pointer-container') |
| 610 .createChild('div', 'triangle-pointer-wrapper') |
| 611 .createChild('div', 'triangle-pointer'); |
| 612 |
| 613 this._summaryText = this._summarySection.createChild('div', 'security-summar
y-text'); |
| 614 } |
| 615 |
| 616 /** |
| 617 * @param {!Element} parent |
| 618 * @param {!SecurityAgent.SecurityStateExplanation} explanation |
| 619 * @return {!Element} |
| 620 */ |
| 621 _addExplanation(parent, explanation) { |
| 622 var explanationSection = parent.createChild('div', 'security-explanation'); |
| 623 explanationSection.classList.add('security-explanation-' + explanation.secur
ityState); |
| 624 |
| 625 explanationSection.createChild('div', 'security-property') |
| 626 .classList.add('security-property-' + explanation.securityState); |
| 627 var text = explanationSection.createChild('div', 'security-explanation-text'
); |
| 628 text.createChild('div', 'security-explanation-title').textContent = explanat
ion.summary; |
| 629 text.createChild('div').textContent = explanation.description; |
| 630 |
| 631 if (explanation.hasCertificate) { |
| 632 text.appendChild(WebInspector.SecurityPanel.createCertificateViewerButton( |
| 633 WebInspector.UIString('View certificate'), this._panel)); |
| 634 } |
| 635 |
| 636 return text; |
| 637 } |
| 638 |
| 639 /** |
| 640 * @param {!SecurityAgent.SecurityState} newSecurityState |
| 641 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations |
| 642 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus |
| 643 * @param {boolean} schemeIsCryptographic |
| 644 */ |
| 645 updateSecurityState(newSecurityState, explanations, insecureContentStatus, sch
emeIsCryptographic) { |
| 646 // Remove old state. |
| 647 // It's safe to call this even when this._securityState is undefined. |
| 648 this._summarySection.classList.remove('security-summary-' + this._securitySt
ate); |
| 649 |
| 650 // Add new state. |
| 651 this._securityState = newSecurityState; |
| 652 this._summarySection.classList.add('security-summary-' + this._securityState
); |
| 653 var summaryExplanationStrings = { |
| 654 'unknown': WebInspector.UIString('The security of this page is unknown.'), |
| 655 'insecure': WebInspector.UIString('This page is not secure (broken HTTPS).
'), |
| 656 'neutral': WebInspector.UIString('This page is not secure.'), |
| 657 'secure': WebInspector.UIString('This page is secure (valid HTTPS).') |
| 658 }; |
| 659 this._summaryText.textContent = summaryExplanationStrings[this._securityStat
e]; |
| 660 |
| 661 this._explanations = explanations, this._insecureContentStatus = insecureCon
tentStatus; |
| 662 this._schemeIsCryptographic = schemeIsCryptographic; |
| 663 |
| 664 this._panel.setRanInsecureContentStyle(insecureContentStatus.ranInsecureCont
entStyle); |
| 665 this._panel.setDisplayedInsecureContentStyle(insecureContentStatus.displayed
InsecureContentStyle); |
| 666 |
| 667 this.refreshExplanations(); |
| 668 } |
| 669 |
| 670 refreshExplanations() { |
| 671 this._securityExplanationsMain.removeChildren(); |
| 672 this._securityExplanationsExtra.removeChildren(); |
| 673 for (var explanation of this._explanations) { |
| 674 if (explanation.securityState === SecurityAgent.SecurityState.Info) { |
| 675 this._addExplanation(this._securityExplanationsExtra, explanation); |
| 676 } else { |
| 677 this._addExplanation(this._securityExplanationsMain, explanation); |
| 678 } |
| 679 } |
| 680 |
| 681 this._addMixedContentExplanations(); |
| 682 this._addContentWithCertErrorsExplanations(); |
| 683 |
| 684 // If all resources were served securely, add a Secure explanation. |
| 685 if (this._schemeIsCryptographic && this._insecureContentStatus && |
| 686 (!this._insecureContentStatus.displayedMixedContent && !this._insecureCo
ntentStatus.ranMixedContent && |
| 687 !this._insecureContentStatus.displayedContentWithCertErrors && |
| 688 !this._insecureContentStatus.ranContentWithCertErrors)) { |
| 689 this._addExplanation(this._securityExplanationsMain, /** @type {!SecurityA
gent.SecurityStateExplanation} */ ({ |
| 690 'securityState': SecurityAgent.SecurityState.Secure
, |
| 691 'summary': WebInspector.UIString('Secure Resources'
), |
| 692 'description': WebInspector.UIString('All resources
on this page are served securely.') |
| 693 })); |
| 694 } |
| 695 } |
| 696 |
| 697 _addMixedContentExplanations() { |
| 698 if (!this._schemeIsCryptographic) |
| 699 return; |
| 700 |
| 701 if (this._insecureContentStatus && |
| 702 (this._insecureContentStatus.ranMixedContent || this._insecureContentSta
tus.displayedMixedContent)) { |
| 703 if (this._insecureContentStatus.ranMixedContent) |
| 704 this._addMixedContentExplanation( |
| 705 this._securityExplanationsMain, this._insecureContentStatus.ranInsec
ureContentStyle, |
| 706 WebInspector.UIString('Active Mixed Content'), |
| 707 WebInspector.UIString( |
| 708 'You have recently allowed non-secure content (such as scripts o
r iframes) to run on this site.'), |
| 709 WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden
, |
| 710 showBlockOverriddenMixedContentInNetworkPanel); |
| 711 if (this._insecureContentStatus.displayedMixedContent) |
| 712 this._addMixedContentExplanation( |
| 713 this._securityExplanationsMain, this._insecureContentStatus.displaye
dInsecureContentStyle, |
| 714 WebInspector.UIString('Mixed Content'), WebInspector.UIString('The s
ite includes HTTP resources.'), |
| 715 WebInspector.NetworkLogView.MixedContentFilterValues.Displayed, show
DisplayedMixedContentInNetworkPanel); |
| 716 } |
| 717 |
| 718 if (this._panel.filterRequestCount(WebInspector.NetworkLogView.MixedContentF
ilterValues.Blocked) > 0) |
| 719 this._addMixedContentExplanation( |
| 720 this._securityExplanationsExtra, SecurityAgent.SecurityState.Info, |
| 721 WebInspector.UIString('Blocked mixed content'), |
| 722 WebInspector.UIString('Your page requested non-secure resources that w
ere blocked.'), |
| 723 WebInspector.NetworkLogView.MixedContentFilterValues.Blocked, showBloc
kedMixedContentInNetworkPanel); |
| 724 |
| 564 /** | 725 /** |
| 565 * @param {!SecurityAgent.SecurityState} newSecurityState | 726 * @param {!Event} e |
| 566 */ | 727 */ |
| 567 setSecurityState: function(newSecurityState) | 728 function showDisplayedMixedContentInNetworkPanel(e) { |
| 568 { | 729 e.consume(); |
| 569 if (this._securityState) | 730 WebInspector.NetworkPanel.revealAndFilter([{ |
| 570 this._iconElement.classList.remove(this._cssPrefix + "-" + this._sec
urityState); | 731 filterType: WebInspector.NetworkLogView.FilterType.MixedContent, |
| 571 | 732 filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Displa
yed |
| 572 this._securityState = newSecurityState; | 733 }]); |
| 573 this._iconElement.classList.add(this._cssPrefix + "-" + newSecurityState
); | 734 } |
| 574 }, | |
| 575 | 735 |
| 576 /** | 736 /** |
| 577 * @return {!SecurityAgent.SecurityState} | 737 * @param {!Event} e |
| 578 */ | 738 */ |
| 579 securityState: function() | 739 function showBlockOverriddenMixedContentInNetworkPanel(e) { |
| 580 { | 740 e.consume(); |
| 581 return this._securityState; | 741 WebInspector.NetworkPanel.revealAndFilter([{ |
| 582 }, | 742 filterType: WebInspector.NetworkLogView.FilterType.MixedContent, |
| 743 filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.BlockO
verridden |
| 744 }]); |
| 745 } |
| 583 | 746 |
| 584 /** | 747 /** |
| 585 * @override | 748 * @param {!Event} e |
| 586 * @return {boolean} | |
| 587 */ | 749 */ |
| 588 onselect: function() | 750 function showBlockedMixedContentInNetworkPanel(e) { |
| 589 { | 751 e.consume(); |
| 590 this._selectCallback(); | 752 WebInspector.NetworkPanel.revealAndFilter([{ |
| 591 return true; | 753 filterType: WebInspector.NetworkLogView.FilterType.MixedContent, |
| 592 }, | 754 filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Blocke
d |
| 593 | 755 }]); |
| 594 __proto__: TreeElement.prototype | 756 } |
| 757 } |
| 758 |
| 759 /** |
| 760 * @param {!Element} parent |
| 761 * @param {!SecurityAgent.SecurityState} securityState |
| 762 * @param {string} summary |
| 763 * @param {string} description |
| 764 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey |
| 765 * @param {!Function} networkFilterFn |
| 766 */ |
| 767 _addMixedContentExplanation(parent, securityState, summary, description, filte
rKey, networkFilterFn) { |
| 768 var mixedContentExplanation = /** @type {!SecurityAgent.SecurityStateExplana
tion} */ ( |
| 769 {'securityState': securityState, 'summary': summary, 'description': desc
ription}); |
| 770 |
| 771 var explanation = this._addExplanation(parent, mixedContentExplanation); |
| 772 |
| 773 var filterRequestCount = this._panel.filterRequestCount(filterKey); |
| 774 if (!filterRequestCount) { |
| 775 // Network instrumentation might not have been enabled for the page |
| 776 // load, so the security panel does not necessarily know a count of |
| 777 // individual mixed requests at this point. Prompt them to refresh |
| 778 // instead of pointing them to the Network panel to get prompted |
| 779 // to refresh. |
| 780 var refreshPrompt = explanation.createChild('div', 'security-mixed-content
'); |
| 781 refreshPrompt.textContent = WebInspector.UIString('Reload the page to reco
rd requests for HTTP resources.'); |
| 782 return; |
| 783 } |
| 784 |
| 785 var requestsAnchor = explanation.createChild('div', 'security-mixed-content
link'); |
| 786 if (filterRequestCount === 1) { |
| 787 requestsAnchor.textContent = WebInspector.UIString('View %d request in Net
work Panel', filterRequestCount); |
| 788 } else { |
| 789 requestsAnchor.textContent = WebInspector.UIString('View %d requests in Ne
twork Panel', filterRequestCount); |
| 790 } |
| 791 requestsAnchor.href = ''; |
| 792 requestsAnchor.addEventListener('click', networkFilterFn); |
| 793 } |
| 794 |
| 795 _addContentWithCertErrorsExplanations() { |
| 796 if (!this._schemeIsCryptographic) |
| 797 return; |
| 798 |
| 799 if (!this._insecureContentStatus) |
| 800 return; |
| 801 |
| 802 if (this._insecureContentStatus.ranContentWithCertErrors) { |
| 803 this._addExplanation( |
| 804 this._securityExplanationsMain, /** @type {!SecurityAgent.SecurityStat
eExplanation} */ ({ |
| 805 'securityState': this._insecureContentStatus.ranInsecureContentStyle
, |
| 806 'summary': WebInspector.UIString('Active content with certificate er
rors'), |
| 807 'description': WebInspector.UIString( |
| 808 'You have recently allowed content loaded with certificate error
s (such as scripts or iframes) to run on this site.') |
| 809 })); |
| 810 } |
| 811 |
| 812 if (this._insecureContentStatus.displayedContentWithCertErrors) { |
| 813 this._addExplanation(this._securityExplanationsMain, /** @type {!SecurityA
gent.SecurityStateExplanation} */ ({ |
| 814 'securityState': this._insecureContentStatus.displa
yedInsecureContentStyle, |
| 815 'summary': WebInspector.UIString('Content with cert
ificate errors'), |
| 816 'description': WebInspector.UIString( |
| 817 'This site includes resources that were loaded
with certificate errors.') |
| 818 })); |
| 819 } |
| 820 } |
| 595 }; | 821 }; |
| 596 | 822 |
| 597 /** | 823 /** |
| 598 * @param {!WebInspector.SecurityPanelSidebarTreeElement} a | 824 * @unrestricted |
| 599 * @param {!WebInspector.SecurityPanelSidebarTreeElement} b | |
| 600 * @return {number} | |
| 601 */ | 825 */ |
| 602 WebInspector.SecurityPanelSidebarTreeElement.SecurityStateComparator = function(
a, b) | 826 WebInspector.SecurityOriginView = class extends WebInspector.VBox { |
| 603 { | 827 /** |
| 604 return WebInspector.SecurityModel.SecurityStateComparator(a.securityState(),
b.securityState()); | 828 * @param {!WebInspector.SecurityPanel} panel |
| 605 }; | 829 * @param {!WebInspector.SecurityPanel.Origin} origin |
| 606 | 830 * @param {!WebInspector.SecurityPanel.OriginState} originState |
| 607 /** | 831 */ |
| 608 * @constructor | 832 constructor(panel, origin, originState) { |
| 609 * @extends {WebInspector.VBox} | 833 super(); |
| 610 * @param {!WebInspector.SecurityPanel} panel | |
| 611 */ | |
| 612 WebInspector.SecurityMainView = function(panel) | |
| 613 { | |
| 614 WebInspector.VBox.call(this, true); | |
| 615 this.registerRequiredCSS("security/mainView.css"); | |
| 616 this.registerRequiredCSS("security/lockIcon.css"); | |
| 617 this.setMinimumSize(200, 100); | |
| 618 | |
| 619 this.contentElement.classList.add("security-main-view"); | |
| 620 | |
| 621 this._panel = panel; | |
| 622 | |
| 623 this._summarySection = this.contentElement.createChild("div", "security-summ
ary"); | |
| 624 | |
| 625 // Info explanations should appear after all others. | |
| 626 this._securityExplanationsMain = this.contentElement.createChild("div", "sec
urity-explanation-list"); | |
| 627 this._securityExplanationsExtra = this.contentElement.createChild("div", "se
curity-explanation-list security-explanations-extra"); | |
| 628 | |
| 629 // Fill the security summary section. | |
| 630 this._summarySection.createChild("div", "security-summary-section-title").te
xtContent = WebInspector.UIString("Security Overview"); | |
| 631 | |
| 632 var lockSpectrum = this._summarySection.createChild("div", "lock-spectrum"); | |
| 633 lockSpectrum.createChild("div", "lock-icon lock-icon-secure").title = WebIns
pector.UIString("Secure"); | |
| 634 lockSpectrum.createChild("div", "lock-icon lock-icon-neutral").title = WebIn
spector.UIString("Not Secure"); | |
| 635 lockSpectrum.createChild("div", "lock-icon lock-icon-insecure").title = WebI
nspector.UIString("Not Secure (Broken)"); | |
| 636 | |
| 637 this._summarySection.createChild("div", "triangle-pointer-container").create
Child("div", "triangle-pointer-wrapper").createChild("div", "triangle-pointer"); | |
| 638 | |
| 639 this._summaryText = this._summarySection.createChild("div", "security-summar
y-text"); | |
| 640 }; | |
| 641 | |
| 642 WebInspector.SecurityMainView.prototype = { | |
| 643 /** | |
| 644 * @param {!Element} parent | |
| 645 * @param {!SecurityAgent.SecurityStateExplanation} explanation | |
| 646 * @return {!Element} | |
| 647 */ | |
| 648 _addExplanation: function(parent, explanation) | |
| 649 { | |
| 650 var explanationSection = parent.createChild("div", "security-explanation
"); | |
| 651 explanationSection.classList.add("security-explanation-" + explanation.s
ecurityState); | |
| 652 | |
| 653 explanationSection.createChild("div", "security-property").classList.add
("security-property-" + explanation.securityState); | |
| 654 var text = explanationSection.createChild("div", "security-explanation-t
ext"); | |
| 655 text.createChild("div", "security-explanation-title").textContent = expl
anation.summary; | |
| 656 text.createChild("div").textContent = explanation.description; | |
| 657 | |
| 658 if (explanation.hasCertificate) { | |
| 659 text.appendChild(WebInspector.SecurityPanel.createCertificateViewerB
utton(WebInspector.UIString("View certificate"), this._panel)); | |
| 660 } | |
| 661 | |
| 662 return text; | |
| 663 }, | |
| 664 | |
| 665 /** | |
| 666 * @param {!SecurityAgent.SecurityState} newSecurityState | |
| 667 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations | |
| 668 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus | |
| 669 * @param {boolean} schemeIsCryptographic | |
| 670 */ | |
| 671 updateSecurityState: function(newSecurityState, explanations, insecureConten
tStatus, schemeIsCryptographic) | |
| 672 { | |
| 673 // Remove old state. | |
| 674 // It's safe to call this even when this._securityState is undefined. | |
| 675 this._summarySection.classList.remove("security-summary-" + this._securi
tyState); | |
| 676 | |
| 677 // Add new state. | |
| 678 this._securityState = newSecurityState; | |
| 679 this._summarySection.classList.add("security-summary-" + this._securityS
tate); | |
| 680 var summaryExplanationStrings = { | |
| 681 "unknown": WebInspector.UIString("The security of this page is unkn
own."), | |
| 682 "insecure": WebInspector.UIString("This page is not secure (broken H
TTPS)."), | |
| 683 "neutral": WebInspector.UIString("This page is not secure."), | |
| 684 "secure": WebInspector.UIString("This page is secure (valid HTTPS)
.") | |
| 685 }; | |
| 686 this._summaryText.textContent = summaryExplanationStrings[this._security
State]; | |
| 687 | |
| 688 this._explanations = explanations, | |
| 689 this._insecureContentStatus = insecureContentStatus; | |
| 690 this._schemeIsCryptographic = schemeIsCryptographic; | |
| 691 | |
| 692 this._panel.setRanInsecureContentStyle(insecureContentStatus.ranInsecure
ContentStyle); | |
| 693 this._panel.setDisplayedInsecureContentStyle(insecureContentStatus.displ
ayedInsecureContentStyle); | |
| 694 | |
| 695 this.refreshExplanations(); | |
| 696 }, | |
| 697 | |
| 698 refreshExplanations: function() | |
| 699 { | |
| 700 this._securityExplanationsMain.removeChildren(); | |
| 701 this._securityExplanationsExtra.removeChildren(); | |
| 702 for (var explanation of this._explanations) { | |
| 703 if (explanation.securityState === SecurityAgent.SecurityState.Info)
{ | |
| 704 this._addExplanation(this._securityExplanationsExtra, explanatio
n); | |
| 705 } else { | |
| 706 this._addExplanation(this._securityExplanationsMain, explanation
); | |
| 707 } | |
| 708 } | |
| 709 | |
| 710 this._addMixedContentExplanations(); | |
| 711 this._addContentWithCertErrorsExplanations(); | |
| 712 | |
| 713 // If all resources were served securely, add a Secure explanation. | |
| 714 if (this._schemeIsCryptographic && this._insecureContentStatus && (!this
._insecureContentStatus.displayedMixedContent && !this._insecureContentStatus.ra
nMixedContent && !this._insecureContentStatus.displayedContentWithCertErrors &&
!this._insecureContentStatus.ranContentWithCertErrors)) { | |
| 715 this._addExplanation(this._securityExplanationsMain, /** @type {!Sec
urityAgent.SecurityStateExplanation} */ ({ | |
| 716 "securityState": SecurityAgent.SecurityState.Secure, | |
| 717 "summary": WebInspector.UIString("Secure Resources"), | |
| 718 "description": WebInspector.UIString("All resources on this page
are served securely.") | |
| 719 })); | |
| 720 } | |
| 721 }, | |
| 722 | |
| 723 _addMixedContentExplanations: function() | |
| 724 { | |
| 725 if (!this._schemeIsCryptographic) | |
| 726 return; | |
| 727 | |
| 728 if (this._insecureContentStatus && (this._insecureContentStatus.ranMixed
Content || this._insecureContentStatus.displayedMixedContent)) { | |
| 729 if (this._insecureContentStatus.ranMixedContent) | |
| 730 this._addMixedContentExplanation(this._securityExplanationsMain,
this._insecureContentStatus.ranInsecureContentStyle, WebInspector.UIString("Act
ive Mixed Content"), WebInspector.UIString("You have recently allowed non-secure
content (such as scripts or iframes) to run on this site."), WebInspector.Netwo
rkLogView.MixedContentFilterValues.BlockOverridden, showBlockOverriddenMixedCont
entInNetworkPanel); | |
| 731 if (this._insecureContentStatus.displayedMixedContent) | |
| 732 this._addMixedContentExplanation(this._securityExplanationsMain,
this._insecureContentStatus.displayedInsecureContentStyle, WebInspector.UIStrin
g("Mixed Content"), WebInspector.UIString("The site includes HTTP resources."),
WebInspector.NetworkLogView.MixedContentFilterValues.Displayed, showDisplayedMix
edContentInNetworkPanel); | |
| 733 } | |
| 734 | |
| 735 if (this._panel.filterRequestCount(WebInspector.NetworkLogView.MixedCont
entFilterValues.Blocked) > 0) | |
| 736 this._addMixedContentExplanation(this._securityExplanationsExtra, Se
curityAgent.SecurityState.Info, WebInspector.UIString("Blocked mixed content"),
WebInspector.UIString("Your page requested non-secure resources that were blocke
d."), WebInspector.NetworkLogView.MixedContentFilterValues.Blocked, showBlockedM
ixedContentInNetworkPanel); | |
| 737 | |
| 738 /** | |
| 739 * @param {!Event} e | |
| 740 */ | |
| 741 function showDisplayedMixedContentInNetworkPanel(e) | |
| 742 { | |
| 743 e.consume(); | |
| 744 WebInspector.NetworkPanel.revealAndFilter([ | |
| 745 { | |
| 746 filterType: WebInspector.NetworkLogView.FilterType.MixedCont
ent, | |
| 747 filterValue: WebInspector.NetworkLogView.MixedContentFilterV
alues.Displayed | |
| 748 } | |
| 749 ]); | |
| 750 } | |
| 751 | |
| 752 /** | |
| 753 * @param {!Event} e | |
| 754 */ | |
| 755 function showBlockOverriddenMixedContentInNetworkPanel(e) | |
| 756 { | |
| 757 e.consume(); | |
| 758 WebInspector.NetworkPanel.revealAndFilter([ | |
| 759 { | |
| 760 filterType: WebInspector.NetworkLogView.FilterType.MixedCont
ent, | |
| 761 filterValue: WebInspector.NetworkLogView.MixedContentFilterV
alues.BlockOverridden | |
| 762 } | |
| 763 ]); | |
| 764 } | |
| 765 | |
| 766 /** | |
| 767 * @param {!Event} e | |
| 768 */ | |
| 769 function showBlockedMixedContentInNetworkPanel(e) | |
| 770 { | |
| 771 e.consume(); | |
| 772 WebInspector.NetworkPanel.revealAndFilter([ | |
| 773 { | |
| 774 filterType: WebInspector.NetworkLogView.FilterType.MixedCont
ent, | |
| 775 filterValue: WebInspector.NetworkLogView.MixedContentFilterV
alues.Blocked | |
| 776 } | |
| 777 ]); | |
| 778 } | |
| 779 }, | |
| 780 | |
| 781 /** | |
| 782 * @param {!Element} parent | |
| 783 * @param {!SecurityAgent.SecurityState} securityState | |
| 784 * @param {string} summary | |
| 785 * @param {string} description | |
| 786 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey | |
| 787 * @param {!Function} networkFilterFn | |
| 788 */ | |
| 789 _addMixedContentExplanation: function(parent, securityState, summary, descri
ption, filterKey, networkFilterFn) | |
| 790 { | |
| 791 var mixedContentExplanation = /** @type {!SecurityAgent.SecurityStateExp
lanation} */ ({ | |
| 792 "securityState": securityState, | |
| 793 "summary": summary, | |
| 794 "description": description | |
| 795 }); | |
| 796 | |
| 797 var explanation = this._addExplanation(parent, mixedContentExplanation); | |
| 798 | |
| 799 var filterRequestCount = this._panel.filterRequestCount(filterKey); | |
| 800 if (!filterRequestCount) { | |
| 801 // Network instrumentation might not have been enabled for the page | |
| 802 // load, so the security panel does not necessarily know a count of | |
| 803 // individual mixed requests at this point. Prompt them to refresh | |
| 804 // instead of pointing them to the Network panel to get prompted | |
| 805 // to refresh. | |
| 806 var refreshPrompt = explanation.createChild("div", "security-mixed-c
ontent"); | |
| 807 refreshPrompt.textContent = WebInspector.UIString("Reload the page t
o record requests for HTTP resources."); | |
| 808 return; | |
| 809 } | |
| 810 | |
| 811 var requestsAnchor = explanation.createChild("div", "security-mixed-cont
ent link"); | |
| 812 if (filterRequestCount === 1) { | |
| 813 requestsAnchor.textContent = WebInspector.UIString("View %d request
in Network Panel", filterRequestCount); | |
| 814 } else { | |
| 815 requestsAnchor.textContent = WebInspector.UIString("View %d requests
in Network Panel", filterRequestCount); | |
| 816 } | |
| 817 requestsAnchor.href = ""; | |
| 818 requestsAnchor.addEventListener("click", networkFilterFn); | |
| 819 }, | |
| 820 | |
| 821 _addContentWithCertErrorsExplanations: function() | |
| 822 { | |
| 823 if (!this._schemeIsCryptographic) | |
| 824 return; | |
| 825 | |
| 826 if (!this._insecureContentStatus) | |
| 827 return; | |
| 828 | |
| 829 if (this._insecureContentStatus.ranContentWithCertErrors) { | |
| 830 this._addExplanation(this._securityExplanationsMain, /** @type {!Sec
urityAgent.SecurityStateExplanation} */ ({ | |
| 831 "securityState": this._insecureContentStatus.ranInsecureContentS
tyle, | |
| 832 "summary": WebInspector.UIString("Active content with certificat
e errors"), | |
| 833 "description": WebInspector.UIString("You have recently allowed
content loaded with certificate errors (such as scripts or iframes) to run on th
is site.") | |
| 834 })); | |
| 835 } | |
| 836 | |
| 837 if (this._insecureContentStatus.displayedContentWithCertErrors) { | |
| 838 this._addExplanation(this._securityExplanationsMain, /** @type {!Sec
urityAgent.SecurityStateExplanation} */ ({ | |
| 839 "securityState": this._insecureContentStatus.displayedInsecureCo
ntentStyle, | |
| 840 "summary": WebInspector.UIString("Content with certificate error
s"), | |
| 841 "description": WebInspector.UIString("This site includes resourc
es that were loaded with certificate errors.") | |
| 842 })); | |
| 843 } | |
| 844 }, | |
| 845 | |
| 846 | |
| 847 __proto__: WebInspector.VBox.prototype | |
| 848 }; | |
| 849 | |
| 850 /** | |
| 851 * @constructor | |
| 852 * @extends {WebInspector.VBox} | |
| 853 * @param {!WebInspector.SecurityPanel} panel | |
| 854 * @param {!WebInspector.SecurityPanel.Origin} origin | |
| 855 * @param {!WebInspector.SecurityPanel.OriginState} originState | |
| 856 */ | |
| 857 WebInspector.SecurityOriginView = function(panel, origin, originState) | |
| 858 { | |
| 859 WebInspector.VBox.call(this); | |
| 860 this._panel = panel; | 834 this._panel = panel; |
| 861 this.setMinimumSize(200, 100); | 835 this.setMinimumSize(200, 100); |
| 862 | 836 |
| 863 this.element.classList.add("security-origin-view"); | 837 this.element.classList.add('security-origin-view'); |
| 864 this.registerRequiredCSS("security/originView.css"); | 838 this.registerRequiredCSS('security/originView.css'); |
| 865 this.registerRequiredCSS("security/lockIcon.css"); | 839 this.registerRequiredCSS('security/lockIcon.css'); |
| 866 | 840 |
| 867 var titleSection = this.element.createChild("div", "title-section"); | 841 var titleSection = this.element.createChild('div', 'title-section'); |
| 868 var originDisplay = titleSection.createChild("div", "origin-display"); | 842 var originDisplay = titleSection.createChild('div', 'origin-display'); |
| 869 this._originLockIcon = originDisplay.createChild("span", "security-property"
); | 843 this._originLockIcon = originDisplay.createChild('span', 'security-property'
); |
| 870 this._originLockIcon.classList.add("security-property-" + originState.securi
tyState); | 844 this._originLockIcon.classList.add('security-property-' + originState.securi
tyState); |
| 871 // TODO(lgarron): Highlight the origin scheme. https://crbug.com/523589 | 845 // TODO(lgarron): Highlight the origin scheme. https://crbug.com/523589 |
| 872 originDisplay.createChild("span", "origin").textContent = origin; | 846 originDisplay.createChild('span', 'origin').textContent = origin; |
| 873 var originNetworkLink = titleSection.createChild("div", "link"); | 847 var originNetworkLink = titleSection.createChild('div', 'link'); |
| 874 originNetworkLink.textContent = WebInspector.UIString("View requests in Netw
ork Panel"); | 848 originNetworkLink.textContent = WebInspector.UIString('View requests in Netw
ork Panel'); |
| 875 function showOriginRequestsInNetworkPanel() | 849 function showOriginRequestsInNetworkPanel() { |
| 876 { | 850 var parsedURL = new WebInspector.ParsedURL(origin); |
| 877 var parsedURL = new WebInspector.ParsedURL(origin); | 851 WebInspector.NetworkPanel.revealAndFilter([ |
| 878 WebInspector.NetworkPanel.revealAndFilter([ | 852 {filterType: WebInspector.NetworkLogView.FilterType.Domain, filterValue:
parsedURL.host}, |
| 879 { | 853 {filterType: WebInspector.NetworkLogView.FilterType.Scheme, filterValue:
parsedURL.scheme} |
| 880 filterType: WebInspector.NetworkLogView.FilterType.Domain, | 854 ]); |
| 881 filterValue: parsedURL.host | 855 } |
| 882 }, | 856 originNetworkLink.addEventListener('click', showOriginRequestsInNetworkPanel
, false); |
| 883 { | |
| 884 filterType: WebInspector.NetworkLogView.FilterType.Scheme, | |
| 885 filterValue: parsedURL.scheme | |
| 886 } | |
| 887 ]); | |
| 888 } | |
| 889 originNetworkLink.addEventListener("click", showOriginRequestsInNetworkPanel
, false); | |
| 890 | |
| 891 | 857 |
| 892 if (originState.securityDetails) { | 858 if (originState.securityDetails) { |
| 893 var connectionSection = this.element.createChild("div", "origin-view-sec
tion"); | 859 var connectionSection = this.element.createChild('div', 'origin-view-secti
on'); |
| 894 connectionSection.createChild("div", "origin-view-section-title").textCo
ntent = WebInspector.UIString("Connection"); | 860 connectionSection.createChild('div', 'origin-view-section-title').textCont
ent = |
| 895 | 861 WebInspector.UIString('Connection'); |
| 896 var table = new WebInspector.SecurityDetailsTable(); | 862 |
| 897 connectionSection.appendChild(table.element()); | 863 var table = new WebInspector.SecurityDetailsTable(); |
| 898 table.addRow("Protocol", originState.securityDetails.protocol); | 864 connectionSection.appendChild(table.element()); |
| 899 if (originState.securityDetails.keyExchange) | 865 table.addRow('Protocol', originState.securityDetails.protocol); |
| 900 table.addRow("Key Exchange", originState.securityDetails.keyExchange
); | 866 if (originState.securityDetails.keyExchange) |
| 901 if (originState.securityDetails.keyExchangeGroup) | 867 table.addRow('Key Exchange', originState.securityDetails.keyExchange); |
| 902 table.addRow("Key Exchange Group", originState.securityDetails.keyEx
changeGroup); | 868 if (originState.securityDetails.keyExchangeGroup) |
| 903 table.addRow("Cipher", originState.securityDetails.cipher + (originState
.securityDetails.mac ? " with " + originState.securityDetails.mac : "")); | 869 table.addRow('Key Exchange Group', originState.securityDetails.keyExchan
geGroup); |
| 904 | 870 table.addRow( |
| 905 // Create the certificate section outside the callback, so that it appea
rs in the right place. | 871 'Cipher', originState.securityDetails.cipher + |
| 906 var certificateSection = this.element.createChild("div", "origin-view-se
ction"); | 872 (originState.securityDetails.mac ? ' with ' + originState.security
Details.mac : '')); |
| 907 certificateSection.createChild("div", "origin-view-section-title").textC
ontent = WebInspector.UIString("Certificate"); | 873 |
| 908 | 874 // Create the certificate section outside the callback, so that it appears
in the right place. |
| 909 if (originState.securityDetails.signedCertificateTimestampList.length) { | 875 var certificateSection = this.element.createChild('div', 'origin-view-sect
ion'); |
| 910 // Create the Certificate Transparency section outside the callback,
so that it appears in the right place. | 876 certificateSection.createChild('div', 'origin-view-section-title').textCon
tent = |
| 911 var sctSection = this.element.createChild("div", "origin-view-sectio
n"); | 877 WebInspector.UIString('Certificate'); |
| 912 sctSection.createChild("div", "origin-view-section-title").textConte
nt = WebInspector.UIString("Certificate Transparency"); | 878 |
| 879 if (originState.securityDetails.signedCertificateTimestampList.length) { |
| 880 // Create the Certificate Transparency section outside the callback, so
that it appears in the right place. |
| 881 var sctSection = this.element.createChild('div', 'origin-view-section'); |
| 882 sctSection.createChild('div', 'origin-view-section-title').textContent = |
| 883 WebInspector.UIString('Certificate Transparency'); |
| 884 } |
| 885 |
| 886 var sanDiv = this._createSanDiv(originState.securityDetails.sanList); |
| 887 var validFromString = new Date(1000 * originState.securityDetails.validFro
m).toUTCString(); |
| 888 var validUntilString = new Date(1000 * originState.securityDetails.validTo
).toUTCString(); |
| 889 |
| 890 table = new WebInspector.SecurityDetailsTable(); |
| 891 certificateSection.appendChild(table.element()); |
| 892 table.addRow(WebInspector.UIString('Subject'), originState.securityDetails
.subjectName); |
| 893 table.addRow(WebInspector.UIString('SAN'), sanDiv); |
| 894 table.addRow(WebInspector.UIString('Valid From'), validFromString); |
| 895 table.addRow(WebInspector.UIString('Valid Until'), validUntilString); |
| 896 table.addRow(WebInspector.UIString('Issuer'), originState.securityDetails.
issuer); |
| 897 table.addRow( |
| 898 '', WebInspector.SecurityPanel.createCertificateViewerButton2( |
| 899 WebInspector.UIString('Open full certificate details'), origin
)); |
| 900 |
| 901 if (!originState.securityDetails.signedCertificateTimestampList.length) |
| 902 return; |
| 903 |
| 904 // Show summary of SCT(s) of Certificate Transparency. |
| 905 var sctSummaryTable = new WebInspector.SecurityDetailsTable(); |
| 906 sctSummaryTable.element().classList.add('sct-summary'); |
| 907 sctSection.appendChild(sctSummaryTable.element()); |
| 908 for (var i = 0; i < originState.securityDetails.signedCertificateTimestamp
List.length; i++) { |
| 909 var sct = originState.securityDetails.signedCertificateTimestampList[i]; |
| 910 sctSummaryTable.addRow( |
| 911 WebInspector.UIString('SCT'), sct.logDescription + ' (' + sct.origin
+ ', ' + sct.status + ')'); |
| 912 } |
| 913 |
| 914 // Show detailed SCT(s) of Certificate Transparency. |
| 915 var sctTableWrapper = sctSection.createChild('div', 'sct-details'); |
| 916 sctTableWrapper.classList.add('hidden'); |
| 917 for (var i = 0; i < originState.securityDetails.signedCertificateTimestamp
List.length; i++) { |
| 918 var sctTable = new WebInspector.SecurityDetailsTable(); |
| 919 sctTableWrapper.appendChild(sctTable.element()); |
| 920 var sct = originState.securityDetails.signedCertificateTimestampList[i]; |
| 921 sctTable.addRow(WebInspector.UIString('Log Name'), sct.logDescription); |
| 922 sctTable.addRow(WebInspector.UIString('Log ID'), sct.logId.replace(/(.{2
})/g, '$1 ')); |
| 923 sctTable.addRow(WebInspector.UIString('Validation Status'), sct.status); |
| 924 sctTable.addRow(WebInspector.UIString('Source'), sct.origin); |
| 925 sctTable.addRow(WebInspector.UIString('Issued At'), new Date(sct.timesta
mp).toUTCString()); |
| 926 sctTable.addRow(WebInspector.UIString('Hash Algorithm'), sct.hashAlgorit
hm); |
| 927 sctTable.addRow(WebInspector.UIString('Signature Algorithm'), sct.signat
ureAlgorithm); |
| 928 sctTable.addRow(WebInspector.UIString('Signature Data'), sct.signatureDa
ta.replace(/(.{2})/g, '$1 ')); |
| 929 } |
| 930 |
| 931 // Add link to toggle between displaying of the summary of the SCT(s) and
the detailed SCT(s). |
| 932 var toggleSctsDetailsLink = sctSection.createChild('div', 'link'); |
| 933 toggleSctsDetailsLink.classList.add('sct-toggle'); |
| 934 toggleSctsDetailsLink.textContent = WebInspector.UIString('Show full detai
ls'); |
| 935 function toggleSctDetailsDisplay() { |
| 936 var isDetailsShown = !sctTableWrapper.classList.contains('hidden'); |
| 937 if (isDetailsShown) |
| 938 toggleSctsDetailsLink.textContent = WebInspector.UIString('Show full d
etails'); |
| 939 else |
| 940 toggleSctsDetailsLink.textContent = WebInspector.UIString('Hide full d
etails'); |
| 941 sctSummaryTable.element().classList.toggle('hidden'); |
| 942 sctTableWrapper.classList.toggle('hidden'); |
| 943 } |
| 944 toggleSctsDetailsLink.addEventListener('click', toggleSctDetailsDisplay, f
alse); |
| 945 |
| 946 var noteSection = this.element.createChild('div', 'origin-view-section'); |
| 947 // TODO(lgarron): Fix the issue and then remove this section. See comment
in SecurityPanel._processRequest(). |
| 948 noteSection.createChild('div').textContent = |
| 949 WebInspector.UIString('The security details above are from the first i
nspected response.'); |
| 950 } else if (originState.securityState !== SecurityAgent.SecurityState.Unknown
) { |
| 951 var notSecureSection = this.element.createChild('div', 'origin-view-sectio
n'); |
| 952 notSecureSection.createChild('div', 'origin-view-section-title').textConte
nt = |
| 953 WebInspector.UIString('Not Secure'); |
| 954 notSecureSection.createChild('div').textContent = |
| 955 WebInspector.UIString('Your connection to this origin is not secure.')
; |
| 956 } else { |
| 957 var noInfoSection = this.element.createChild('div', 'origin-view-section')
; |
| 958 noInfoSection.createChild('div', 'origin-view-section-title').textContent
= |
| 959 WebInspector.UIString('No Security Information'); |
| 960 noInfoSection.createChild('div').textContent = |
| 961 WebInspector.UIString('No security details are available for this orig
in.'); |
| 962 } |
| 963 } |
| 964 |
| 965 /** |
| 966 * @param {!Array<string>} sanList |
| 967 * *return {!Element} |
| 968 */ |
| 969 _createSanDiv(sanList) { |
| 970 var sanDiv = createElement('div'); |
| 971 if (sanList.length === 0) { |
| 972 sanDiv.textContent = WebInspector.UIString('(N/A)'); |
| 973 sanDiv.classList.add('empty-san'); |
| 974 } else { |
| 975 var truncatedNumToShow = 2; |
| 976 var listIsTruncated = sanList.length > truncatedNumToShow + 1; |
| 977 for (var i = 0; i < sanList.length; i++) { |
| 978 var span = sanDiv.createChild('span', 'san-entry'); |
| 979 span.textContent = sanList[i]; |
| 980 if (listIsTruncated && i >= truncatedNumToShow) |
| 981 span.classList.add('truncated-entry'); |
| 982 } |
| 983 if (listIsTruncated) { |
| 984 var truncatedSANToggle = sanDiv.createChild('div', 'link'); |
| 985 truncatedSANToggle.href = ''; |
| 986 |
| 987 function toggleSANTruncation() { |
| 988 if (sanDiv.classList.contains('truncated-san')) { |
| 989 sanDiv.classList.remove('truncated-san'); |
| 990 truncatedSANToggle.textContent = WebInspector.UIString('Show less'); |
| 991 } else { |
| 992 sanDiv.classList.add('truncated-san'); |
| 993 truncatedSANToggle.textContent = WebInspector.UIString('Show more (%
d total)', sanList.length); |
| 994 } |
| 913 } | 995 } |
| 914 | 996 truncatedSANToggle.addEventListener('click', toggleSANTruncation, false)
; |
| 915 var sanDiv = this._createSanDiv(originState.securityDetails.sanList); | 997 toggleSANTruncation(); |
| 916 var validFromString = new Date(1000 * originState.securityDetails.validF
rom).toUTCString(); | 998 } |
| 917 var validUntilString = new Date(1000 * originState.securityDetails.valid
To).toUTCString(); | 999 } |
| 918 | 1000 return sanDiv; |
| 919 table = new WebInspector.SecurityDetailsTable(); | 1001 } |
| 920 certificateSection.appendChild(table.element()); | 1002 |
| 921 table.addRow(WebInspector.UIString("Subject"), originState.securityDetai
ls.subjectName); | 1003 /** |
| 922 table.addRow(WebInspector.UIString("SAN"), sanDiv); | 1004 * @param {!SecurityAgent.SecurityState} newSecurityState |
| 923 table.addRow(WebInspector.UIString("Valid From"), validFromString); | 1005 */ |
| 924 table.addRow(WebInspector.UIString("Valid Until"), validUntilString); | 1006 setSecurityState(newSecurityState) { |
| 925 table.addRow(WebInspector.UIString("Issuer"), originState.securityDetail
s.issuer); | 1007 for (var className of Array.prototype.slice.call(this._originLockIcon.classL
ist)) { |
| 926 table.addRow("", WebInspector.SecurityPanel.createCertificateViewerButto
n2(WebInspector.UIString("Open full certificate details"), origin)); | 1008 if (className.startsWith('security-property-')) |
| 927 | 1009 this._originLockIcon.classList.remove(className); |
| 928 if (!originState.securityDetails.signedCertificateTimestampList.length) | 1010 } |
| 929 return; | 1011 |
| 930 | 1012 this._originLockIcon.classList.add('security-property-' + newSecurityState); |
| 931 // Show summary of SCT(s) of Certificate Transparency. | 1013 } |
| 932 var sctSummaryTable = new WebInspector.SecurityDetailsTable(); | 1014 }; |
| 933 sctSummaryTable.element().classList.add("sct-summary"); | 1015 |
| 934 sctSection.appendChild(sctSummaryTable.element()); | 1016 /** |
| 935 for (var i = 0; i < originState.securityDetails.signedCertificateTimesta
mpList.length; i++) | 1017 * @unrestricted |
| 936 { | 1018 */ |
| 937 var sct = originState.securityDetails.signedCertificateTimestampList
[i]; | 1019 WebInspector.SecurityDetailsTable = class { |
| 938 sctSummaryTable.addRow(WebInspector.UIString("SCT"), sct.logDescript
ion + " (" + sct.origin + ", " + sct.status + ")"); | 1020 constructor() { |
| 939 } | 1021 this._element = createElement('table'); |
| 940 | 1022 this._element.classList.add('details-table'); |
| 941 // Show detailed SCT(s) of Certificate Transparency. | 1023 } |
| 942 var sctTableWrapper = sctSection.createChild("div", "sct-details"); | 1024 |
| 943 sctTableWrapper.classList.add("hidden"); | 1025 /** |
| 944 for (var i = 0; i < originState.securityDetails.signedCertificateTimesta
mpList.length; i++) | 1026 * @return: {!Element} |
| 945 { | 1027 */ |
| 946 var sctTable = new WebInspector.SecurityDetailsTable(); | 1028 element() { |
| 947 sctTableWrapper.appendChild(sctTable.element()); | 1029 return this._element; |
| 948 var sct = originState.securityDetails.signedCertificateTimestampList
[i]; | 1030 } |
| 949 sctTable.addRow(WebInspector.UIString("Log Name"), sct.logDescriptio
n); | 1031 |
| 950 sctTable.addRow(WebInspector.UIString("Log ID"), sct.logId.replace(/
(.{2})/g,"$1 ")); | 1032 /** |
| 951 sctTable.addRow(WebInspector.UIString("Validation Status"), sct.stat
us); | 1033 * @param {string} key |
| 952 sctTable.addRow(WebInspector.UIString("Source"), sct.origin); | 1034 * @param {string|!Node} value |
| 953 sctTable.addRow(WebInspector.UIString("Issued At"), new Date(sct.tim
estamp).toUTCString()); | 1035 */ |
| 954 sctTable.addRow(WebInspector.UIString("Hash Algorithm"), sct.hashAlg
orithm); | 1036 addRow(key, value) { |
| 955 sctTable.addRow(WebInspector.UIString("Signature Algorithm"), sct.si
gnatureAlgorithm); | 1037 var row = this._element.createChild('div', 'details-table-row'); |
| 956 sctTable.addRow(WebInspector.UIString("Signature Data"), sct.signatu
reData.replace(/(.{2})/g,"$1 ")); | 1038 row.createChild('div').textContent = key; |
| 957 } | 1039 |
| 958 | 1040 var valueDiv = row.createChild('div'); |
| 959 // Add link to toggle between displaying of the summary of the SCT(s) an
d the detailed SCT(s). | 1041 if (typeof value === 'string') { |
| 960 var toggleSctsDetailsLink = sctSection.createChild("div", "link"); | 1042 valueDiv.textContent = value; |
| 961 toggleSctsDetailsLink.classList.add("sct-toggle"); | |
| 962 toggleSctsDetailsLink.textContent = WebInspector.UIString("Show full det
ails"); | |
| 963 function toggleSctDetailsDisplay() | |
| 964 { | |
| 965 var isDetailsShown = !sctTableWrapper.classList.contains("hidden"); | |
| 966 if (isDetailsShown) | |
| 967 toggleSctsDetailsLink.textContent = WebInspector.UIString("Show
full details"); | |
| 968 else | |
| 969 toggleSctsDetailsLink.textContent = WebInspector.UIString("Hide
full details"); | |
| 970 sctSummaryTable.element().classList.toggle("hidden"); | |
| 971 sctTableWrapper.classList.toggle("hidden"); | |
| 972 } | |
| 973 toggleSctsDetailsLink.addEventListener("click", toggleSctDetailsDisplay,
false); | |
| 974 | |
| 975 var noteSection = this.element.createChild("div", "origin-view-section")
; | |
| 976 // TODO(lgarron): Fix the issue and then remove this section. See commen
t in SecurityPanel._processRequest(). | |
| 977 noteSection.createChild("div").textContent = WebInspector.UIString("The
security details above are from the first inspected response."); | |
| 978 } else if (originState.securityState !== SecurityAgent.SecurityState.Unknown
) { | |
| 979 var notSecureSection = this.element.createChild("div", "origin-view-sect
ion"); | |
| 980 notSecureSection.createChild("div", "origin-view-section-title").textCon
tent = WebInspector.UIString("Not Secure"); | |
| 981 notSecureSection.createChild("div").textContent = WebInspector.UIString(
"Your connection to this origin is not secure."); | |
| 982 } else { | 1043 } else { |
| 983 var noInfoSection = this.element.createChild("div", "origin-view-section
"); | 1044 valueDiv.appendChild(value); |
| 984 noInfoSection.createChild("div", "origin-view-section-title").textConten
t = WebInspector.UIString("No Security Information"); | 1045 } |
| 985 noInfoSection.createChild("div").textContent = WebInspector.UIString("No
security details are available for this origin."); | 1046 } |
| 986 } | |
| 987 }; | 1047 }; |
| 988 | |
| 989 WebInspector.SecurityOriginView.prototype = { | |
| 990 | |
| 991 /** | |
| 992 * @param {!Array<string>} sanList | |
| 993 * *return {!Element} | |
| 994 */ | |
| 995 _createSanDiv: function(sanList) | |
| 996 { | |
| 997 var sanDiv = createElement("div"); | |
| 998 if (sanList.length === 0) { | |
| 999 sanDiv.textContent = WebInspector.UIString("(N/A)"); | |
| 1000 sanDiv.classList.add("empty-san"); | |
| 1001 } else { | |
| 1002 var truncatedNumToShow = 2; | |
| 1003 var listIsTruncated = sanList.length > truncatedNumToShow + 1; | |
| 1004 for (var i = 0; i < sanList.length; i++) { | |
| 1005 var span = sanDiv.createChild("span", "san-entry"); | |
| 1006 span.textContent = sanList[i]; | |
| 1007 if (listIsTruncated && i >= truncatedNumToShow) | |
| 1008 span.classList.add("truncated-entry"); | |
| 1009 } | |
| 1010 if (listIsTruncated) { | |
| 1011 var truncatedSANToggle = sanDiv.createChild("div", "link"); | |
| 1012 truncatedSANToggle.href = ""; | |
| 1013 | |
| 1014 function toggleSANTruncation() | |
| 1015 { | |
| 1016 if (sanDiv.classList.contains("truncated-san")) { | |
| 1017 sanDiv.classList.remove("truncated-san"); | |
| 1018 truncatedSANToggle.textContent = WebInspector.UIString("
Show less"); | |
| 1019 } else { | |
| 1020 sanDiv.classList.add("truncated-san"); | |
| 1021 truncatedSANToggle.textContent = WebInspector.UIString("
Show more (%d total)", sanList.length); | |
| 1022 } | |
| 1023 } | |
| 1024 truncatedSANToggle.addEventListener("click", toggleSANTruncation
, false); | |
| 1025 toggleSANTruncation(); | |
| 1026 } | |
| 1027 } | |
| 1028 return sanDiv; | |
| 1029 }, | |
| 1030 | |
| 1031 /** | |
| 1032 * @param {!SecurityAgent.SecurityState} newSecurityState | |
| 1033 */ | |
| 1034 setSecurityState: function(newSecurityState) | |
| 1035 { | |
| 1036 for (var className of Array.prototype.slice.call(this._originLockIcon.cl
assList)) { | |
| 1037 if (className.startsWith("security-property-")) | |
| 1038 this._originLockIcon.classList.remove(className); | |
| 1039 } | |
| 1040 | |
| 1041 this._originLockIcon.classList.add("security-property-" + newSecuritySta
te); | |
| 1042 }, | |
| 1043 | |
| 1044 __proto__: WebInspector.VBox.prototype | |
| 1045 }; | |
| 1046 | |
| 1047 /** | |
| 1048 * @constructor | |
| 1049 */ | |
| 1050 WebInspector.SecurityDetailsTable = function() | |
| 1051 { | |
| 1052 this._element = createElement("table"); | |
| 1053 this._element.classList.add("details-table"); | |
| 1054 }; | |
| 1055 | |
| 1056 WebInspector.SecurityDetailsTable.prototype = { | |
| 1057 | |
| 1058 /** | |
| 1059 * @return: {!Element} | |
| 1060 */ | |
| 1061 element: function() | |
| 1062 { | |
| 1063 return this._element; | |
| 1064 }, | |
| 1065 | |
| 1066 /** | |
| 1067 * @param {string} key | |
| 1068 * @param {string|!Node} value | |
| 1069 */ | |
| 1070 addRow: function(key, value) | |
| 1071 { | |
| 1072 var row = this._element.createChild("div", "details-table-row"); | |
| 1073 row.createChild("div").textContent = key; | |
| 1074 | |
| 1075 var valueDiv = row.createChild("div"); | |
| 1076 if (typeof value === "string") { | |
| 1077 valueDiv.textContent = value; | |
| 1078 } else { | |
| 1079 valueDiv.appendChild(value); | |
| 1080 } | |
| 1081 } | |
| 1082 }; | |
| OLD | NEW |