// 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.

// Use the <code>chrome.passwordsPrivate</code> API to add or remove password
// data from the settings UI.
namespace passwordsPrivate {
  // Possible reasons why a plaintext password was requested.
  enum PlaintextReason {
    // The user wants to view the password.
    VIEW,
    // The user wants to copy the password.
    COPY,
    // The user wants to edit the password.
    EDIT
  };

  enum ExportProgressStatus {
    // No export was started.
    NOT_STARTED,
    // Data is being written to the destination.
    IN_PROGRESS,
    // Data has been written.
    SUCCEEDED,
    // The user rejected the file selection prompts.
    FAILED_CANCELLED,
    // Writing to the destination failed.
    FAILED_WRITE_FAILED
  };

  enum CompromiseType {
    // If the credentials was leaked by a data breach.
    LEAKED,
    // If the credentials was reused on a phishing site.
    PHISHED,
    // If the credentials was reused on a phishing site and leaked by a data
    // breach.
    PHISHED_AND_LEAKED
  };

  enum PasswordCheckState {
    // idle state, e.g. after successfully running to completion.
    IDLE,
    // Running, following an explicit user action to start the check.
    RUNNING,
    // Canceled, entered when the user explicitly cancels a check.
    CANCELED,
    // Offline, the user is offline.
    OFFLINE,
    // The user is not signed into Chrome.
    SIGNED_OUT,
    // The user does not have any passwords saved.
    NO_PASSWORDS,
    // The user hit the quota limit.
    QUOTA_LIMIT,
    // Any other error state.
    OTHER_ERROR
  };

  dictionary UrlCollection {
    // The fully specified URL of the credential's origin.
    DOMString origin;

    // A human readable version of the URL of the credential's origin.
    DOMString shown;

    // The URL that will be linked to when an entry is clicked.
    DOMString link;
  };

  // Entry used to display a password in the settings UI.
  dictionary PasswordUiEntry {
    // The URL collection corresponding to this saved password entry.
    UrlCollection urls;

    // The username used in conjunction with the saved password.
    DOMString username;

    // Text shown if the password was obtained via a federated identity.
    DOMString? federationText;

    // An index to refer back to a unique password entry record.
    long id;

    // If true, the entry came from the Gaia-account-scoped password store
    // rather than from the profile-scoped one.
    boolean fromAccountStore;
  };

  dictionary ExceptionEntry {
    // The URL collection corresponding to this exception entry.
    UrlCollection urls;

    // An id to refer back to a unique exception entry record.
    long id;

    // If true, the entry came from the Gaia-account-scoped password store
    // rather than from the profile-scoped one.
    boolean fromAccountStore;
  };

  dictionary PasswordExportProgress {
    // The current status of the export task.
    ExportProgressStatus status;

    // If |status| is $ref(ExportProgressStatus.FAILED_WRITE_FAILED), this will
    // be the name of the selected folder to export to.
    DOMString? folderName;
  };

  // Information about a compromised credential and relevant information
  // required for the display in the UI.
  dictionary CompromisedCredential {
    // An id serving as a mapping to a given compromised credential. This
    // identifier will remain stable for a single browser session.
    long id;

    // The formatted origin of the compromised credential. Can be the origin of
    // a website (excluding scheme) or the name of an app.
    DOMString formattedOrigin;

    // The detailed origin of the compromised credential. As opposed to
    // formattedOrigin this also includes the scheme and trivial subdomains like
    // www.
    // For an app this is either the app name or the name of the package, if the
    // former could not be retrieved.
    DOMString detailedOrigin;

    // Indicates whether this credential belongs to an Android app.
    boolean isAndroidCredential;

    // The URL where the compromised password can be changed. Might be not set
    // for Android apps.
    DOMString? changePasswordUrl;

    // The signon realm of the credential.
    DOMString signonRealm;

    // The username of the credential.
    DOMString username;

    // The password of the credential. Initially empty, only set if explicitly
    // requested.
    DOMString? password;

    // The timestamp of when this credential was determined to be compromised.
    // Specified in milliseconds since the UNIX epoch. Intended to be passed to
    // the JavaScript Date() constructor.
    double compromiseTime;

    // The elapsed time since this credential was determined to be compromised.
    // This is passed as an already formatted string, since JavaScript lacks the
    // required formatting APIs. Example: "5 minutes ago"
    DOMString elapsedTimeSinceCompromise;

    // The type of the credentials that was compromised.
    CompromiseType compromiseType;
  };

  // Object describing the current state of the password check. The check could
  // be in any of the above described states.
  dictionary PasswordCheckStatus {
    // The state of the password check.
    PasswordCheckState state;

    // How many passwords have already been processed. Populated if and only if
    // the password check is currently running.
    long? alreadyProcessed;

    // How many passwords are remaining in the queue. Populated if and only if
    // the password check is currently running.
    long? remainingInQueue;

    // The elapsed time since the last full password check was performed. This
    // is passed as a string, since JavaScript lacks the required formatting
    // APIs. If no check has been performed yet this is not set.
    DOMString? elapsedTimeSinceLastCheck;
  };

  callback PlaintextPasswordCallback = void(DOMString password);
  callback PasswordListCallback = void(PasswordUiEntry[] entries);
  callback ExceptionListCallback = void(ExceptionEntry[] exceptions);
  callback ExportProgressStatusCallback = void(ExportProgressStatus status);
  callback VoidCallback = void();
  callback OptInCallback = void(boolean optedIn);
  callback CompromisedCredentialsCallback =
      void(CompromisedCredential[] compromisedCredential);
  callback GetPlaintextCompromisedPasswordCallback =
      void(CompromisedCredential credential);
  callback PasswordCheckStatusCallback = void(PasswordCheckStatus status);

