summaryrefslogtreecommitdiffstats
path: root/toolkit/components/aboutwebauthn/tests/browser/browser_aboutwebauthn_pin.js
blob: 0849b194a46329281d86ab2c5948df18d58ad06f (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const ABOUT_URL = "about:webauthn";

var doc, tab;

async function send_authinfo_and_open_pin_section(ops) {
  reset_about_page(doc);
  send_auth_info_and_check_categories(doc, ops);

  ["credentials-tab-button", "bio-enrollments-tab-button"].forEach(
    button_id => {
      let button = doc.getElementById(button_id);
      is(
        button.style.display,
        "none",
        button_id + " in the sidebar not hidden"
      );
    }
  );

  if (ops.clientPin !== null) {
    let pin_tab_button = doc.getElementById("pin-tab-button");
    // Check if PIN section is visible
    isnot(
      pin_tab_button.style.display,
      "none",
      "PIN button in the sidebar not visible"
    );

    // Click the section and wait for it to open
    let pin_section = doc.getElementById("set-change-pin-section");
    pin_tab_button.click();
    isnot(pin_section.style.display, "none", "PIN section not visible");
    is(
      pin_tab_button.getAttribute("selected"),
      "true",
      "PIN section button not selected"
    );
  }
}

add_setup(async function () {
  info("Starting about:webauthn");
  tab = await BrowserTestUtils.openNewForegroundTab({
    gBrowser,
    opening: "about:webauthn",
    waitForLoad: true,
  });

  doc = tab.linkedBrowser.contentDocument;
});

registerCleanupFunction(async function () {
  // Close tab.
  await BrowserTestUtils.removeTab(tab);
});

add_task(async function pin_not_supported() {
  // Not setting clientPIN at all should lead to not showing it in the sidebar
  send_authinfo_and_open_pin_section({ uv: true, clientPin: null });
  // Check if PIN section is invisible
  let pin_tab_button = doc.getElementById("pin-tab-button");
  is(pin_tab_button.style.display, "none", "PIN button in the sidebar visible");
});

add_task(async function pin_already_set() {
  send_authinfo_and_open_pin_section({ clientPin: true });

  let set_pin_button = doc.getElementById("set-pin-button");
  is(set_pin_button.style.display, "none", "Set PIN button visible");

  let change_pin_button = doc.getElementById("change-pin-button");
  isnot(
    change_pin_button.style.display,
    "none",
    "Change PIN button not visible"
  );

  let current_pin_div = doc.getElementById("current-pin-div");
  is(current_pin_div.hidden, false, "Current PIN field not visible");

  // Test that the button is only active if both inputs are set the same
  let new_pin = doc.getElementById("new-pin");
  let new_pin_repeat = doc.getElementById("new-pin-repeat");
  let current_pin = doc.getElementById("current-pin");

  set_text(new_pin, "abcdefg");
  is(change_pin_button.disabled, true, "Change PIN button not disabled");
  set_text(new_pin_repeat, "abcde");
  is(change_pin_button.disabled, true, "Change PIN button not disabled");
  set_text(new_pin_repeat, "abcdefg");
  is(change_pin_button.disabled, true, "Change PIN button not disabled");
  set_text(current_pin, "1234567");
  is(change_pin_button.disabled, false, "Change PIN button disabled");
});

add_task(async function pin_not_yet_set() {
  send_authinfo_and_open_pin_section({ clientPin: false });

  let set_pin_button = doc.getElementById("set-pin-button");
  isnot(set_pin_button.style.display, "none", "Set PIN button not visible");

  let change_pin_button = doc.getElementById("change-pin-button");
  is(change_pin_button.style.display, "none", "Change PIN button visible");

  let current_pin_div = doc.getElementById("current-pin-div");
  is(current_pin_div.hidden, true, "Current PIN field visible");

  // Test that the button is only active if both inputs are set the same
  let new_pin = doc.getElementById("new-pin");
  let new_pin_repeat = doc.getElementById("new-pin-repeat");

  set_text(new_pin, "abcdefg");
  is(set_pin_button.disabled, true, "Set PIN button not disabled");
  set_text(new_pin_repeat, "abcde");
  is(set_pin_button.disabled, true, "Set PIN button not disabled");
  set_text(new_pin_repeat, "abcdefg");
  is(set_pin_button.disabled, false, "Set PIN button disabled");
});

add_task(async function pin_switch_back_and_forth() {
  // This will click the PIN section button
  send_authinfo_and_open_pin_section({ clientPin: false });

  let pin_tab_button = doc.getElementById("pin-tab-button");
  let pin_section = doc.getElementById("set-change-pin-section");
  let info_tab_button = doc.getElementById("info-tab-button");
  let info_section = doc.getElementById("token-info-section");

  // a11y-tree is racy here, so we have to wait a tick for it to get up to date
  await TestUtils.waitForTick();
  // Now click the "info"-button and verify the correct buttons are highlighted
  info_tab_button.click();
  // await info_promise;
  isnot(info_section.style.display, "none", "info section not visible");
  is(
    info_tab_button.getAttribute("selected"),
    "true",
    "Info tab button not selected"
  );
  isnot(
    pin_tab_button.getAttribute("selected"),
    "true",
    "PIN tab button selected"
  );

  // Click back to the PIN section
  pin_tab_button.click();
  isnot(pin_section.style.display, "none", "PIN section not visible");
  is(
    pin_tab_button.getAttribute("selected"),
    "true",
    "PIN tab button not selected"
  );
  isnot(
    info_tab_button.getAttribute("selected"),
    "true",
    "Info button selected"
  );
});

add_task(async function invalid_pin() {
  send_authinfo_and_open_pin_section({ clientPin: true });
  let pin_tab_button = doc.getElementById("pin-tab-button");
  // Click the section and wait for it to open
  pin_tab_button.click();
  is(
    pin_tab_button.getAttribute("selected"),
    "true",
    "PIN section button not selected"
  );

  let change_pin_button = doc.getElementById("change-pin-button");

  // Test that the button is only active if both inputs are set the same
  let new_pin = doc.getElementById("new-pin");
  let new_pin_repeat = doc.getElementById("new-pin-repeat");
  let current_pin = doc.getElementById("current-pin");

  // Needed to activate change_pin_button
  set_text(new_pin, "abcdefg");
  set_text(new_pin_repeat, "abcdefg");
  set_text(current_pin, "1234567");

  // This should silently error out since we have no authenticator
  change_pin_button.click();

  // Now we fake a response from the authenticator, saying the PIN was invalid
  let pin_required = doc.getElementById("pin-required-section");
  let msg = JSON.stringify({ type: "pin-required" });
  Services.obs.notifyObservers(null, "about-webauthn-prompt", msg);
  isnot(pin_required.style.display, "none", "PIN required dialog not visible");

  let info_tab_button = doc.getElementById("info-tab-button");
  is(
    info_tab_button.classList.contains("disabled-category"),
    true,
    "Sidebar not disabled"
  );

  let pin_field = doc.getElementById("pin-required");
  let send_pin_button = doc.getElementById("send-pin-button");

  set_text(pin_field, "654321");
  send_pin_button.click();

  is(
    pin_required.style.display,
    "none",
    "PIN required dialog did not disappear"
  );
  let pin_section = doc.getElementById("set-change-pin-section");
  isnot(pin_section.style.display, "none", "PIN section did not reappear");
});