1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5/* This is a JavaScript module (JSM) to be imported via
6 * Components.utils.import() and acts as a singleton. Only the following
7 * listed symbols will exposed on import, and only when and where imported.
8 */
9
10var EXPORTED_SYMBOLS = ["Password", "DumpPasswords"];
11
12const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
13const { Logger } = ChromeUtils.import("resource://tps/logger.jsm");
14
15var nsLoginInfo = new Components.Constructor(
16  "@mozilla.org/login-manager/loginInfo;1",
17  Ci.nsILoginInfo,
18  "init"
19);
20
21var DumpPasswords = function TPS__Passwords__DumpPasswords() {
22  let logins = Services.logins.getAllLogins();
23  Logger.logInfo("\ndumping password list\n", true);
24  for (var i = 0; i < logins.length; i++) {
25    Logger.logInfo(
26      "* origin=" +
27        logins[i].origin +
28        ", formActionOrigin=" +
29        logins[i].formActionOrigin +
30        ", realm=" +
31        logins[i].httpRealm +
32        ", password=" +
33        logins[i].password +
34        ", passwordField=" +
35        logins[i].passwordField +
36        ", username=" +
37        logins[i].username +
38        ", usernameField=" +
39        logins[i].usernameField,
40      true
41    );
42  }
43  Logger.logInfo("\n\nend password list\n", true);
44};
45
46/**
47 * PasswordProps object; holds password properties.
48 */
49function PasswordProps(props) {
50  this.hostname = null;
51  this.submitURL = null;
52  this.realm = null;
53  this.username = "";
54  this.password = "";
55  this.usernameField = "";
56  this.passwordField = "";
57  this.delete = false;
58
59  for (var prop in props) {
60    if (prop in this) {
61      this[prop] = props[prop];
62    }
63  }
64}
65
66/**
67 * Password class constructor. Initializes instance properties.
68 */
69function Password(props) {
70  this.props = new PasswordProps(props);
71  if ("changes" in props) {
72    this.updateProps = new PasswordProps(props);
73    for (var prop in props.changes) {
74      if (prop in this.updateProps) {
75        this.updateProps[prop] = props.changes[prop];
76      }
77    }
78  } else {
79    this.updateProps = null;
80  }
81}
82
83/**
84 * Password instance methods.
85 */
86Password.prototype = {
87  /**
88   * Create
89   *
90   * Adds a password entry to the login manager for the password
91   * represented by this object's properties. Throws on error.
92   *
93   * @return the new login guid
94   */
95  Create() {
96    let login = new nsLoginInfo(
97      this.props.hostname,
98      this.props.submitURL,
99      this.props.realm,
100      this.props.username,
101      this.props.password,
102      this.props.usernameField,
103      this.props.passwordField
104    );
105    Services.logins.addLogin(login);
106    login.QueryInterface(Ci.nsILoginMetaInfo);
107    return login.guid;
108  },
109
110  /**
111   * Find
112   *
113   * Finds a password entry in the login manager, for the password
114   * represented by this object's properties.
115   *
116   * @return the guid of the password if found, otherwise -1
117   */
118  Find() {
119    let logins = Services.logins.findLogins(
120      this.props.hostname,
121      this.props.submitURL,
122      this.props.realm
123    );
124    for (var i = 0; i < logins.length; i++) {
125      if (
126        logins[i].username == this.props.username &&
127        logins[i].password == this.props.password &&
128        logins[i].usernameField == this.props.usernameField &&
129        logins[i].passwordField == this.props.passwordField
130      ) {
131        logins[i].QueryInterface(Ci.nsILoginMetaInfo);
132        return logins[i].guid;
133      }
134    }
135    return -1;
136  },
137
138  /**
139   * Update
140   *
141   * Updates an existing password entry in the login manager with
142   * new properties. Throws on error.  The 'old' properties are this
143   * object's properties, the 'new' properties are the properties in
144   * this object's 'updateProps' object.
145   *
146   * @return nothing
147   */
148  Update() {
149    let oldlogin = new nsLoginInfo(
150      this.props.hostname,
151      this.props.submitURL,
152      this.props.realm,
153      this.props.username,
154      this.props.password,
155      this.props.usernameField,
156      this.props.passwordField
157    );
158    let newlogin = new nsLoginInfo(
159      this.updateProps.hostname,
160      this.updateProps.submitURL,
161      this.updateProps.realm,
162      this.updateProps.username,
163      this.updateProps.password,
164      this.updateProps.usernameField,
165      this.updateProps.passwordField
166    );
167    Services.logins.modifyLogin(oldlogin, newlogin);
168  },
169
170  /**
171   * Remove
172   *
173   * Removes an entry from the login manager for a password which
174   * matches this object's properties. Throws on error.
175   *
176   * @return nothing
177   */
178  Remove() {
179    let login = new nsLoginInfo(
180      this.props.hostname,
181      this.props.submitURL,
182      this.props.realm,
183      this.props.username,
184      this.props.password,
185      this.props.usernameField,
186      this.props.passwordField
187    );
188    Services.logins.removeLogin(login);
189  },
190};
191