Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: ios/chrome/browser/passwords/resources/credential_manager.js

Issue 1456983002: Move JS-related password manager code upstream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Indent fixed, capitalisation fixed, typo fixed Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/passwords/resources/credential_manager.js
diff --git a/ios/chrome/browser/passwords/resources/credential_manager.js b/ios/chrome/browser/passwords/resources/credential_manager.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e2e84079be137d63d21d310c74443f285f0f8e1
--- /dev/null
+++ b/ios/chrome/browser/passwords/resources/credential_manager.js
@@ -0,0 +1,574 @@
+// Copyright 2015 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 JavaScript implementation of the credential management API
+ * defined at http://w3c.github.io/webappsec/specs/credentialmanagement.
+ * This is a minimal implementation that sends data to the app side to
+ * integrate with the password manager. When loaded, installs the API onto
+ * the window.navigator object.
+ */
+
+// Namespace for all credential management stuff. __gCrWeb must have already
+// been defined.
+__gCrWeb['credentialManager'] = {
+ /**
+ * The next ID for forwarding a call from JS to the App and tracking its
+ * associated Promise resolvers and rejecters.
+ * @private {number}
+ */
+ nextId_: 0,
+
+ /**
+ * Tracks navigator.credentials Promise resolvers.
+ * @type {!Object<number, function(?Credential|undefined)>}
+ * @private
+ */
+ resolvers_: {},
+
+ /**
+ * Tracks navigator.credentials Promise rejecters.
+ * @type {!Object<number, function(?Error)>}
+ * @private
+ */
+ rejecters_: {}
+};
+
+
+/** @enum {string} */
+__gCrWeb.credentialManager.CredentialType = {
+ CREDENTIAL: 'Credential',
+ PASSWORD_CREDENTIAL: 'PasswordCredential',
+ FEDERATED_CREDENTIAL: 'FederatedCredential',
+ PENDING_CREDENTIAL: 'PendingCredential'
+};
+
+
+/** @typedef {
+ * type: __gCrWeb.credentialManager.CredentialType,
+ * id: string,
+ * name: (string|undefined),
+ * avatarURL: (string|undefined),
+ * federation: (string|undefined)
+ * }
+ */
+__gCrWeb.credentialManager.SerializedCredential;
+
+
+/**
+ * Creates and returns a Promise whose resolver and rejecter functions are
+ * stored with the associated |requestId|. They can be accessed by calling
+ * |resolve| or |reject| on __gCrWeb['credentialManager'] with that ID.
+ * @param {number} requestId An identifier to track the resolver and rejecter
+ * associated with the returned Promise.
+ * @return {!Promise<?Credential|undefined>} A new Promise.
+ * @private
+ */
+__gCrWeb['credentialManager'].createPromise_ = function(requestId) {
+ return new Promise(function(resolve, reject) {
+ __gCrWeb['credentialManager'].resolvers_[requestId] = resolve;
+ __gCrWeb['credentialManager'].rejecters_[requestId] = reject;
+ });
+};
+
+
+/**
+ * Deletes the resolver and rejecter of the Promise associated with |requestId|.
+ * @param {number} requestId The identifier of the Promise.
+ * @private
+ */
+__gCrWeb['credentialManager'].removePromise_ = function(requestId) {
+ delete __gCrWeb['credentialManager'].rejecters_[requestId];
+ delete __gCrWeb['credentialManager'].resolvers_[requestId];
+};
+
+
+/**
+ * Parses |credentialData| into a Credential object.
+ * @param {!__gCrWeb.credentialManager.SerializedCredential} credentialData A
+ * simple object representation of a Credential like might be obtained from
+ * Credential.prototype.serialize.
+ * @return {?Credential} A Credential object, or null if parsing was
+ * unsuccessful.
+ * @private
+ */
+__gCrWeb['credentialManager'].parseCredential_ = function(credentialData) {
+ var CredentialType = __gCrWeb.credentialManager.CredentialType;
+ switch (credentialData['type']) {
+ case CredentialType.CREDENTIAL:
+ return Credential.parse(credentialData);
+ case CredentialType.PASSWORD_CREDENTIAL:
+ return PasswordCredential.parse(credentialData);
+ case CredentialType.FEDERATED_CREDENTIAL:
+ return FederatedCredential.parse(credentialData);
+ case CredentialType.PENDING_CREDENTIAL:
+ return PendingCredential.parse(credentialData);
+ default:
+ return null;
+ }
+};
+
+
+/**
+ * Resolves the Promise that was created with the given |requestId| with a
+ * Credential object parsed from |opt_credentialData| and removes that promise
+ * from the global state. Future attempts to resolve or reject the Promise will
+ * fail.
+ * @param {number} requestId The identifier of the Promise to resolve.
+ * @param {Object=} opt_credentialData An object describing a credential. If
+ * provided, this parameter will be parsed into the appropriate Credential
+ * type.
+ * @return {boolean} Indicates whether the Promise was successfully resolved.
+ */
+__gCrWeb['credentialManager'].resolve = function(requestId,
+ opt_credentialData) {
+ var resolver = __gCrWeb['credentialManager'].resolvers_[requestId];
+ if (!resolver) {
+ return false;
+ }
+ if (opt_credentialData) {
+ var credential = null;
+ try {
+ credential =
+ __gCrWeb['credentialManager'].parseCredential_(opt_credentialData);
+ } catch (e) {
+ // Failed to parse |opt_credentialData|. The app side sent bad data.
+ return false;
+ }
+ resolver(credential);
+ } else {
+ resolver();
+ }
+ __gCrWeb['credentialManager'].removePromise_(requestId);
+ return true;
+};
+
+
+/**
+ * Rejects the Promise that was created with the given |requestId| and cleans up
+ * that Promise.
+ * @param {number} requestId The identifier of the Promise to resolve.
+ * @param {string} errorType The type of the Error to pass to the rejecter
+ * function. If not recognized, a standard JavaScript Error will be used.
+ * @param {string} message A human-readable description of the error.
+ * @return {boolean} Indicates whether the Promise was successfully rejected.
+ */
+__gCrWeb['credentialManager'].reject = function(requestId, errorType, message) {
+ var rejecter = __gCrWeb['credentialManager'].rejecters_[requestId];
+ if (!rejecter) {
+ return false;
+ }
+ var error = null;
+ if (errorType == 'SecurityError') {
+ error = new SecurityError(message);
+ } else if (errorType == 'InvalidStateError') {
+ error = new InvalidStateError(message);
+ } else {
+ error = new Error(message);
+ }
+ rejecter(error);
+ __gCrWeb['credentialManager'].removePromise_(requestId);
+ return true;
+};
+
+
+/**
+ * Sends a command representing |method| of navigator.credentials to the app
+ * side with the given |opt_options|.
+ * @param {string} command The name of the command being sent.
+ * @param {Object=} opt_options A dictionary of additional properties to forward
+ * to the app.
+ * @return {!Promise<?Credential|undefined>} A promise for the result.
+ * @private
+ */
+__gCrWeb['credentialManager'].invokeOnHost_ = function(command, opt_options) {
+ var requestId = __gCrWeb['credentialManager'].nextId_++;
+ var message = {
+ 'command': command,
+ 'requestId': requestId
+ };
+ if (opt_options) {
+ Object.keys(opt_options).forEach(function(key) {
+ message[key] = opt_options[key];
+ });
+ }
+ __gCrWeb.message.invokeOnHost(message);
+ return __gCrWeb['credentialManager'].createPromise_(requestId);
+};
+
+
+
+/**
+ * Creates a new SecurityError to represent failures caused by violating
+ * security requirements of the API.
+ * @param {string} message A human-readable message describing this error.
+ * @extends {Error}
+ * @constructor
+ */
+function SecurityError(message) {
+ Error.call(this, message);
+ this.name = 'SecurityError';
+ this.message = message;
+}
+SecurityError.prototype = Object.create(Error.prototype);
+SecurityError.prototype.constructor = SecurityError;
+
+
+
+/**
+ * Creates a new InvalidStateError to represent failures caused by inconsistent
+ * internal state.
+ * @param {string} message A human-readable message describing this error.
+ * @extends {Error}
+ * @constructor
+ */
+function InvalidStateError(message) {
+ Error.call(this, message);
+ this.name = 'InvalidStateError';
+ this.message = message;
+}
+InvalidStateError.prototype = Object.create(Error.prototype);
+InvalidStateError.prototype.constructor = InvalidStateError;
+
+
+
+/**
+ * Creates a new Credential object. For more information, see
+ * https://w3c.github.io/webappsec/specs/credentialmanagement/#credential
+ * @param {string} id The credential’s identifier. This might be a username or
+ * email address, for instance.
+ * @param {string=} opt_name A name associated with the credential, intended as
+ * a human-understandable public name.
+ * @param {string=} opt_avatarUrl A URL pointing to an avatar image for the
+ * user. This URL MUST NOT be an a priori insecure URL.
+ * @constructor
+ */
+function Credential(id, opt_name, opt_avatarUrl) {
+ if (id === null || id === undefined)
+ throw new TypeError('id must be provided');
+ /**
+ * The credential's identifier. Read-only.
+ * @type {string}
+ */
+ this.id;
+ Object.defineProperty(this, 'id', {
+ configurable: false,
+ enumerable: true,
+ value: id,
+ writable: false
+ });
+ /**
+ * A human-understandable public name associated with the credential.
+ * Read-only.
+ * @type {string}
+ */
+ this.name;
+ Object.defineProperty(this, 'name', {
+ configurable: false,
+ enumerable: true,
+ value: opt_name || '',
+ writable: false
+ });
+ /**
+ * A URL pointing to an avatar image for the user. Read-only.
+ * NOTE: This property name deviates from the Google JavaScript style guide
+ * in order to meet the public API specification.
+ * @type {string}
+ */
+ this.avatarURL;
+ Object.defineProperty(this, 'avatarURL', {
+ configurable: false,
+ enumerable: true,
+ value: opt_avatarUrl || '',
+ writable: false
+ });
+}
+
+
+/**
+ * Returns a simple object representation of this credential suitable for
+ * sending to the app side.
+ * @return {__gCrWeb.credentialManager.SerializedCredential} An object
+ * representing this credential.
+ */
+Credential.prototype.serialize = function() {
+ var serialized = {
+ 'type': this.constructor.name,
+ 'id': this.id,
+ 'name': this.name
+ };
+ if (this.avatarURL && this.avatarURL.length > 0)
+ serialized['avatarURL'] = this.avatarURL;
+ return serialized;
+};
+
+
+/**
+ * Parses |credentialData| into a Credential object.
+ * @param {!__gCrWeb.credentialManager.SerializedCredential} credentialData A
+ * simple object representation of a Credential like might be obtained from
+ * Credential.prototype.serialize.
+ * @return {Credential} A Credential object.
+ */
+Credential.parse = function(credentialData) {
+ return new Credential(credentialData['id'],
+ credentialData['name'],
+ credentialData['avatarURL']);
+};
+
+
+
+/**
+ * Creates a new PasswordCredential object. For more information, see
+ * https://w3c.github.io/webappsec/specs/credentialmanagement/#localcredential
+ * @param {string} id The credential’s identifier. This might be a username or
+ * email address, for instance.
+ * @param {string} password The credential's password.
+ * @param {string=} opt_name A name associated with the credential, intended as
+ * a human-understandable public name.
+ * @param {string=} opt_avatarUrl A URL pointing to an avatar image for the
+ * user. This URL MUST NOT be an a priori insecure URL.
+ * @constructor
+ * @extends {Credential}
+ */
+function PasswordCredential(id, password, opt_name, opt_avatarUrl) {
+ if (password === null || password === undefined)
+ throw new TypeError('password must be provided');
+ Credential.call(this, id, opt_name, opt_avatarUrl);
+ var formData = new FormData();
+ formData.append('username', id);
+ formData.append('password', password);
+ /**
+ * A FormData object, containing two entries: one named username, the other
+ * named password. Read-only.
+ * @type {FormData}
+ */
+ this.formData;
+ Object.defineProperty(this, 'formData', {
+ configurable: false,
+ enumerable: true,
+ value: formData,
+ writable: false
+ });
+ /**
+ * The credential's password.
+ * @type {string}
+ * @private
+ */
+ this.password_;
+ Object.defineProperty(this, 'password_', {
+ configurable: false,
+ enumerable: false,
+ value: password,
+ writable: false
+ });
+}
+PasswordCredential.prototype = Object.create(Credential.prototype);
+PasswordCredential.prototype.constructor = PasswordCredential;
+
+
+/**
+ * Returns a simple object representation of this credential suitable for
+ * sending to the app side.
+ * @return {__gCrWeb.credentialManager.SerializedCredential} An object
+ * representing this credential.
+ */
+PasswordCredential.prototype.serialize = function() {
+ var obj = Credential.prototype.serialize.call(this);
+ obj.password = this.password_;
+ return obj;
+};
+
+
+/**
+ * Parses |credentialData| into a PasswordCredential object.
+ * @param {!__gCrWeb.credentialManager.SerializedCredential} credentialData A
+ * simple object representation of a PasswordCredential like might be
+ * obtained from PasswordCredential.prototype.serialize.
+ * @return {PasswordCredential} A PasswordCredential object.
+ */
+PasswordCredential.parse = function(credentialData) {
+ return new PasswordCredential(credentialData['id'],
+ credentialData['password'],
+ credentialData['name'],
+ credentialData['avatarURL']);
+};
+
+
+
+/**
+ * Creates a new FederatedCredential object. For more information, see
+ * https://w3c.github.io/webappsec/specs/credentialmanagement/#federatedcredential
+ * @param {string} id The credential’s identifier. This might be a username or
+ * email address, for instance.
+ * @param {string} federation The credential’s federation. For details regarding
+ * valid formats, see https://w3c.github.io/webappsec/specs/credentialmanagement/#identifying-federations
+ * @param {string=} opt_name A name associated with the credential, intended as
+ * a human-understandable public name.
+ * @param {string=} opt_avatarUrl A URL pointing to an avatar image for the
+ * user. This URL MUST NOT be an a priori insecure URL.
+ * @constructor
+ * @extends {Credential}
+ */
+function FederatedCredential(id, federation, opt_name, opt_avatarUrl) {
+ if (federation === null || federation === undefined)
+ throw new TypeError('federation must be provided');
+ Credential.call(this, id, opt_name, opt_avatarUrl);
+ /**
+ * The credential’s federation. Read-only.
+ * @type {string}
+ */
+ this.federation;
+ Object.defineProperty(this, 'federation', {
+ configurable: false,
+ enumerable: true,
+ value: federation,
+ writable: false
+ });
+}
+FederatedCredential.prototype = Object.create(Credential.prototype);
+FederatedCredential.prototype.constructor = FederatedCredential;
+
+
+/**
+ * Returns a simple object representation of this credential suitable for
+ * sending to the app side.
+ * @return {__gCrWeb.credentialManager.SerializedCredential} An object
+ * representing this credential.
+ */
+FederatedCredential.prototype.serialize = function() {
+ var obj = Credential.prototype.serialize.call(this);
+ obj.federation = this.federation;
+ return obj;
+};
+
+
+/**
+ * Parses |credentialData| into a FederatedCredential object.
+ * @param {!__gCrWeb.credentialManager.SerializedCredential} credentialData A
+ * simple object representation of a FederatedCredential like might be
+ * obtained from FederatedCredential.prototype.serialize.
+ * @return {!FederatedCredential} A FederatedCredential object.
+ */
+FederatedCredential.parse = function(credentialData) {
+ return new FederatedCredential(credentialData['id'],
+ credentialData['federation'],
+ credentialData['name'],
+ credentialData['avatarURL']);
+};
+
+
+
+/**
+ * Creates a new PendingCredential object. For more information, see
+ * https://w3c.github.io/webappsec/specs/credentialmanagement/#pendingcredential
+ * @param {string} id The credential’s identifier. This might be a username or
+ * email address, for instance.
+ * @param {string=} opt_name A name associated with the credential, intended as
+ * a human-understandable public name.
+ * @param {string=} opt_avatarUrl A URL pointing to an avatar image for the
+ * user. This URL MUST NOT be an a priori insecure URL.
+ * @constructor
+ * @extends {Credential}
+ */
+function PendingCredential(id, opt_name, opt_avatarUrl) {
+ Credential.call(this, id, opt_name, opt_avatarUrl);
+}
+PendingCredential.prototype = Object.create(Credential.prototype);
+PendingCredential.prototype.constructor = PendingCredential;
+
+
+/**
+ * Parses |credentialData| into a PendingCredential object.
+ * @param {!__gCrWeb.credentialManager.SerializedCredential} credentialData A
+ * simple object representation of a PendingCredential like might be
+ * obtained from PendingCredential.prototype.serialize.
+ * @return {!Credential} A PendingCredential object.
+ */
+PendingCredential.parse = function(credentialData) {
+ return new PendingCredential(credentialData['id'],
+ credentialData['name'],
+ credentialData['avatarURL']);
+};
+
+
+
+/**
+ * Implements the public Credential Management API. For more information, see
+ * http://w3c.github.io/webappsec/specs/credentialmanagement/#interfaces-credential-manager
+ * @constructor
+ */
+function CredentialsContainer() {
+}
+
+
+/**
+ * Requests a credential from the credential manager.
+ * @param {{suppressUI: boolean, federations: Array<string>}=} opt_options An
+ * optional dictionary of parameters for the request. If |suppressUI| is
+ * true, the returned promise will only be resolved with a credential if
+ * this is possible without user interaction; otherwise, the returned
+ * promise will be resolved with |undefined|. |federations| specifies a
+ * list of acceptable federation providers. For more information, see
+ * https://w3c.github.io/webappsec/specs/credentialmanagement/#interfaces-request-options
+ * @return {!Promise<?Credential|undefined>} A promise for retrieving the result
+ * of the request.
+ */
+CredentialsContainer.prototype.request = function(opt_options) {
+ var options = {
+ 'suppressUI': !!opt_options && !!opt_options['suppressUI'],
+ 'federations': (!!opt_options && opt_options['federations']) || []
+ };
+ return __gCrWeb['credentialManager'].invokeOnHost_(
+ 'navigator.credentials.request', options);
+};
+
+
+/**
+ * Notifies the browser that the user has successfully signed in.
+ * @param {Credential=} opt_successfulCredential The credential that was used
+ * to sign in.
+ * @return {!Promise<?Credential|undefined>} A promise to wait for
+ * acknowledgement from the browser.
+ */
+CredentialsContainer.prototype.notifySignedIn = function(
+ opt_successfulCredential) {
+ var options = opt_successfulCredential && {
+ 'credential': opt_successfulCredential.serialize()
+ };
+ return __gCrWeb['credentialManager'].invokeOnHost_(
+ 'navigator.credentials.notifySignedIn', options);
+};
+
+
+/**
+ * Notifies the browser that the user failed to sign in.
+ * @param {Credential=} opt_failedCredential The credential that failed to
+ * sign in.
+ * @return {!Promise<?Credential|undefined>} A promise to wait for
+ * acknowledgement from the browser.
+ */
+CredentialsContainer.prototype.notifyFailedSignIn = function(
+ opt_failedCredential) {
+ var options = opt_failedCredential && {
+ 'credential': opt_failedCredential.serialize()
+ };
+ return __gCrWeb['credentialManager'].invokeOnHost_(
+ 'navigator.credentials.notifyFailedSignIn', options);
+};
+
+
+/**
+ * Notifies the browser that the user signed out.
+ * @return {!Promise<?Credential|undefined>} A promise to wait for
+ * acknowledgement from the browser.
+ */
+CredentialsContainer.prototype.notifySignedOut = function() {
+ return __gCrWeb['credentialManager'].invokeOnHost_(
+ 'navigator.credentials.notifySignedOut');
+};
+
+
+// Install the public interface.
+window.navigator.credentials = new CredentialsContainer();
« no previous file with comments | « ios/chrome/browser/passwords/js_password_manager.mm ('k') | ios/chrome/browser/passwords/resources/password_controller.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698