blob: edc17230273e0ac14874233d86b6db182ea29173 [file] [log] [blame]
<!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>