| <!DOCTYPE html> |
| <title>Credential Manager: PasswordCredential basics.</title> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <body> |
| <input type=hidden id=thing value=sekrit> |
| <script> |
| add_completion_callback(() => { |
| if (window.testRunner) |
| testRunner.clearMockCredentialManagerResponse(); |
| }); |
| |
| var c = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| promise_test(_ => { |
| var r = new Request('/', { credentials: c, body: 'this is a body', method: 'POST' }); |
| return r.text().then(t => assert_equals(t, "")); |
| }, "Body ignored in presence of a PasswordCredential"); |
| |
| promise_test(_ => { |
| var r = new Request('/', { credentials: 'include', body: 'this is a body', method: 'POST' }); |
| return r.text().then(t => assert_equals(t, "this is a body")); |
| }, "Body present if 'credentials' is not a PasswordCredential"); |
| |
| promise_test(_ => { |
| var r = new Request('/', { credentials: c, method: 'POST' }); |
| var clone = r.clone(); |
| assert_equals(r.credentials, "password"); |
| assert_equals(clone.credentials, "password"); |
| return Promise.all([ |
| r.text().then(t => assert_equals(t, "")), |
| clone.text().then(t => assert_equals(t, "")) |
| ]); |
| }, "Creating/cloning a 'Request' does not expose the credential."); |
| |
| test(_ => { |
| assert_throws(new TypeError(), _ => new Request("https://cross-origin.example.test/", { credentials: c, method: 'POST' })); |
| assert_throws(new TypeError(), _ => new Request("/", { credentials: c, method: 'GET' })); |
| assert_throws(new TypeError(), _ => new Request("/", { credentials: c, method: 'HEAD' })); |
| assert_throws(new TypeError(), _ => new Request("/", { credentials: 'password', method: 'POST' })); |
| assert_throws(new TypeError(), _ => new Request("/", { credentials: 'password', method: 'GET' })); |
| assert_throws(new TypeError(), _ => new Request("/", { credentials: 'password', body: "Body", method: 'GET' })); |
| }, "Creating a 'Request' throws in various ways."); |
| |
| promise_test(function() { |
| return fetch("./resources/echo-post.php", { credentials: c, method: "POST" }) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }); |
| }, "Simple Fetch"); |
| |
| promise_test(function() { |
| document.cookie = "a=1"; |
| document.cookie = "b=2"; |
| return fetch("./resources/echo-cookies.php", { credentials: c, method: "POST" }) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.a, '1'); |
| assert_equals(j.b, '2'); |
| }) |
| .then(_ => { |
| document.cookie = "a=1; max-age=0"; |
| document.cookie = "b=2; max-age=0"; |
| }); |
| }, "Simple Fetch"); |
| |
| promise_test(function() { |
| var r1 = new Request('./resources/echo-post.php', { credentials: c, method: "POST" }); |
| var r2 = r1.clone(); |
| return fetch(r1) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }) |
| .then(_ => fetch(r2)) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }); |
| }, "Fetch with cloned Request"); |
| |
| promise_test(function() { |
| var r1 = new Request('./resources/echo-post.php', { credentials: c, method: "POST" }); |
| var r2 = new Request(r1); |
| return fetch(r1) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }) |
| .then(_ => fetch(r2)) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }); |
| }, "Fetch with copied Request"); |
| |
| promise_test(function() { |
| var r1 = new Request('./resources/echo-post.php', { credentials: c, method: "POST" }); |
| var r2 = new Request(r1, { credentials: 'same-origin' }); |
| return fetch(r1) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }) |
| .then(_ => fetch(r2)) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, undefined); |
| assert_equals(j.password, undefined); |
| }); |
| }, "Fetch with overridden 'credentials'"); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| credential.idName = "notUsername"; |
| credential.passwordName = "notPassword"; |
| |
| return fetch("./resources/echo-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.json() |
| }) |
| .then(function (j) { |
| assert_equals(j.username, undefined); |
| assert_equals(j.password, undefined); |
| assert_equals(j.notUsername, 'id'); |
| assert_equals(j.notPassword, 'pencil'); |
| }); |
| }, "'idName' and 'passwordName'"); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| var fd = new FormData(); |
| credential.additionalData = fd; |
| |
| return fetch("./resources/echo-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.json(); |
| }) |
| .then(function (j) { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }); |
| }, "'additionalData': Empty FormData has no effect."); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| var fd = new FormData(); |
| fd.append("excitingData", "exciting value"); |
| fd.append("csrf", "[randomness]"); |
| credential.additionalData = fd; |
| |
| return fetch("./resources/echo-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.json(); |
| }) |
| .then(function (j) { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| assert_equals(j.excitingData, 'exciting value'); |
| assert_equals(j.csrf, '[randomness]'); |
| }); |
| }, "'additionalData': FormData properties are properly injected."); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| credential.additionalData = new FormData(); |
| credential.additionalData.append("excitingData", "exciting value"); |
| credential.additionalData.append("csrf", "[randomness]"); |
| |
| return fetch("./resources/echo-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.json(); |
| }) |
| .then(function (j) { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| assert_equals(j.excitingData, 'exciting value'); |
| assert_equals(j.csrf, '[randomness]'); |
| }); |
| }, "'additionalData': FormData properties are properly injected after assignment."); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| var fd = new FormData(); |
| fd.append("username", "foo"); |
| fd.append("password", "bar"); |
| credential.additionalData = fd; |
| |
| // Use post-echo.cgi since PHP doesn't give us the raw data of a POST's |
| // body if it's multipart/form-data. |
| return fetch("/xmlhttprequest/resources/post-echo.cgi", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.text(); |
| }) |
| .then(function (t) { |
| // Match "CRLF *OCTET CRLF". See RFC 2046 for the multipart |
| // grammar. |
| assert_false( |
| /\r\nfoo\r\n/.test(t), |
| "POST data should not contain the overridden value foo."); |
| assert_false( |
| /\r\nbar\r\n/.test(t), |
| "POST data should not contain the overridden value bar."); |
| }); |
| }, "'additionalData': FormData properties are properly overridden."); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| var params = new URLSearchParams(); |
| credential.additionalData = params; |
| |
| return fetch("./resources/echo-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.json(); |
| }) |
| .then(function (j) { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| }); |
| }, "'additionalData': Empty URLSearchParams has no effect."); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| var params = new URLSearchParams(); |
| params.append("excitingData", "exciting value"); |
| params.append("csrf", "[randomness]"); |
| credential.additionalData = params; |
| |
| return fetch("./resources/echo-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.json(); |
| }) |
| .then(function (j) { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil'); |
| assert_equals(j.excitingData, 'exciting value'); |
| assert_equals(j.csrf, '[randomness]'); |
| }); |
| }, "'additionalData': URLSearchParams properties are properly injected."); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| var params = new URLSearchParams(); |
| params.append("username", "foo"); |
| params.append("password", "bar"); |
| credential.additionalData = params; |
| |
| return fetch("./resources/echo-raw-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.text(); |
| }) |
| .then(function (t) { |
| assert_equals(t, 'username=id&password=pencil'); |
| }); |
| }, "'additionalData': URLSearchParams properties are properly overridden."); |
| |
| promise_test(function() { |
| var credential = new PasswordCredential({ |
| id: 'id', |
| password: 'pencil', |
| name: 'name', |
| iconURL: 'https://example.com/icon.png' |
| }); |
| |
| var params = new URLSearchParams(); |
| params.append("a", "1"); |
| params.append("a", "2"); |
| params.append("a", "3"); |
| credential.additionalData = params; |
| |
| return fetch("./resources/echo-raw-post.php", { credentials: credential, method: "POST" }) |
| .then(function (r) { |
| return r.text(); |
| }) |
| .then(function (t) { |
| assert_equals(t, 'a=1&a=2&a=3&username=id&password=pencil'); |
| }); |
| }, "'additionalData': URLSearchParams properties are properly injected (ordering matters)."); |
| |
| promise_test(_ => { |
| var id = "id"; |
| var name = "name"; |
| var icon = "http://example.com/"; |
| var password = "pencil"; |
| |
| if (window.testRunner) |
| testRunner.setMockCredentialManagerResponse(id, name, icon, password); |
| |
| return navigator.credentials.get({ password: true }) |
| .then(c => { |
| return fetch("./resources/echo-post.php", { credentials: c, method: "POST" }) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil') |
| }); |
| }); |
| }, 'fetch() after get()'); |
| |
| promise_test(_ => { |
| var id = "id"; |
| var name = "name"; |
| var icon = "http://example.com/"; |
| var password = "pencil"; |
| |
| if (window.testRunner) |
| testRunner.setMockCredentialManagerResponse(id, name, icon, password); |
| |
| return navigator.credentials.get({ password: true }) |
| .then(c => { |
| var fd = new FormData(); |
| fd.append('csrf_token', 'sekrit'); |
| c.additionalData = fd; |
| |
| return fetch("./resources/echo-post.php", { credentials: c, method: "POST" }) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil') |
| assert_equals(j.csrf_token, 'sekrit') |
| }); |
| }); |
| }, 'fetch() after get() with additionalData'); |
| |
| promise_test(_ => { |
| var id = "id"; |
| var name = "name"; |
| var icon = "http://example.com/"; |
| var password = "pencil"; |
| |
| if (window.testRunner) |
| testRunner.setMockCredentialManagerResponse(id, name, icon, password); |
| |
| return navigator.credentials.get({ password: true }) |
| .then(c => { |
| var fd = new FormData(); |
| fd.append('csrf_token', document.querySelector('#thing').value); |
| c.additionalData = fd; |
| |
| return fetch("./resources/echo-post.php", { credentials: c, method: "POST" }) |
| .then(resp => resp.json()) |
| .then(j => { |
| assert_equals(j.username, 'id'); |
| assert_equals(j.password, 'pencil') |
| assert_equals(j.csrf_token, 'sekrit') |
| }); |
| }); |
| }, 'fetch() after get() with additionalData from DOM'); |
| </script> |