blob: 663248dda1cbf3f3cc4d84b9cabf0f46374650c6 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* HSTS is HTTPS Strict Transport Security: a way for sites to elect to always
* use HTTPS. See http://dev.chromium.org/sts
*
* This UI allows a user to query and update the browser's list of HSTS domains.
* It also allows users to query and update the browser's list of public key
* pins.
*/
var HSTSView = (function() {
'use strict';
// We inherit from DivView.
var superClass = DivView;
/**
* @constructor
*/
function HSTSView() {
assertFirstConstructorCall(HSTSView);
// Call superclass's constructor.
superClass.call(this, HSTSView.MAIN_BOX_ID);
this.addInput_ = $(HSTSView.ADD_INPUT_ID);
this.addStsCheck_ = $(HSTSView.ADD_STS_CHECK_ID);
this.addPkpCheck_ = $(HSTSView.ADD_PKP_CHECK_ID);
this.addPins_ = $(HSTSView.ADD_PINS_ID);
this.deleteInput_ = $(HSTSView.DELETE_INPUT_ID);
this.queryInput_ = $(HSTSView.QUERY_INPUT_ID);
this.queryOutputDiv_ = $(HSTSView.QUERY_OUTPUT_DIV_ID);
var form = $(HSTSView.ADD_FORM_ID);
form.addEventListener('submit', this.onSubmitAdd_.bind(this), false);
form = $(HSTSView.DELETE_FORM_ID);
form.addEventListener('submit', this.onSubmitDelete_.bind(this), false);
form = $(HSTSView.QUERY_FORM_ID);
form.addEventListener('submit', this.onSubmitQuery_.bind(this), false);
g_browser.addHSTSObserver(this);
}
HSTSView.TAB_ID = 'tab-handle-hsts';
HSTSView.TAB_NAME = 'HSTS';
HSTSView.TAB_HASH = '#hsts';
// IDs for special HTML elements in hsts_view.html
HSTSView.MAIN_BOX_ID = 'hsts-view-tab-content';
HSTSView.ADD_INPUT_ID = 'hsts-view-add-input';
HSTSView.ADD_STS_CHECK_ID = 'hsts-view-check-sts-input';
HSTSView.ADD_PKP_CHECK_ID = 'hsts-view-check-pkp-input';
HSTSView.ADD_PINS_ID = 'hsts-view-add-pins';
HSTSView.ADD_FORM_ID = 'hsts-view-add-form';
HSTSView.ADD_SUBMIT_ID = 'hsts-view-add-submit';
HSTSView.DELETE_INPUT_ID = 'hsts-view-delete-input';
HSTSView.DELETE_FORM_ID = 'hsts-view-delete-form';
HSTSView.DELETE_SUBMIT_ID = 'hsts-view-delete-submit';
HSTSView.QUERY_INPUT_ID = 'hsts-view-query-input';
HSTSView.QUERY_OUTPUT_DIV_ID = 'hsts-view-query-output';
HSTSView.QUERY_FORM_ID = 'hsts-view-query-form';
HSTSView.QUERY_SUBMIT_ID = 'hsts-view-query-submit';
cr.addSingletonGetter(HSTSView);
HSTSView.prototype = {
// Inherit the superclass's methods.
__proto__: superClass.prototype,
onSubmitAdd_: function(event) {
g_browser.sendHSTSAdd(this.addInput_.value,
this.addStsCheck_.checked,
this.addPkpCheck_.checked,
this.addPins_.value);
g_browser.sendHSTSQuery(this.addInput_.value);
this.queryInput_.value = this.addInput_.value;
this.addStsCheck_.checked = false;
this.addPkpCheck_.checked = false;
this.addInput_.value = '';
this.addPins_.value = '';
event.preventDefault();
},
onSubmitDelete_: function(event) {
g_browser.sendHSTSDelete(this.deleteInput_.value);
this.deleteInput_.value = '';
event.preventDefault();
},
onSubmitQuery_: function(event) {
g_browser.sendHSTSQuery(this.queryInput_.value);
event.preventDefault();
},
onHSTSQueryResult: function(result) {
if (result.error != undefined) {
this.queryOutputDiv_.innerHTML = '';
var s = addNode(this.queryOutputDiv_, 'span');
s.textContent = result.error;
s.style.color = '#e00';
yellowFade(this.queryOutputDiv_);
return;
}
if (result.result == false) {
this.queryOutputDiv_.innerHTML = '<b>Not found</b>';
yellowFade(this.queryOutputDiv_);
return;
}
this.queryOutputDiv_.innerHTML = '';
var s = addNode(this.queryOutputDiv_, 'span');
s.innerHTML = '<b>Found</b>: mode: ';
var t = addNode(this.queryOutputDiv_, 'tt');
t.textContent = modeToString(result.mode);
addTextNode(this.queryOutputDiv_, ' sts_include_subdomains:');
t = addNode(this.queryOutputDiv_, 'tt');
t.textContent = result.sts_subdomains;
addTextNode(this.queryOutputDiv_, ' pkp_include_subdomains:');
t = addNode(this.queryOutputDiv_, 'tt');
t.textContent = result.pkp_subdomains;
addTextNode(this.queryOutputDiv_, ' domain:');
t = addNode(this.queryOutputDiv_, 'tt');
t.textContent = result.domain;
addTextNode(this.queryOutputDiv_, ' pubkey_hashes:');
t = addNode(this.queryOutputDiv_, 'tt');
// |public_key_hashes| is an old synonym for what is now
// |preloaded_spki_hashes|, which in turn is a legacy synonym for
// |static_spki_hashes|. Look for all three, and also for
// |dynamic_spki_hashes|.
if (typeof result.public_key_hashes === 'undefined')
result.public_key_hashes = '';
if (typeof result.preloaded_spki_hashes === 'undefined')
result.preloaded_spki_hashes = '';
if (typeof result.static_spki_hashes === 'undefined')
result.static_spki_hashes = '';
if (typeof result.dynamic_spki_hashes === 'undefined')
result.dynamic_spki_hashes = '';
var hashes = [];
if (result.public_key_hashes)
hashes.push(result.public_key_hashes);
if (result.preloaded_spki_hashes)
hashes.push(result.preloaded_spki_hashes);
if (result.static_spki_hashes)
hashes.push(result.static_spki_hashes);
if (result.dynamic_spki_hashes)
hashes.push(result.dynamic_spki_hashes);
t.textContent = hashes.join(',');
yellowFade(this.queryOutputDiv_);
}
};
function modeToString(m) {
// These numbers must match those in
// TransportSecurityState::DomainState::UpgradeMode.
if (m == 0) {
return 'STRICT';
} else if (m == 1) {
return 'OPPORTUNISTIC';
} else {
return 'UNKNOWN';
}
}
function yellowFade(element) {
element.style.webkitTransitionProperty = 'background-color';
element.style.webkitTransitionDuration = '0';
element.style.backgroundColor = '#fffccf';
setTimeout(function() {
element.style.webkitTransitionDuration = '1000ms';
element.style.backgroundColor = '#fff';
}, 0);
}
return HSTSView;
})();