summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formActionOrigin.js
blob: d630ed0e078caf50e2e384f1b98670c3ad9e0604 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

/**
 * Tests the legacy case of a login store containing entries that have an empty
 * string in the formActionOrigin field.
 *
 * In normal conditions, for the purpose of login autocomplete, HTML forms are
 * identified using both the prePath of the URI on which they are located, and
 * the prePath of the URI where the data will be submitted.  This is represented
 * by the origin and formActionOrigin properties of the stored nsILoginInfo.
 *
 * When a new login for use in forms is saved (after the user replies to the
 * password prompt), it is always stored with both the origin and the
 * formActionOrigin (that will be equal to the origin when the form has no
 * "action" attribute).
 *
 * When the same form is displayed again, the password is autocompleted.  If
 * there is another form on the same site that submits to a different site, it
 * is considered a different form, so the password is not autocompleted, but a
 * new password can be stored for the other form.
 *
 * However, the login database might contain data for an nsILoginInfo that has a
 * valid origin, but an empty formActionOrigin.  This means that the login
 * applies to all forms on the site, regardless of where they submit data to.
 *
 * A site can have at most one such login, and in case it is present, then it is
 * not possible to store separate logins for forms on the same site that submit
 * data to different sites.
 *
 * The only way to have such condition is to be using logins that were initially
 * saved by a very old version of the browser, or because of data manually added
 * by an extension in an old version.
 */

"use strict";

// Tests

/**
 * Adds a login with an empty formActionOrigin, then it verifies that no other
 * form logins can be added for the same host.
 */
add_task(async function test_addLogin_wildcard() {
  let loginInfo = TestData.formLogin({
    origin: "http://any.example.com",
    formActionOrigin: "",
  });
  await Services.logins.addLoginAsync(loginInfo);

  // Normal form logins cannot be added anymore.
  loginInfo = TestData.formLogin({ origin: "http://any.example.com" });
  await Assert.rejects(
    Services.logins.addLoginAsync(loginInfo),
    /already exists/
  );

  // Authentication logins can still be added.
  loginInfo = TestData.authLogin({ origin: "http://any.example.com" });
  await Services.logins.addLoginAsync(loginInfo);

  // Form logins can be added for other hosts.
  loginInfo = TestData.formLogin({ origin: "http://other.example.com" });
  await Services.logins.addLoginAsync(loginInfo);
});

/**
 * Verifies that searchLogins and countLogins include all logins
 * that have an empty formActionOrigin in the store, even when a formActionOrigin is
 * specified.
 */
add_task(function test_search_all_wildcard() {
  // Search a given formActionOrigin on any host.
  let matchData = newPropertyBag({
    formActionOrigin: "http://www.example.com",
  });
  Assert.equal(Services.logins.searchLogins(matchData).length, 2);

  Assert.equal(
    Services.logins.countLogins("", "http://www.example.com", null),
    2
  );

  // Restrict the search to one host.
  matchData.setProperty("origin", "http://any.example.com");
  Assert.equal(Services.logins.searchLogins(matchData).length, 1);

  Assert.equal(
    Services.logins.countLogins(
      "http://any.example.com",
      "http://www.example.com",
      null
    ),
    1
  );
});

/**
 * Verifies that specifying an empty string for formActionOrigin in searchLogins
 * includes only logins that have an empty formActionOrigin in the store.
 */
add_task(function test_searchLogins_wildcard() {
  let logins = Services.logins.searchLogins(
    newPropertyBag({ formActionOrigin: "" })
  );

  let loginInfo = TestData.formLogin({
    origin: "http://any.example.com",
    formActionOrigin: "",
  });
  LoginTestUtils.assertLoginListsEqual(logins, [loginInfo]);
});