Commit dce697e1 authored by Ayu Ishii's avatar Ayu Ishii Committed by Commit Bot

WebOTP: Update API shape to spec

This change updates the WebOTP API shape to the latest spec.
It adds the following changes.

1. Adds `code` field for the one-time-code
2. Updates `id` to be undefined for OTPCredentials
3. Updates OtpCredentials to be OTPCredentials

WebOTP Explainer: https://github.com/samuelgoto/WebOTP/blob/master/explainer.md

Bug: 1053594
Change-Id: I747446b2fffc8f00afef105db3a5bcb35b124890
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2068300Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Commit-Queue: Ayu Ishii <ayui@chromium.org>
Cr-Commit-Position: refs/heads/master@{#745092}
parent 99f70a0c
...@@ -149,7 +149,7 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, Receive) { ...@@ -149,7 +149,7 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, Receive) {
std::string script = R"( std::string script = R"(
(async () => { (async () => {
let cred = await navigator.credentials.get({otp: {transport: ["sms"]}}); let cred = await navigator.credentials.get({otp: {transport: ["sms"]}});
return cred.id; return cred.code;
}) (); }) ();
)"; )";
...@@ -194,8 +194,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, AtMostOneSmsRequestPerOrigin) { ...@@ -194,8 +194,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, AtMostOneSmsRequestPerOrigin) {
return name; return name;
}); });
let secondRequest = navigator.credentials.get({otp: {transport: ["sms"]}}) let secondRequest = navigator.credentials.get({otp: {transport: ["sms"]}})
.then(({id}) => { .then(({code}) => {
return id; return code;
}); });
return Promise.all([firstRequest, secondRequest]); return Promise.all([firstRequest, secondRequest]);
}) (); }) ();
...@@ -255,8 +255,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, ...@@ -255,8 +255,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest,
// Make 1 request on tab2 to verify requests on tab1 have no affect on tab2. // Make 1 request on tab2 to verify requests on tab1 have no affect on tab2.
EXPECT_TRUE(ExecJs(tab2, R"( EXPECT_TRUE(ExecJs(tab2, R"(
var request = navigator.credentials.get({otp: {transport: ["sms"]}}) var request = navigator.credentials.get({otp: {transport: ["sms"]}})
.then(({id}) => { .then(({code}) => {
return id; return code;
}); });
)")); )"));
...@@ -265,8 +265,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, ...@@ -265,8 +265,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest,
EXPECT_TRUE(ExecJs(tab1, R"( EXPECT_TRUE(ExecJs(tab1, R"(
var secondRequest = navigator.credentials var secondRequest = navigator.credentials
.get({otp: {transport: ["sms"]}}) .get({otp: {transport: ["sms"]}})
.then(({id}) => { .then(({code}) => {
return id; return code;
}); });
)")); )"));
...@@ -417,8 +417,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, DISABLED_TwoTabsSameOrigin) { ...@@ -417,8 +417,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, DISABLED_TwoTabsSameOrigin) {
std::string script = R"( std::string script = R"(
var otp = navigator.credentials.get({otp: {transport: ["sms"]}}) var otp = navigator.credentials.get({otp: {transport: ["sms"]}})
.then(({id}) => { .then(({code}) => {
return id; return code;
}); });
)"; )";
...@@ -498,8 +498,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, DISABLED_TwoTabsDifferentOrigin) { ...@@ -498,8 +498,8 @@ IN_PROC_BROWSER_TEST_F(SmsBrowserTest, DISABLED_TwoTabsDifferentOrigin) {
std::string script = R"( std::string script = R"(
var otp = navigator.credentials.get({otp: {transport: ["sms"]}}) var otp = navigator.credentials.get({otp: {transport: ["sms"]}})
.then(({id}) => { .then(({code}) => {
return id; return code;
}); });
)"; )";
......
...@@ -8,11 +8,15 @@ ...@@ -8,11 +8,15 @@
namespace blink { namespace blink {
namespace {
constexpr char kOtpCredentialType[] = "otp";
}
Credential::~Credential() = default; Credential::~Credential() = default;
Credential::Credential(const String& id, const String& type) Credential::Credential(const String& id, const String& type)
: id_(id), type_(type) { : id_(id), type_(type) {
DCHECK(!id_.IsEmpty()); DCHECK(!id_.IsEmpty() || type == kOtpCredentialType);
DCHECK(!type_.IsEmpty()); DCHECK(!type_.IsEmpty());
} }
......
...@@ -25,7 +25,7 @@ class MODULES_EXPORT Credential : public ScriptWrappable { ...@@ -25,7 +25,7 @@ class MODULES_EXPORT Credential : public ScriptWrappable {
virtual bool IsPasswordCredential() const { return false; } virtual bool IsPasswordCredential() const { return false; }
virtual bool IsFederatedCredential() const { return false; } virtual bool IsFederatedCredential() const { return false; }
virtual bool IsPublicKeyCredential() const { return false; } virtual bool IsPublicKeyCredential() const { return false; }
virtual bool IsOtpCredential() const { return false; } virtual bool IsOTPCredential() const { return false; }
// Credential.idl // Credential.idl
const String& id() const { return id_; } const String& id() const { return id_; }
......
...@@ -16,7 +16,7 @@ dictionary CredentialRequestOptions { ...@@ -16,7 +16,7 @@ dictionary CredentialRequestOptions {
boolean password = false; boolean password = false;
CredentialMediationRequirement mediation = "optional"; CredentialMediationRequirement mediation = "optional";
[RuntimeEnabled=SmsReceiver] OtpCredentialRequestOptions otp; [RuntimeEnabled=SmsReceiver] OTPCredentialRequestOptions otp;
PublicKeyCredentialRequestOptions publicKey; PublicKeyCredentialRequestOptions publicKey;
AbortSignal signal; AbortSignal signal;
......
...@@ -507,7 +507,7 @@ void OnSmsReceive(ScriptPromiseResolver* resolver, ...@@ -507,7 +507,7 @@ void OnSmsReceive(ScriptPromiseResolver* resolver,
} }
RecordSmsSuccessTime(base::TimeTicks::Now() - start_time); RecordSmsSuccessTime(base::TimeTicks::Now() - start_time);
RecordSmsOutcome(SMSReceiverOutcome::kSuccess, source_id, recorder); RecordSmsOutcome(SMSReceiverOutcome::kSuccess, source_id, recorder);
resolver->Resolve(MakeGarbageCollected<OtpCredential>(otp)); resolver->Resolve(MakeGarbageCollected<OTPCredential>(otp));
} }
} // namespace } // namespace
......
...@@ -13,10 +13,10 @@ namespace { ...@@ -13,10 +13,10 @@ namespace {
constexpr char kOtpCredentialType[] = "otp"; constexpr char kOtpCredentialType[] = "otp";
} }
OtpCredential::OtpCredential(const String& id) OTPCredential::OTPCredential(const String& code)
: Credential(id, kOtpCredentialType) {} : Credential(String(), kOtpCredentialType), code_(code) {}
bool OtpCredential::IsOtpCredential() const { bool OTPCredential::IsOTPCredential() const {
return true; return true;
} }
......
...@@ -14,14 +14,20 @@ namespace blink { ...@@ -14,14 +14,20 @@ namespace blink {
// OtpCredentials represents credentials for when the otp is requested // OtpCredentials represents credentials for when the otp is requested
// through the credential manager. It stores the one-time-passcode (otp) that // through the credential manager. It stores the one-time-passcode (otp) that
// is retrieved from SMS by the browser. // is retrieved from SMS by the browser.
class MODULES_EXPORT OtpCredential final : public Credential { class MODULES_EXPORT OTPCredential final : public Credential {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
public: public:
explicit OtpCredential(const String& id); explicit OTPCredential(const String& code);
// Credential: // Credential:
bool IsOtpCredential() const override; bool IsOTPCredential() const override;
// OTPCredential.idl
const String& code() const { return code_; }
private:
String code_;
}; };
} // namespace blink } // namespace blink
......
...@@ -7,5 +7,6 @@ ...@@ -7,5 +7,6 @@
RuntimeEnabled=SmsReceiver, RuntimeEnabled=SmsReceiver,
Exposed=Window, Exposed=Window,
SecureContext SecureContext
] interface OtpCredential : Credential { ] interface OTPCredential : Credential {
readonly attribute DOMString code;
}; };
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
// https://github.com/samuelgoto/WebOTP // https://github.com/samuelgoto/WebOTP
enum OtpCredentialTransportType { enum OTPCredentialTransportType {
"sms" "sms"
}; };
dictionary OtpCredentialRequestOptions { dictionary OTPCredentialRequestOptions {
sequence<OtpCredentialTransportType> transport = []; sequence<OTPCredentialTransportType> transport = [];
}; };
...@@ -136,7 +136,8 @@ promise_test(_ => { ...@@ -136,7 +136,8 @@ promise_test(_ => {
mockSmsReceiver.setStatus(blink.mojom.SmsStatus.kSuccess); mockSmsReceiver.setStatus(blink.mojom.SmsStatus.kSuccess);
return navigator.credentials.get({otp: {transport: ["sms"]}}).then(r => { return navigator.credentials.get({otp: {transport: ["sms"]}}).then(r => {
assert_equals(r.type, "otp", "type"); assert_equals(r.type, "otp", "type");
assert_equals(r.id, otp, "id"); assert_equals(r.id, "", "id");
assert_equals(r.code, otp, "code");
}); });
}, "Verify that mockSmsReceiver returns the values we give it."); }, "Verify that mockSmsReceiver returns the values we give it.");
......
...@@ -5581,6 +5581,10 @@ interface Notification : EventTarget ...@@ -5581,6 +5581,10 @@ interface Notification : EventTarget
setter onclose setter onclose
setter onerror setter onerror
setter onshow setter onshow
interface OTPCredential : Credential
attribute @@toStringTag
getter code
method constructor
interface OfflineAudioCompletionEvent : Event interface OfflineAudioCompletionEvent : Event
attribute @@toStringTag attribute @@toStringTag
getter renderedBuffer getter renderedBuffer
...@@ -5718,9 +5722,6 @@ interface OscillatorNode : AudioScheduledSourceNode ...@@ -5718,9 +5722,6 @@ interface OscillatorNode : AudioScheduledSourceNode
method constructor method constructor
method setPeriodicWave method setPeriodicWave
setter type setter type
interface OtpCredential : Credential
attribute @@toStringTag
method constructor
interface OverconstrainedError interface OverconstrainedError
attribute @@toStringTag attribute @@toStringTag
getter constraint getter constraint
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment