|
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 "use strict"; |
|
6 |
|
7 module.metadata = { |
|
8 "stability": "unstable" |
|
9 }; |
|
10 |
|
11 const { Cc, Ci, CC } = require("chrome"); |
|
12 const { uri: ADDON_URI } = require("../self"); |
|
13 const loginManager = Cc["@mozilla.org/login-manager;1"]. |
|
14 getService(Ci.nsILoginManager); |
|
15 const { URL: parseURL } = require("../url"); |
|
16 const LoginInfo = CC("@mozilla.org/login-manager/loginInfo;1", |
|
17 "nsILoginInfo", "init"); |
|
18 |
|
19 function filterMatchingLogins(loginInfo) |
|
20 Object.keys(this).every(function(key) loginInfo[key] === this[key], this); |
|
21 |
|
22 /** |
|
23 * Removes `user`, `password` and `path` fields from the given `url` if it's |
|
24 * 'http', 'https' or 'ftp'. All other URLs are returned unchanged. |
|
25 * @example |
|
26 * http://user:pass@www.site.com/foo/?bar=baz#bang -> http://www.site.com |
|
27 */ |
|
28 function normalizeURL(url) { |
|
29 let { scheme, host, port } = parseURL(url); |
|
30 // We normalize URL only if it's `http`, `https` or `ftp`. All other types of |
|
31 // URLs (`resource`, `chrome`, etc..) should not be normalized as they are |
|
32 // used with add-on associated credentials path. |
|
33 return scheme === "http" || scheme === "https" || scheme === "ftp" ? |
|
34 scheme + "://" + (host || "") + (port ? ":" + port : "") : |
|
35 url |
|
36 } |
|
37 |
|
38 function Login(options) { |
|
39 let login = Object.create(Login.prototype); |
|
40 Object.keys(options || {}).forEach(function(key) { |
|
41 if (key === 'url') |
|
42 login.hostname = normalizeURL(options.url); |
|
43 else if (key === 'formSubmitURL') |
|
44 login.formSubmitURL = options.formSubmitURL ? |
|
45 normalizeURL(options.formSubmitURL) : null; |
|
46 else if (key === 'realm') |
|
47 login.httpRealm = options.realm; |
|
48 else |
|
49 login[key] = options[key]; |
|
50 }); |
|
51 |
|
52 return login; |
|
53 } |
|
54 Login.prototype.toJSON = function toJSON() { |
|
55 return { |
|
56 url: this.hostname || ADDON_URI, |
|
57 realm: this.httpRealm || null, |
|
58 formSubmitURL: this.formSubmitURL || null, |
|
59 username: this.username || null, |
|
60 password: this.password || null, |
|
61 usernameField: this.usernameField || '', |
|
62 passwordField: this.passwordField || '', |
|
63 } |
|
64 }; |
|
65 Login.prototype.toLoginInfo = function toLoginInfo() { |
|
66 let { url, realm, formSubmitURL, username, password, usernameField, |
|
67 passwordField } = this.toJSON(); |
|
68 |
|
69 return new LoginInfo(url, formSubmitURL, realm, username, password, |
|
70 usernameField, passwordField); |
|
71 }; |
|
72 |
|
73 function loginToJSON(value) Login(value).toJSON() |
|
74 |
|
75 /** |
|
76 * Returns array of `nsILoginInfo` objects that are stored in the login manager |
|
77 * and have all the properties with matching values as a given `options` object. |
|
78 * @param {Object} options |
|
79 * @returns {nsILoginInfo[]} |
|
80 */ |
|
81 exports.search = function search(options) { |
|
82 return loginManager.getAllLogins() |
|
83 .filter(filterMatchingLogins, Login(options)) |
|
84 .map(loginToJSON); |
|
85 }; |
|
86 |
|
87 /** |
|
88 * Stores login info created from the given `options` to the applications |
|
89 * built-in login management system. |
|
90 * @param {Object} options. |
|
91 */ |
|
92 exports.store = function store(options) { |
|
93 loginManager.addLogin(Login(options).toLoginInfo()); |
|
94 }; |
|
95 |
|
96 /** |
|
97 * Removes login info from the applications built-in login management system. |
|
98 * _Please note: When removing a login info the specified properties must |
|
99 * exactly match to the one that is already stored or exception will be thrown._ |
|
100 * @param {Object} options. |
|
101 */ |
|
102 exports.remove = function remove(options) { |
|
103 loginManager.removeLogin(Login(options).toLoginInfo()); |
|
104 }; |