blob: 68938a99c1aec3396ff7ddb316c49162c68a8f19 [file] [log] [blame]
<!doctype html>
<title>Credential Manager: get() basics.</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script type="module">
import {SmsStatus} from '/gen/third_party/blink/public/mojom/sms/webotp_service.mojom.m.js';
import {AuthenticatorStatus} from '/gen/third_party/blink/public/mojom/webauthn/authenticator.mojom.m.js';
import {MockAuthenticator, MockCredentialManager, MockWebOTPService} from './resources/mock-navigator-credentials.js';
import {assertValidGetCredentialResponse, CABLE_AUTHENTICATION, CABLE_REGISTRATION, deepCopy, GET_CREDENTIAL_OPTIONS, RAW_ID} from './resources/test-inputs.js';
if (document.location.host != "subdomain.example.test:8443") {
document.location = "https://subdomain.example.test:8443/credentialmanager/credentialscontainer-get-basics.html";
promise_test(_ => new Promise(_ => {}), "Stall tests on the wrong host.");
}
const mockAuthenticator = new MockAuthenticator;
const mockCredentialManager = new MockCredentialManager;
const mockWebOTPService = new MockWebOTPService;
add_completion_callback(() => {
mockCredentialManager.reset();
mockWebOTPService.reset();
});
promise_test(_ => {
return navigator.credentials.get().then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with no argument.");
promise_test(_ => {
return navigator.credentials.get({}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get({}).");
promise_test(_ => {
return navigator.credentials.get({
federated: {
providers: [ 'https://example.com/' ]
}
}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with a valid options including FederatedCredentialRequestOptions.");
promise_test(_ => {
return navigator.credentials.get({
password: true,
unmediated: true
}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with a valid options including password and unmediated.");
promise_test(_ => {
return navigator.credentials.get({
federated: {
providers: [ 'https://example.com/' ]
},
unmediated: true
}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with a valid options including federated and unmediated.");
promise_test(_ => {
return navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://example.com/' ]
},
unmediated: true
}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with a valid options including federated, password and unmediated.");
promise_test(_ => {
return navigator.credentials.get({
unmediated: true
}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with a valid options including unmediated.");
promise_test(_ => {
return navigator.credentials.get({
mediation: "silent"
}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with a valid options including mediation.");
promise_test(_ => {
return navigator.credentials.get({
notValid: 'yay!'
}).then(r => {
assert_equals(r, null);
});
}, "navigator.credentials.get() with an options including an unknown attribute.");
promise_test(_ => {
var id = "id";
var password = "pencil";
var name = "name";
var icon = "http://example.com/";
mockCredentialManager.setResponse(id, password, name, icon);
return navigator.credentials.get({
password: true
}).then(r => {
assert_equals(r.id, id, "id");
assert_equals(r.password, password, "password");
assert_equals(r.name, name, "name");
assert_equals(r.iconURL, icon, "icon");
});
}, "Verify that the mock returns the values we give it.");
promise_test(_ => {
mockAuthenticator.setRawId(RAW_ID);
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
return navigator.credentials.get({publicKey : GET_CREDENTIAL_OPTIONS}).then(r => {
assertValidGetCredentialResponse(r);
});
}, "Verify that mockAuthenticator returns the values we give it.");
promise_test(_ => {
var otp = "ABC123";
mockWebOTPService.setOtp(otp);
mockWebOTPService.setStatus(SmsStatus.kSuccess);
return navigator.credentials.get({otp: {transport: ["sms"]}}).then(r => {
assert_equals(r.type, "otp", "type");
assert_equals(r.id, "", "id");
assert_equals(r.code, otp, "code");
});
}, "Verify that mockWebOTPService returns the values we give it.");
promise_test(t => {
mockWebOTPService.setStatus(SmsStatus.kCancelled);
return promise_rejects_dom(t, "AbortError",
navigator.credentials.get({otp: {transport: ["sms"]}}));
}, "Verify that cancelled status returned by mock is properly handled.");
promise_test(t => {
mockWebOTPService.setStatus(SmsStatus.kAborted);
return promise_rejects_dom(t, "AbortError",
navigator.credentials.get({otp: {transport: ["sms"]}}));
}, "Verify that abort status returned by mock is properly handled.");
promise_test(t => {
mockWebOTPService.setStatus(SmsStatus.kUnhandledRequest);
return promise_rejects_dom(t, "InvalidStateError",
navigator.credentials.get({otp: {transport: ["sms"]}}));
}, "Verify that unhandled request status returned by mock is properly handled.");
promise_test(t => {
mockWebOTPService.setStatus(SmsStatus.kTimeout);
return promise_rejects_dom(t, "InvalidStateError",
navigator.credentials.get({otp: {transport: ["sms"]}}));
}, "Verify that timeout status returned by mock is properly handled.");
promise_test(t => {
mockWebOTPService.setStatus(SmsStatus.kBackendNotAvailable);
return promise_rejects_dom(t, "InvalidStateError",
navigator.credentials.get({otp: {transport: ["sms"]}}));
}, "Verify that backend unavailable status returned by mock is properly handled.");
promise_test(t => {
mockWebOTPService.setStatus(SmsStatus.kTimeout);
return promise_rejects_dom(t, "NotSupportedError",
navigator.credentials.get({otp: {transport: []}}));
}, "Verify that invalid transport is properly handled");
promise_test(t => {
mockAuthenticator.setAuthenticatorStatus(AuthenticatorStatus.PENDING_REQUEST);
return promise_rejects_dom(t, "InvalidStateError",
navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that pending request error returned by mock is properly handled.");
promise_test(function (t) {
mockAuthenticator.setAuthenticatorStatus(AuthenticatorStatus.UNKNOWN_ERROR);
return promise_rejects_dom(t, "NotReadableError",
navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that unknown error returned by mock is properly handled.");
promise_test(t => {
mockAuthenticator.setAuthenticatorStatus(
AuthenticatorStatus.NOT_ALLOWED_ERROR);
return promise_rejects_dom(t, "NotAllowedError",
navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that not allowed error returned by mock is properly handled.");
promise_test(t => {
mockAuthenticator.setAuthenticatorStatus(
AuthenticatorStatus.USER_VERIFICATION_UNSUPPORTED);
return promise_rejects_dom(t, "NotSupportedError",
navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that user verification unsupported error returned by mock is properly handled.");
promise_test(t => {
mockAuthenticator.setAuthenticatorStatus(
AuthenticatorStatus.EMPTY_ALLOW_CREDENTIALS);
var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS);
delete customGetCredentialOptions.allowCredentials;
return promise_rejects_dom(t, "NotSupportedError",
navigator.credentials.get({ publicKey : customGetCredentialOptions}));
}, "Verify that empty allow credentials error returned by mock is properly handled.");
promise_test(t => {
mockAuthenticator.setAuthenticatorStatus(AuthenticatorStatus.ABORT_ERROR);
return promise_rejects_dom(t, "AbortError",
navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that abort error returned by mock is properly handled.");
promise_test(function(t) {
var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS);
delete customGetCredentialOptions.challenge;
return promise_rejects_js(t, TypeError,
navigator.credentials.get({publicKey: customGetCredentialOptions}));
}, "navigator.credentials.get() with missing challenge");
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS);
delete customGetCredentialOptions.rpId;
console.log(customGetCredentialOptions);
return navigator.credentials.get({publicKey: customGetCredentialOptions}).then(r => {
assertValidGetCredentialResponse(r);
});
}, "navigator.credentials.get() with missing rpId");
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS);
delete customGetCredentialOptions.userVerification;
return navigator.credentials.get({publicKey: customGetCredentialOptions}).then(r => {
assertValidGetCredentialResponse(r);
});
}, "navigator.credentials.get() with missing user verification requirement");
promise_test(t => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS);
customGetCredentialOptions.extensions = {cableRegistration: CABLE_REGISTRATION};
return promise_rejects_dom(t, "NotSupportedError",
navigator.credentials.get({ publicKey : customGetCredentialOptions}));
}, "navigator.credentials.get() with cableRegistration extension not supported");
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
var customGetCredentialOptions = deepCopy(GET_CREDENTIAL_OPTIONS);
customGetCredentialOptions.extensions = {cableAuthentication: [CABLE_AUTHENTICATION]};
return navigator.credentials.get({publicKey: customGetCredentialOptions}).then(r => {
assertValidGetCredentialResponse(r);
});
}, "navigator.credentials.get() with cableAuthentication extension");
promise_test(t => {
var authAbortController = new AbortController();
var authAbortSignal = authAbortController.signal;
authAbortController.abort()
return promise_rejects_dom(t, "AbortError",
navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS, signal : authAbortSignal}));
}, "navigator.credentials.get() with abort signal.");
</script>