  interface Functions {
    // Function that logs that the Passwords page was accessed from the Chrome
    // Settings WebUI.
    static void recordPasswordsPageAccessInSettings();

    // Changes the username and password corresponding to |id|.
    // |id|: The id for the password entry being updated.
    // |new_username|: The new username.
    // |new_password|: The new password.
    static void changeSavedPassword(long id, DOMString new_username,
                                    optional DOMString new_password);

    // Removes the saved password corresponding to |id|. If no saved password
    // for this pair exists, this function is a no-op. |id|: The id for the
    // password entry being removed.
    static void removeSavedPassword(long id);

    // Removes the saved password exception corresponding to |exceptionUrl|. If
    // no exception with this URL exists, this function is a no-op.
    // |id|: The id for the exception url entry being removed.
    static void removePasswordException(long id);

    // Undoes the last removal of a saved password or exception.
    static void undoRemoveSavedPasswordOrException();

    // Returns the plaintext password corresponding to |id|. Note that on
    // some operating systems, this call may result in an OS-level
    // reauthentication. Once the password has been fetched, it will be returned
    // via |callback|.
    // |id|: The id for the password entry being being retrieved.
    // |reason|: The reason why the plaintext password is requested.
    // |callback|: The callback that gets invoked with the retrieved password.
    static void requestPlaintextPassword(long id, PlaintextReason reason,
                                         PlaintextPasswordCallback callback);

    // Returns the list of saved passwords.
    // |callback|: Called with the list of saved passwords.
    static void getSavedPasswordList(PasswordListCallback callback);

    // Returns the list of password exceptions.
    // |callback|: Called with the list of password exceptions.
    static void getPasswordExceptionList(ExceptionListCallback callback);

    // Triggers the Password Manager password import functionality.
    static void importPasswords();

    // Triggers the Password Manager password export functionality. Completion
    // Will be signaled by the onPasswordsFileExportProgress event.
    // |callback| will be called when the request is started or rejected. If
    // rejected <code>chrome.runtime.lastError</code> will be set to
    // 'in-progress' or 'reauth-failed'.
    static void exportPasswords(VoidCallback callback);

    // Requests the export progress status. This is the same as the last value
    // seen on the onPasswordsFileExportProgress event. This function is useful
    // for checking if an export has already been initiated from an older tab,
    // where we might have missed the original event.
    static void requestExportProgressStatus(
        ExportProgressStatusCallback callback);

    // Stops exporting passwords and cleans up any passwords, which were already
    // written to the filesystem.
    static void cancelExportPasswords();

    // Requests the account-storage opt-in state of the current user.
    static void isOptedInForAccountStorage(OptInCallback callback);

    // Triggers the opt-in or opt-out flow for the account storage.
    static void optInForAccountStorage(boolean optIn);

    // Requests the latest compromised credentials.
    static void getCompromisedCredentials(
        CompromisedCredentialsCallback callback);

    // Requests the plaintext password for |credential|. |callback| gets invoked
    // with the same |credential|, whose |password| field will be set.
    // |credential|: The compromised credential whose password is being
    // retrieved.
    // |reason|: The reason why the plaintext password is requested.
    // |callback|: The callback that gets invoked with the result.
    static void getPlaintextCompromisedPassword(
        CompromisedCredential credential, PlaintextReason reason,
        GetPlaintextCompromisedPasswordCallback callback);

    // Requests to change the password of |credential| to |new_password|.
    // Invokes |callback| or raises an error depending on whether the operation
    // succeeded.
    // |credential|: The credential whose password should be changed.
    // |new_password|: The new password.
    // |callback|: The callback that gets invoked in the end.
    static void changeCompromisedCredential(CompromisedCredential credential,
                                            DOMString new_password,
                                            optional VoidCallback callback);

    // Requests to remove |credential| from the password store.
    // Invokes |callback| on completion.
    static void removeCompromisedCredential(CompromisedCredential credential,
                                            optional VoidCallback callback);

    // Starts a check for compromised passwords. Invokes |callback| on
    // completion.
    static void startPasswordCheck(optional VoidCallback callback);
    // Stops checking for compromised passwords. Invokes |callback| on
    // completion.
    static void stopPasswordCheck(optional VoidCallback callback);

    // Returns the current status of the check via |callback|.
    static void getPasswordCheckStatus(PasswordCheckStatusCallback callback);
  };

  interface Events {
    // Fired when the saved passwords list has changed, meaning that an entry
    // has been added or removed.
    // |entries|: The updated list of password entries.
    static void onSavedPasswordsListChanged(PasswordUiEntry[] entries);

    // Fired when the password exceptions list has changed, meaning that an
    // entry has been added or removed.
    // |exceptions|: The updated list of password exceptions.
    static void onPasswordExceptionsListChanged(ExceptionEntry[] exceptions);

    // Fired when the status of the export has changed.
    // |status|: The progress status and an optional UI message.
    static void onPasswordsFileExportProgress(PasswordExportProgress status);

    // Fired when the opt-in state for the account-scoped storage has changed.
    // |optedIn|: The new opt-in state.
    static void onAccountStorageOptInStateChanged(boolean optedIn);

    // Fired when the compromised credentials changed.
    // |compromisedCredentials|: The updated compromised credentials.
    static void onCompromisedCredentialsChanged(
        CompromisedCredential[] compromisedCredentials);

    // Fired when the status of the password check changes.
    // |status|: The updated status of the password check.
    static void onPasswordCheckStatusChanged(PasswordCheckStatus status);
  };
};
