| Index: chrome/browser/resources/gaia_auth/saml_injected.js
|
| diff --git a/chrome/browser/resources/gaia_auth/saml_injected.js b/chrome/browser/resources/gaia_auth/saml_injected.js
|
| deleted file mode 100644
|
| index f79c62649293a13ab79900937ea9c284d611445d..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/resources/gaia_auth/saml_injected.js
|
| +++ /dev/null
|
| @@ -1,218 +0,0 @@
|
| -// Copyright 2013 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.
|
| -
|
| -/**
|
| - * @fileoverview
|
| - * Script to be injected into SAML provider pages, serving three main purposes:
|
| - * 1. Signal hosting extension that an external page is loaded so that the
|
| - * UI around it should be changed accordingly;
|
| - * 2. Provide an API via which the SAML provider can pass user credentials to
|
| - * Chrome OS, allowing the password to be used for encrypting user data and
|
| - * offline login.
|
| - * 3. Scrape password fields, making the password available to Chrome OS even if
|
| - * the SAML provider does not support the credential passing API.
|
| - */
|
| -
|
| -(function() {
|
| - function APICallForwarder() {
|
| - }
|
| -
|
| - /**
|
| - * The credential passing API is used by sending messages to the SAML page's
|
| - * |window| object. This class forwards API calls from the SAML page to a
|
| - * background script and API responses from the background script to the SAML
|
| - * page. Communication with the background script occurs via a |Channel|.
|
| - */
|
| - APICallForwarder.prototype = {
|
| - // Channel to which API calls are forwarded.
|
| - channel_: null,
|
| -
|
| - /**
|
| - * Initialize the API call forwarder.
|
| - * @param {!Object} channel Channel to which API calls should be forwarded.
|
| - */
|
| - init: function(channel) {
|
| - this.channel_ = channel;
|
| - this.channel_.registerMessage('apiResponse',
|
| - this.onAPIResponse_.bind(this));
|
| -
|
| - window.addEventListener('message', this.onMessage_.bind(this));
|
| - },
|
| -
|
| - onMessage_: function(event) {
|
| - if (event.source != window ||
|
| - typeof event.data != 'object' ||
|
| - !event.data.hasOwnProperty('type') ||
|
| - event.data.type != 'gaia_saml_api') {
|
| - return;
|
| - }
|
| - // Forward API calls to the background script.
|
| - this.channel_.send({name: 'apiCall', call: event.data.call});
|
| - },
|
| -
|
| - onAPIResponse_: function(msg) {
|
| - // Forward API responses to the SAML page.
|
| - window.postMessage({type: 'gaia_saml_api_reply', response: msg.response},
|
| - '/');
|
| - }
|
| - };
|
| -
|
| - /**
|
| - * A class to scrape password from type=password input elements under a given
|
| - * docRoot and send them back via a Channel.
|
| - */
|
| - function PasswordInputScraper() {
|
| - }
|
| -
|
| - PasswordInputScraper.prototype = {
|
| - // URL of the page.
|
| - pageURL_: null,
|
| -
|
| - // Channel to send back changed password.
|
| - channel_: null,
|
| -
|
| - // An array to hold password fields.
|
| - passwordFields_: null,
|
| -
|
| - // An array to hold cached password values.
|
| - passwordValues_: null,
|
| -
|
| - // A MutationObserver to watch for dynamic password field creation.
|
| - passwordFieldsObserver: null,
|
| -
|
| - /**
|
| - * Initialize the scraper with given channel and docRoot. Note that the
|
| - * scanning for password fields happens inside the function and does not
|
| - * handle DOM tree changes after the call returns.
|
| - * @param {!Object} channel The channel to send back password.
|
| - * @param {!string} pageURL URL of the page.
|
| - * @param {!HTMLElement} docRoot The root element of the DOM tree that
|
| - * contains the password fields of interest.
|
| - */
|
| - init: function(channel, pageURL, docRoot) {
|
| - this.pageURL_ = pageURL;
|
| - this.channel_ = channel;
|
| -
|
| - this.passwordFields_ = [];
|
| - this.passwordValues_ = [];
|
| -
|
| - this.findAndTrackChildren(docRoot);
|
| -
|
| - this.passwordFieldsObserver = new MutationObserver(function(mutations) {
|
| - mutations.forEach(function(mutation) {
|
| - Array.prototype.forEach.call(
|
| - mutation.addedNodes,
|
| - function(addedNode) {
|
| - if (addedNode.nodeType != Node.ELEMENT_NODE)
|
| - return;
|
| -
|
| - if (addedNode.matches('input[type=password]')) {
|
| - this.trackPasswordField(addedNode);
|
| - } else {
|
| - this.findAndTrackChildren(addedNode);
|
| - }
|
| - }.bind(this));
|
| - }.bind(this));
|
| - }.bind(this));
|
| - this.passwordFieldsObserver.observe(docRoot,
|
| - {subtree: true, childList: true});
|
| - },
|
| -
|
| - /**
|
| - * Find and track password fields that are descendants of the given element.
|
| - * @param {!HTMLElement} element The parent element to search from.
|
| - */
|
| - findAndTrackChildren: function(element) {
|
| - Array.prototype.forEach.call(
|
| - element.querySelectorAll('input[type=password]'), function(field) {
|
| - this.trackPasswordField(field);
|
| - }.bind(this));
|
| - },
|
| -
|
| - /**
|
| - * Start tracking value changes of the given password field if it is
|
| - * not being tracked yet.
|
| - * @param {!HTMLInputElement} passworField The password field to track.
|
| - */
|
| - trackPasswordField: function(passwordField) {
|
| - var existing = this.passwordFields_.filter(function(element) {
|
| - return element === passwordField;
|
| - });
|
| - if (existing.length != 0)
|
| - return;
|
| -
|
| - var index = this.passwordFields_.length;
|
| - var fieldId = passwordField.id || passwordField.name || '';
|
| - passwordField.addEventListener(
|
| - 'input', this.onPasswordChanged_.bind(this, index, fieldId));
|
| - this.passwordFields_.push(passwordField);
|
| - this.passwordValues_.push(passwordField.value);
|
| - },
|
| -
|
| - /**
|
| - * Check if the password field at |index| has changed. If so, sends back
|
| - * the updated value.
|
| - */
|
| - maybeSendUpdatedPassword: function(index, fieldId) {
|
| - var newValue = this.passwordFields_[index].value;
|
| - if (newValue == this.passwordValues_[index])
|
| - return;
|
| -
|
| - this.passwordValues_[index] = newValue;
|
| -
|
| - // Use an invalid char for URL as delimiter to concatenate page url,
|
| - // password field index and id to construct a unique ID for the password
|
| - // field.
|
| - var passwordId = this.pageURL_.split('#')[0].split('?')[0] +
|
| - '|' + index + '|' + fieldId;
|
| - this.channel_.send({
|
| - name: 'updatePassword',
|
| - id: passwordId,
|
| - password: newValue
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Handles 'change' event in the scraped password fields.
|
| - * @param {number} index The index of the password fields in
|
| - * |passwordFields_|.
|
| - * @param {string} fieldId The id or name of the password field or blank.
|
| - */
|
| - onPasswordChanged_: function(index, fieldId) {
|
| - this.maybeSendUpdatedPassword(index, fieldId);
|
| - }
|
| - };
|
| -
|
| - function onGetSAMLFlag(channel, isSAMLPage) {
|
| - if (!isSAMLPage)
|
| - return;
|
| - var pageURL = window.location.href;
|
| -
|
| - channel.send({name: 'pageLoaded', url: pageURL});
|
| -
|
| - var initPasswordScraper = function() {
|
| - var passwordScraper = new PasswordInputScraper();
|
| - passwordScraper.init(channel, pageURL, document.documentElement);
|
| - };
|
| -
|
| - if (document.readyState == 'loading') {
|
| - window.addEventListener('readystatechange', function listener(event) {
|
| - if (document.readyState == 'loading')
|
| - return;
|
| - initPasswordScraper();
|
| - window.removeEventListener(event.type, listener, true);
|
| - }, true);
|
| - } else {
|
| - initPasswordScraper();
|
| - }
|
| - }
|
| -
|
| - var channel = Channel.create();
|
| - channel.connect('injected');
|
| - channel.sendWithCallback({name: 'getSAMLFlag'},
|
| - onGetSAMLFlag.bind(undefined, channel));
|
| -
|
| - var apiCallForwarder = new APICallForwarder();
|
| - apiCallForwarder.init(channel);
|
| -})();
|
|
|