Account: collapse 3-state model to 2 states with verification intent (#36111)
This commit is contained in:
+1
-1
@@ -192,7 +192,7 @@ public class BraveAccountSectionController
|
||||
setVisibility(resendConfirmationEmailPref, false);
|
||||
setVisibility(cancelRegistrationPref, false);
|
||||
setVisibility(getStartedPref, false);
|
||||
} else if (state.which() == AccountState.Tag.Verification) {
|
||||
} else if (state.getLoggedOut().verification != null) {
|
||||
setVisibility(userInfoPref, false);
|
||||
setVisibility(signOutPref, false);
|
||||
setVisibility(almostTherePref, true);
|
||||
|
||||
@@ -182,60 +182,62 @@ export class SettingsBraveAccountRowElement extends I18nMixinLit(CrLitElement) {
|
||||
</leo-button>
|
||||
`
|
||||
),
|
||||
[AccountStateFieldTags.VERIFICATION]: () => html`
|
||||
${this.createFirstRow(
|
||||
this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_TITLE),
|
||||
[
|
||||
html`<localized-link
|
||||
.localizedString=${`${
|
||||
this.i18n(BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_DESCRIPTION_1)} ${
|
||||
this.i18n(BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_DESCRIPTION_2)} ${
|
||||
this.i18nAdvanced(BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_DESCRIPTION_3,
|
||||
{tags: ['a'], attrs: ['href']})}`}
|
||||
@link-clicked=${this.onResendConfirmationEmailLinkClicked}>
|
||||
</localized-link>`
|
||||
]
|
||||
)}
|
||||
<div class="second-row">
|
||||
<leo-button kind="plain"
|
||||
size="small"
|
||||
@click=${this.openBraveAccountDialog}>
|
||||
${this.i18n(
|
||||
[AccountStateFieldTags.LOGGED_OUT]: () =>
|
||||
this.state!.loggedOut!.verification
|
||||
? html`
|
||||
${this.createFirstRow(
|
||||
this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_TITLE),
|
||||
[
|
||||
html`<localized-link
|
||||
.localizedString=${`${
|
||||
this.i18n(BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_DESCRIPTION_1)} ${
|
||||
this.i18n(BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_DESCRIPTION_2)} ${
|
||||
this.i18nAdvanced(BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_VERIFICATION_ROW_DESCRIPTION_3,
|
||||
{tags: ['a'], attrs: ['href']})}`}
|
||||
@link-clicked=${this.onResendConfirmationEmailLinkClicked}>
|
||||
</localized-link>`
|
||||
]
|
||||
)}
|
||||
<div class="second-row">
|
||||
<leo-button kind="plain"
|
||||
size="small"
|
||||
@click=${this.openBraveAccountDialog}>
|
||||
${this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_ENTER_REGISTRATION_CODE_BUTTON_LABEL)}
|
||||
</leo-button>
|
||||
<leo-button kind="plain"
|
||||
size="small"
|
||||
class="cancel-registration-button"
|
||||
@click=${this.onCancelRegistrationButtonClicked}>
|
||||
${this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_CANCEL_REGISTRATION_BUTTON_LABEL)}
|
||||
</leo-button>
|
||||
</div>
|
||||
`
|
||||
: this.createFirstRow(
|
||||
this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_ENTER_REGISTRATION_CODE_BUTTON_LABEL)}
|
||||
</leo-button>
|
||||
<leo-button kind="plain"
|
||||
size="small"
|
||||
class="cancel-registration-button"
|
||||
@click=${this.onCancelRegistrationButtonClicked}>
|
||||
${this.i18n(
|
||||
.SETTINGS_BRAVE_ACCOUNT_LOGGED_OUT_ROW_TITLE),
|
||||
[this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_CANCEL_REGISTRATION_BUTTON_LABEL)}
|
||||
</leo-button>
|
||||
</div>
|
||||
`,
|
||||
[AccountStateFieldTags.LOGGED_OUT]: () => this.createFirstRow(
|
||||
this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_LOGGED_OUT_ROW_TITLE),
|
||||
[this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.BRAVE_ACCOUNT_DESCRIPTION)],
|
||||
html`
|
||||
<leo-button kind="filled"
|
||||
size="small"
|
||||
@click=${this.openBraveAccountDialog}>
|
||||
${this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_GET_STARTED_BUTTON_LABEL)}
|
||||
</leo-button>
|
||||
`
|
||||
),
|
||||
.BRAVE_ACCOUNT_DESCRIPTION)],
|
||||
html`
|
||||
<leo-button kind="filled"
|
||||
size="small"
|
||||
@click=${this.openBraveAccountDialog}>
|
||||
${this.i18n(
|
||||
BraveAccountSettingsStrings
|
||||
.SETTINGS_BRAVE_ACCOUNT_GET_STARTED_BUTTON_LABEL)}
|
||||
</leo-button>
|
||||
`
|
||||
),
|
||||
}
|
||||
|
||||
return this.state === undefined
|
||||
|
||||
@@ -11,10 +11,8 @@ source_set("brave_account") {
|
||||
"brave_account_constants.h",
|
||||
"brave_account_service.cc",
|
||||
"brave_account_service.h",
|
||||
"brave_account_service_constants.h",
|
||||
"brave_account_ui_base.h",
|
||||
"brave_account_utils.h",
|
||||
"pref_names.h",
|
||||
"prefs.cc",
|
||||
"prefs.h",
|
||||
]
|
||||
@@ -22,6 +20,7 @@ source_set("brave_account") {
|
||||
deps = [
|
||||
"//base",
|
||||
"//brave/components/brave_account:features",
|
||||
"//brave/components/brave_account:internal",
|
||||
"//brave/components/brave_account/endpoint_client",
|
||||
"//brave/components/brave_account/endpoints",
|
||||
"//brave/components/brave_account/mojom",
|
||||
@@ -49,6 +48,26 @@ source_set("brave_account") {
|
||||
}
|
||||
}
|
||||
|
||||
source_set("internal") {
|
||||
visibility = [
|
||||
":*",
|
||||
"//brave/components/email_aliases:service",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"brave_account_service_constants.h",
|
||||
"brave_account_state_prefs.cc",
|
||||
"brave_account_state_prefs.h",
|
||||
"pref_names.h",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"//base",
|
||||
"//brave/components/brave_account/mojom",
|
||||
"//components/prefs",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("features") {
|
||||
sources = [
|
||||
"features.cc",
|
||||
@@ -95,6 +114,7 @@ source_set("unit_tests") {
|
||||
"//base/test:test_support",
|
||||
"//brave/components/brave_account",
|
||||
"//brave/components/brave_account:features",
|
||||
"//brave/components/brave_account:internal",
|
||||
"//brave/components/brave_account:test_support",
|
||||
"//brave/components/brave_account/endpoint_client:test_support",
|
||||
"//brave/components/brave_account/endpoints",
|
||||
|
||||
@@ -15,20 +15,17 @@
|
||||
#include "base/check_is_test.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/json/values_util.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/notimplemented.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/types/expected.h"
|
||||
#include "base/values.h"
|
||||
#include "brave/components/brave_account/brave_account_service_constants.h"
|
||||
#include "brave/components/brave_account/brave_account_state_prefs.h"
|
||||
#include "brave/components/brave_account/brave_account_utils.h"
|
||||
#include "brave/components/brave_account/endpoint_client/client.h"
|
||||
#include "brave/components/brave_account/endpoint_client/with_headers.h"
|
||||
#include "brave/components/brave_account/endpoints/auth_logout.h"
|
||||
#include "brave/components/brave_account/endpoints/error_body.h"
|
||||
#include "brave/components/brave_account/endpoints/verify_delete.h"
|
||||
#include "brave/components/brave_account/pref_names.h"
|
||||
#include "components/os_crypt/async/browser/os_crypt_async.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "net/http/http_request_headers.h"
|
||||
@@ -159,9 +156,8 @@ BraveAccountService::BraveAccountService(
|
||||
PrefService* pref_service,
|
||||
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
|
||||
os_crypt_async::OSCryptAsync* os_crypt_async)
|
||||
: pref_service_(pref_service),
|
||||
: account_state_prefs_(CHECK_DEREF(pref_service)),
|
||||
url_loader_factory_(std::move(url_loader_factory)) {
|
||||
CHECK(pref_service_);
|
||||
CHECK(url_loader_factory_);
|
||||
|
||||
CHECK_DEREF(os_crypt_async)
|
||||
@@ -191,21 +187,9 @@ void BraveAccountService::FinishInitialization(
|
||||
os_crypt_async::Encryptor encryptor) {
|
||||
encryptor_ = std::move(encryptor);
|
||||
|
||||
pref_verification_token_.Init(
|
||||
prefs::kBraveAccountVerificationToken, pref_service_,
|
||||
base::BindRepeating(&BraveAccountService::OnVerificationTokenChanged,
|
||||
base::Unretained(this)));
|
||||
|
||||
pref_authentication_token_.Init(
|
||||
prefs::kBraveAccountAuthenticationToken, pref_service_,
|
||||
base::BindRepeating(&BraveAccountService::OnAuthenticationTokenChanged,
|
||||
base::Unretained(this)));
|
||||
OnAuthenticationTokenChanged();
|
||||
|
||||
pref_email_address_.Init(
|
||||
prefs::kBraveAccountEmailAddress, pref_service_,
|
||||
base::BindRepeating(&BraveAccountService::OnEmailAddressChanged,
|
||||
base::Unretained(this)));
|
||||
account_state_prefs_.StartObserving(base::BindRepeating(
|
||||
&BraveAccountService::OnAccountStateChanged, base::Unretained(this)));
|
||||
OnAccountStateChanged();
|
||||
|
||||
for (auto& pending_receiver : pending_receivers_) {
|
||||
authentication_receivers_.Add(this, std::move(pending_receiver));
|
||||
@@ -217,7 +201,7 @@ void BraveAccountService::AddObserver(
|
||||
mojo::PendingRemote<mojom::AuthenticationObserver> observer) {
|
||||
const auto observer_id = observers_.Add(std::move(observer));
|
||||
CHECK_DEREF(observers_.Get(observer_id))
|
||||
.OnAccountStateChanged(GetAccountState());
|
||||
.OnAccountStateChanged(account_state_prefs_.GetAccountState());
|
||||
}
|
||||
|
||||
void BraveAccountService::RegisterInitialize(
|
||||
@@ -269,11 +253,12 @@ void BraveAccountService::RegisterVerify(const std::string& code,
|
||||
CHECK(!code.empty());
|
||||
|
||||
const auto encrypted_verification_token =
|
||||
pref_service_->GetString(prefs::kBraveAccountVerificationToken);
|
||||
account_state_prefs_.GetVerificationToken(
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
if (encrypted_verification_token.empty()) {
|
||||
return std::move(callback).Run(
|
||||
base::unexpected(MakeClientError<mojom::RegisterError>(
|
||||
mojom::RegisterClientErrorCode::kUserNotInTheVerificationState)));
|
||||
mojom::RegisterClientErrorCode::kNoRegistrationInProgress)));
|
||||
}
|
||||
|
||||
const auto verification_token = Decrypt(encrypted_verification_token);
|
||||
@@ -295,12 +280,13 @@ void BraveAccountService::RegisterVerify(const std::string& code,
|
||||
void BraveAccountService::ResendConfirmationEmail(
|
||||
ResendConfirmationEmailCallback callback) {
|
||||
const auto encrypted_verification_token =
|
||||
pref_service_->GetString(prefs::kBraveAccountVerificationToken);
|
||||
account_state_prefs_.GetVerificationToken(
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
if (encrypted_verification_token.empty()) {
|
||||
return std::move(callback).Run(
|
||||
base::unexpected(MakeClientError<mojom::ResendConfirmationEmailError>(
|
||||
mojom::ResendConfirmationEmailClientErrorCode::
|
||||
kUserNotInTheVerificationState)));
|
||||
kNoRegistrationInProgress)));
|
||||
}
|
||||
|
||||
const auto verification_token = Decrypt(encrypted_verification_token);
|
||||
@@ -325,9 +311,10 @@ void BraveAccountService::ResendConfirmationEmail(
|
||||
|
||||
void BraveAccountService::CancelRegistration() {
|
||||
const auto encrypted_verification_token =
|
||||
pref_service_->GetString(prefs::kBraveAccountVerificationToken);
|
||||
account_state_prefs_.GetVerificationToken(
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
|
||||
pref_service_->ClearPref(prefs::kBraveAccountVerificationToken);
|
||||
account_state_prefs_.SetLoggedOut();
|
||||
|
||||
const auto verification_token = Decrypt(encrypted_verification_token);
|
||||
if (verification_token.empty()) {
|
||||
@@ -385,9 +372,9 @@ void BraveAccountService::LoginFinalize(
|
||||
|
||||
void BraveAccountService::LogOut() {
|
||||
const auto encrypted_authentication_token =
|
||||
pref_service_->GetString(prefs::kBraveAccountAuthenticationToken);
|
||||
account_state_prefs_.GetAuthenticationToken();
|
||||
|
||||
pref_service_->ClearPref(prefs::kBraveAccountAuthenticationToken);
|
||||
account_state_prefs_.SetLoggedOut();
|
||||
|
||||
const auto authentication_token = Decrypt(encrypted_authentication_token);
|
||||
if (authentication_token.empty()) {
|
||||
@@ -406,14 +393,15 @@ void BraveAccountService::GetServiceToken(mojom::Service service,
|
||||
GetServiceTokenCallback callback) {
|
||||
CHECK(service != mojom::Service::kAccounts);
|
||||
std::string service_name(kServiceToString.at(service));
|
||||
if (auto service_token = GetCachedServiceToken(service_name);
|
||||
if (auto service_token =
|
||||
Decrypt(account_state_prefs_.GetCachedServiceToken(service_name));
|
||||
!service_token.empty()) {
|
||||
return std::move(callback).Run(
|
||||
mojom::GetServiceTokenResult::New(std::move(service_token)));
|
||||
}
|
||||
|
||||
auto encrypted_authentication_token =
|
||||
pref_service_->GetString(prefs::kBraveAccountAuthenticationToken);
|
||||
account_state_prefs_.GetAuthenticationToken();
|
||||
if (encrypted_authentication_token.empty()) {
|
||||
return std::move(callback).Run(
|
||||
base::unexpected(MakeClientError<mojom::GetServiceTokenError>(
|
||||
@@ -513,8 +501,9 @@ void BraveAccountService::OnRegisterFinalize(
|
||||
.and_then([&](auto success_body)
|
||||
-> base::expected<mojom::RegisterFinalizeResultPtr,
|
||||
mojom::RegisterErrorPtr> {
|
||||
pref_service_->SetString(prefs::kBraveAccountVerificationToken,
|
||||
encrypted_verification_token);
|
||||
account_state_prefs_.SetLoggedOutWithVerification(
|
||||
encrypted_verification_token,
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
|
||||
return mojom::RegisterFinalizeResult::New();
|
||||
});
|
||||
@@ -560,11 +549,8 @@ void BraveAccountService::OnRegisterVerify(RegisterVerifyCallback callback,
|
||||
kAuthenticationTokenEncryptionFailed));
|
||||
}
|
||||
|
||||
pref_service_->SetString(prefs::kBraveAccountEmailAddress,
|
||||
success_body.email);
|
||||
pref_service_->SetString(prefs::kBraveAccountAuthenticationToken,
|
||||
encrypted_authentication_token);
|
||||
pref_service_->ClearPref(prefs::kBraveAccountVerificationToken);
|
||||
account_state_prefs_.SetLoggedIn(success_body.email,
|
||||
encrypted_authentication_token);
|
||||
|
||||
return mojom::RegisterVerifyResult::New();
|
||||
});
|
||||
@@ -592,10 +578,6 @@ void BraveAccountService::OnResendConfirmationEmail(
|
||||
std::move(response.body->error()))));
|
||||
}
|
||||
|
||||
void BraveAccountService::OnVerificationTokenChanged() {
|
||||
NotifyObservers();
|
||||
}
|
||||
|
||||
void BraveAccountService::OnLoginInitialize(LoginInitializeCallback callback,
|
||||
LoginInit::Response response) {
|
||||
if (!response.body) {
|
||||
@@ -678,10 +660,8 @@ void BraveAccountService::OnLoginFinalize(LoginFinalizeCallback callback,
|
||||
kAuthenticationTokenEncryptionFailed));
|
||||
}
|
||||
|
||||
pref_service_->SetString(prefs::kBraveAccountEmailAddress,
|
||||
success_body.email);
|
||||
pref_service_->SetString(prefs::kBraveAccountAuthenticationToken,
|
||||
encrypted_authentication_token);
|
||||
account_state_prefs_.SetLoggedIn(success_body.email,
|
||||
encrypted_authentication_token);
|
||||
|
||||
return mojom::LoginFinalizeResult::New();
|
||||
});
|
||||
@@ -689,12 +669,13 @@ void BraveAccountService::OnLoginFinalize(LoginFinalizeCallback callback,
|
||||
std::move(callback).Run(std::move(result));
|
||||
}
|
||||
|
||||
void BraveAccountService::OnAuthenticationTokenChanged() {
|
||||
NotifyObservers();
|
||||
void BraveAccountService::OnAccountStateChanged() {
|
||||
const auto account_state = account_state_prefs_.GetAccountState();
|
||||
for (auto& observer : observers_) {
|
||||
observer->OnAccountStateChanged(account_state.Clone());
|
||||
}
|
||||
|
||||
if (pref_authentication_token_.GetValue().empty()) {
|
||||
pref_service_->ClearPref(prefs::kBraveAccountEmailAddress);
|
||||
pref_service_->ClearPref(prefs::kBraveAccountServiceTokens);
|
||||
if (!account_state->is_logged_in()) {
|
||||
return auth_validate_timer_.Stop();
|
||||
}
|
||||
|
||||
@@ -715,7 +696,7 @@ void BraveAccountService::AuthValidate(
|
||||
current_auth_validate_request.reset();
|
||||
|
||||
const auto encrypted_authentication_token =
|
||||
pref_service_->GetString(prefs::kBraveAccountAuthenticationToken);
|
||||
account_state_prefs_.GetAuthenticationToken();
|
||||
if (encrypted_authentication_token.empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -747,51 +728,17 @@ void BraveAccountService::OnAuthValidate(AuthValidate::Response response) {
|
||||
: "";
|
||||
|
||||
if (!email.empty()) {
|
||||
pref_service_->SetString(prefs::kBraveAccountEmailAddress, email);
|
||||
account_state_prefs_.UpdateEmail(email);
|
||||
} else if (response.status_code >= 400 && response.status_code < 500) {
|
||||
// Clear the auth token (and stop polling) to prevent
|
||||
// presenting invalid state to the user and issuing invalid requests.
|
||||
return pref_service_->ClearPref(prefs::kBraveAccountAuthenticationToken);
|
||||
// Force logged-out (and stop polling) to prevent presenting invalid state
|
||||
// to the user and issuing invalid requests.
|
||||
return account_state_prefs_.SetLoggedOut();
|
||||
}
|
||||
|
||||
// Replace watchdog timer with the normal cadence.
|
||||
ScheduleAuthValidate(kAuthValidatePollInterval);
|
||||
}
|
||||
|
||||
void BraveAccountService::OnEmailAddressChanged() {
|
||||
// Only notify observers if logged in, since the email is only relevant in
|
||||
// the LoggedIn state.
|
||||
if (!pref_authentication_token_.GetValue().empty()) {
|
||||
NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
void BraveAccountService::NotifyObservers() {
|
||||
const auto state = GetAccountState();
|
||||
for (auto& observer : observers_) {
|
||||
observer->OnAccountStateChanged(state.Clone());
|
||||
}
|
||||
}
|
||||
|
||||
mojom::AccountStatePtr BraveAccountService::GetAccountState() const {
|
||||
if (!pref_service_->GetString(prefs::kBraveAccountAuthenticationToken)
|
||||
.empty()) {
|
||||
std::string email =
|
||||
pref_service_->GetString(prefs::kBraveAccountEmailAddress);
|
||||
CHECK(!email.empty());
|
||||
return mojom::AccountState::NewLoggedIn(
|
||||
mojom::LoggedInState::New(std::move(email)));
|
||||
}
|
||||
|
||||
if (!pref_service_->GetString(prefs::kBraveAccountVerificationToken)
|
||||
.empty()) {
|
||||
return mojom::AccountState::NewVerification(
|
||||
mojom::VerificationState::New());
|
||||
}
|
||||
|
||||
return mojom::AccountState::NewLoggedOut(mojom::LoggedOutState::New());
|
||||
}
|
||||
|
||||
void BraveAccountService::OnGetServiceToken(
|
||||
const std::string& expected_encrypted_authentication_token,
|
||||
const std::string& service_name,
|
||||
@@ -803,7 +750,7 @@ void BraveAccountService::OnGetServiceToken(
|
||||
// token as it belongs to a different (or no longer valid) authentication
|
||||
// session.
|
||||
if (const auto current_encrypted_authentication_token =
|
||||
pref_service_->GetString(prefs::kBraveAccountAuthenticationToken);
|
||||
account_state_prefs_.GetAuthenticationToken();
|
||||
current_encrypted_authentication_token !=
|
||||
expected_encrypted_authentication_token) {
|
||||
return std::move(callback).Run(
|
||||
@@ -849,18 +796,8 @@ void BraveAccountService::OnGetServiceToken(
|
||||
kServiceTokenEncryptionFailed));
|
||||
}
|
||||
|
||||
auto service_tokens =
|
||||
pref_service_->GetDict(prefs::kBraveAccountServiceTokens)
|
||||
.Clone();
|
||||
service_tokens.Set(service_name,
|
||||
base::DictValue()
|
||||
.Set(prefs::keys::kServiceToken,
|
||||
std::move(encrypted_service_token))
|
||||
.Set(prefs::keys::kLastFetched,
|
||||
base::TimeToValue(base::Time::Now())));
|
||||
|
||||
pref_service_->SetDict(prefs::kBraveAccountServiceTokens,
|
||||
std::move(service_tokens));
|
||||
account_state_prefs_.CacheServiceToken(
|
||||
service_name, std::move(encrypted_service_token));
|
||||
|
||||
return mojom::GetServiceTokenResult::New(
|
||||
std::move(success_body.auth_token));
|
||||
@@ -869,35 +806,6 @@ void BraveAccountService::OnGetServiceToken(
|
||||
std::move(callback).Run(std::move(result));
|
||||
}
|
||||
|
||||
std::string BraveAccountService::GetCachedServiceToken(
|
||||
const std::string& service_name) const {
|
||||
const auto* service =
|
||||
pref_service_->GetDict(prefs::kBraveAccountServiceTokens)
|
||||
.FindDict(service_name);
|
||||
if (!service) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto* encrypted_service_token =
|
||||
service->FindString(prefs::keys::kServiceToken);
|
||||
const auto* last_fetched_value = service->Find(prefs::keys::kLastFetched);
|
||||
|
||||
if (!encrypted_service_token || !last_fetched_value) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto last_fetched_time = base::ValueToTime(*last_fetched_value);
|
||||
if (!last_fetched_time) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (base::Time::Now() - *last_fetched_time >= kServiceTokenMaxAge) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return Decrypt(*encrypted_service_token);
|
||||
}
|
||||
|
||||
std::string BraveAccountService::Encrypt(const std::string& plain_text) const {
|
||||
if (plain_text.empty()) {
|
||||
return std::string();
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "brave/components/brave_account/brave_account_state_prefs.h"
|
||||
#include "brave/components/brave_account/endpoint_client/request_handle.h"
|
||||
#include "brave/components/brave_account/endpoints/auth_validate.h"
|
||||
#include "brave/components/brave_account/endpoints/login_finalize.h"
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "brave/components/brave_account/mojom/brave_account.mojom.h"
|
||||
#include "components/keyed_service/core/keyed_service.h"
|
||||
#include "components/os_crypt/async/common/encryptor.h"
|
||||
#include "components/prefs/pref_member.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
@@ -125,15 +124,13 @@ class BraveAccountService : public KeyedService, public mojom::Authentication {
|
||||
void OnResendConfirmationEmail(ResendConfirmationEmailCallback callback,
|
||||
endpoints::VerifyResend::Response response);
|
||||
|
||||
void OnVerificationTokenChanged();
|
||||
|
||||
void OnLoginInitialize(LoginInitializeCallback callback,
|
||||
endpoints::LoginInit::Response response);
|
||||
|
||||
void OnLoginFinalize(LoginFinalizeCallback callback,
|
||||
endpoints::LoginFinalize::Response response);
|
||||
|
||||
void OnAuthenticationTokenChanged();
|
||||
void OnAccountStateChanged();
|
||||
|
||||
void ScheduleAuthValidate(
|
||||
base::TimeDelta delay = base::Seconds(0),
|
||||
@@ -144,33 +141,22 @@ class BraveAccountService : public KeyedService, public mojom::Authentication {
|
||||
|
||||
void OnAuthValidate(endpoints::AuthValidate::Response response);
|
||||
|
||||
void OnEmailAddressChanged();
|
||||
|
||||
void NotifyObservers();
|
||||
|
||||
mojom::AccountStatePtr GetAccountState() const;
|
||||
|
||||
void OnGetServiceToken(
|
||||
const std::string& expected_encrypted_authentication_token,
|
||||
const std::string& service_name,
|
||||
GetServiceTokenCallback callback,
|
||||
endpoints::ServiceToken::Response response);
|
||||
|
||||
std::string GetCachedServiceToken(const std::string& service_name) const;
|
||||
|
||||
std::string Encrypt(const std::string& plain_text) const;
|
||||
|
||||
std::string Decrypt(const std::string& base64) const;
|
||||
|
||||
const raw_ptr<PrefService> pref_service_;
|
||||
AccountStatePrefs account_state_prefs_;
|
||||
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
|
||||
std::optional<os_crypt_async::Encryptor> encryptor_;
|
||||
std::vector<mojo::PendingReceiver<mojom::Authentication>> pending_receivers_;
|
||||
mojo::ReceiverSet<mojom::Authentication> authentication_receivers_;
|
||||
mojo::RemoteSet<mojom::AuthenticationObserver> observers_;
|
||||
StringPrefMember pref_verification_token_;
|
||||
StringPrefMember pref_authentication_token_;
|
||||
StringPrefMember pref_email_address_;
|
||||
base::OneShotTimer auth_validate_timer_;
|
||||
base::WeakPtrFactory<BraveAccountService> weak_factory_{this};
|
||||
};
|
||||
|
||||
@@ -10,11 +10,10 @@
|
||||
|
||||
namespace brave_account {
|
||||
|
||||
inline constexpr base::TimeDelta kVerifyResultPollInterval = base::Seconds(5);
|
||||
inline constexpr base::TimeDelta kAuthValidatePollInterval = base::Minutes(2);
|
||||
inline constexpr base::TimeDelta kVerifyResendTimeout = base::Seconds(10);
|
||||
|
||||
// If a polling request (VerifyResult or AuthValidate) doesn't complete within
|
||||
// If a polling request (AuthValidate) doesn't complete within
|
||||
// this interval, it will be canceled and retried to prevent hung requests from
|
||||
// stopping the periodic polling indefinitely.
|
||||
inline constexpr base::TimeDelta kWatchdogInterval = base::Seconds(15);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "base/values.h"
|
||||
#include "brave/components/brave_account/brave_account_service_constants.h"
|
||||
#include "brave/components/brave_account/brave_account_service_test.h"
|
||||
#include "brave/components/brave_account/brave_account_state_prefs.h"
|
||||
#include "brave/components/brave_account/endpoints/auth_validate.h"
|
||||
#include "brave/components/brave_account/endpoints/login_finalize.h"
|
||||
#include "brave/components/brave_account/endpoints/login_init.h"
|
||||
@@ -29,6 +30,7 @@
|
||||
#include "brave/components/brave_account/mojom/brave_account.mojom.h"
|
||||
#include "brave/components/brave_account/pref_names.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/scoped_user_pref_update.h"
|
||||
#include "net/http/http_status_code.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@@ -82,6 +84,7 @@ struct AuthenticationObserverTestCase {
|
||||
static void Run(const AuthenticationObserverTestCase& test_case,
|
||||
PrefService& pref_service,
|
||||
mojom::Authentication& authentication) {
|
||||
AccountStatePrefs account_state_prefs(pref_service);
|
||||
const auto account_state_eq = [](const mojom::AccountStatePtr& expected) {
|
||||
return testing::Truly([&](const mojom::AccountStatePtr& state) {
|
||||
return state.Equals(expected);
|
||||
@@ -90,15 +93,15 @@ struct AuthenticationObserverTestCase {
|
||||
|
||||
switch (CHECK_DEREF(test_case.from).which()) {
|
||||
case mojom::AccountState::Tag::kLoggedOut:
|
||||
break;
|
||||
case mojom::AccountState::Tag::kVerification:
|
||||
pref_service.SetString(prefs::kBraveAccountVerificationToken,
|
||||
EncryptedVerificationToken());
|
||||
if (test_case.from->get_logged_out()->verification) {
|
||||
account_state_prefs.SetLoggedOutWithVerification(
|
||||
EncryptedVerificationToken(),
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
}
|
||||
break;
|
||||
case mojom::AccountState::Tag::kLoggedIn:
|
||||
pref_service.SetString(prefs::kBraveAccountEmailAddress, kEmailAddress);
|
||||
pref_service.SetString(prefs::kBraveAccountAuthenticationToken,
|
||||
EncryptedAuthenticationToken());
|
||||
account_state_prefs.SetLoggedIn(kEmailAddress,
|
||||
EncryptedAuthenticationToken());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -118,19 +121,19 @@ struct AuthenticationObserverTestCase {
|
||||
|
||||
switch (test_case.action) {
|
||||
case StateAction::kSwitchToVerification:
|
||||
pref_service.SetString(prefs::kBraveAccountVerificationToken,
|
||||
EncryptedVerificationToken());
|
||||
account_state_prefs.SetLoggedOutWithVerification(
|
||||
EncryptedVerificationToken(),
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
break;
|
||||
case StateAction::kSwitchToLoggedIn:
|
||||
pref_service.SetString(prefs::kBraveAccountEmailAddress, kEmailAddress);
|
||||
pref_service.SetString(prefs::kBraveAccountAuthenticationToken,
|
||||
EncryptedAuthenticationToken());
|
||||
account_state_prefs.SetLoggedIn(kEmailAddress,
|
||||
EncryptedAuthenticationToken());
|
||||
break;
|
||||
case StateAction::kSwitchToLoggedOut:
|
||||
pref_service.ClearPref(prefs::kBraveAccountAuthenticationToken);
|
||||
account_state_prefs.SetLoggedOut();
|
||||
break;
|
||||
case StateAction::kUpdateEmailAddress:
|
||||
pref_service.SetString(prefs::kBraveAccountEmailAddress, "new_email");
|
||||
account_state_prefs.UpdateEmail("new_email");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -145,17 +148,30 @@ struct AuthenticationObserverTestCase {
|
||||
|
||||
namespace {
|
||||
|
||||
mojom::AccountStatePtr LoggedOut() {
|
||||
return mojom::AccountState::NewLoggedOut(mojom::LoggedOutState::New(nullptr));
|
||||
}
|
||||
|
||||
mojom::AccountStatePtr LoggedOutWithVerification() {
|
||||
return mojom::AccountState::NewLoggedOut(
|
||||
mojom::LoggedOutState::New(mojom::LoggedOutVerification::New(
|
||||
mojom::LoggedOutVerificationIntent::kRegistration)));
|
||||
}
|
||||
|
||||
mojom::AccountStatePtr LoggedIn(const std::string& email) {
|
||||
return mojom::AccountState::NewLoggedIn(
|
||||
mojom::LoggedInState::New(email, nullptr));
|
||||
}
|
||||
|
||||
const AuthenticationObserverTestCase*
|
||||
AuthenticationObserverLoggedOutToVerification() {
|
||||
static const base::NoDestructor<AuthenticationObserverTestCase>
|
||||
kAuthenticationObserverLoggedOutToVerification(
|
||||
{.test_name = "authentication_observer_logged_out_to_verification",
|
||||
.from =
|
||||
mojom::AccountState::NewLoggedOut(mojom::LoggedOutState::New()),
|
||||
.from = LoggedOut(),
|
||||
.action = AuthenticationObserverTestCase::StateAction::
|
||||
kSwitchToVerification,
|
||||
.to = mojom::AccountState::NewVerification(
|
||||
mojom::VerificationState::New())});
|
||||
.to = LoggedOutWithVerification()});
|
||||
return kAuthenticationObserverLoggedOutToVerification.get();
|
||||
}
|
||||
|
||||
@@ -164,12 +180,10 @@ AuthenticationObserverVerificationToLoggedIn() {
|
||||
static const base::NoDestructor<AuthenticationObserverTestCase>
|
||||
kAuthenticationObserverVerificationToLoggedIn(
|
||||
{.test_name = "authentication_observer_verification_to_logged_in",
|
||||
.from = mojom::AccountState::NewVerification(
|
||||
mojom::VerificationState::New()),
|
||||
.from = LoggedOutWithVerification(),
|
||||
.action =
|
||||
AuthenticationObserverTestCase::StateAction::kSwitchToLoggedIn,
|
||||
.to = mojom::AccountState::NewLoggedIn(
|
||||
mojom::LoggedInState::New(kEmailAddress))});
|
||||
.to = LoggedIn(kEmailAddress)});
|
||||
return kAuthenticationObserverVerificationToLoggedIn.get();
|
||||
}
|
||||
|
||||
@@ -178,12 +192,10 @@ AuthenticationObserverLoggedInToLoggedOut() {
|
||||
static const base::NoDestructor<AuthenticationObserverTestCase>
|
||||
kAuthenticationObserverLoggedInToLoggedOut(
|
||||
{.test_name = "authentication_observer_logged_in_to_logged_out",
|
||||
.from = mojom::AccountState::NewLoggedIn(
|
||||
mojom::LoggedInState::New(kEmailAddress)),
|
||||
.from = LoggedIn(kEmailAddress),
|
||||
.action =
|
||||
AuthenticationObserverTestCase::StateAction::kSwitchToLoggedOut,
|
||||
.to = mojom::AccountState::NewLoggedOut(
|
||||
mojom::LoggedOutState::New())});
|
||||
.to = LoggedOut()});
|
||||
return kAuthenticationObserverLoggedInToLoggedOut.get();
|
||||
}
|
||||
|
||||
@@ -192,12 +204,10 @@ AuthenticationObserverLoggedOutToLoggedIn() {
|
||||
static const base::NoDestructor<AuthenticationObserverTestCase>
|
||||
kAuthenticationObserverLoggedOutToLoggedIn(
|
||||
{.test_name = "authentication_observer_logged_out_to_logged_in",
|
||||
.from =
|
||||
mojom::AccountState::NewLoggedOut(mojom::LoggedOutState::New()),
|
||||
.from = LoggedOut(),
|
||||
.action =
|
||||
AuthenticationObserverTestCase::StateAction::kSwitchToLoggedIn,
|
||||
.to = mojom::AccountState::NewLoggedIn(
|
||||
mojom::LoggedInState::New(kEmailAddress))});
|
||||
.to = LoggedIn(kEmailAddress)});
|
||||
return kAuthenticationObserverLoggedOutToLoggedIn.get();
|
||||
}
|
||||
|
||||
@@ -207,12 +217,10 @@ AuthenticationObserverLoggedInToLoggedInEmailChange() {
|
||||
kAuthenticationObserverLoggedInToLoggedInEmailChange(
|
||||
{.test_name =
|
||||
"authentication_observer_logged_in_to_logged_in_email_change",
|
||||
.from = mojom::AccountState::NewLoggedIn(
|
||||
mojom::LoggedInState::New(kEmailAddress)),
|
||||
.from = LoggedIn(kEmailAddress),
|
||||
.action =
|
||||
AuthenticationObserverTestCase::StateAction::kUpdateEmailAddress,
|
||||
.to = mojom::AccountState::NewLoggedIn(
|
||||
mojom::LoggedInState::New("new_email"))});
|
||||
.to = LoggedIn("new_email")});
|
||||
return kAuthenticationObserverLoggedInToLoggedInEmailChange.get();
|
||||
}
|
||||
|
||||
@@ -900,7 +908,14 @@ TEST_P(BraveAccountServiceRegisterFinalizeTest,
|
||||
|
||||
if (const auto& test_case = CHECK_DEREF(this->GetParam());
|
||||
test_case.mojo_expected.has_value()) {
|
||||
EXPECT_EQ(pref_service_.GetString(prefs::kBraveAccountVerificationToken),
|
||||
AccountStatePrefs account_state_prefs(pref_service_);
|
||||
const auto state = account_state_prefs.GetAccountState();
|
||||
ASSERT_TRUE(state->is_logged_out());
|
||||
ASSERT_TRUE(state->get_logged_out()->verification);
|
||||
EXPECT_EQ(state->get_logged_out()->verification->intent,
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
EXPECT_EQ(account_state_prefs.GetVerificationToken(
|
||||
mojom::LoggedOutVerificationIntent::kRegistration),
|
||||
test_case.encrypted_verification_token);
|
||||
}
|
||||
}
|
||||
@@ -932,8 +947,10 @@ struct RegisterVerifyTestCase {
|
||||
mojom::Authentication& authentication,
|
||||
base::OnceCallback<void(MojoExpected)> callback) {
|
||||
if (!test_case.encrypted_verification_token.empty()) {
|
||||
pref_service.SetString(prefs::kBraveAccountVerificationToken,
|
||||
test_case.encrypted_verification_token);
|
||||
AccountStatePrefs(pref_service)
|
||||
.SetLoggedOutWithVerification(
|
||||
test_case.encrypted_verification_token,
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
}
|
||||
|
||||
authentication.RegisterVerify(
|
||||
@@ -941,28 +958,27 @@ struct RegisterVerifyTestCase {
|
||||
std::move(callback).Then(base::BindOnce(
|
||||
[](PrefService* pref_service,
|
||||
std::string initial_verification_token, bool success) {
|
||||
AccountStatePrefs account_state_prefs(*pref_service);
|
||||
const auto state = account_state_prefs.GetAccountState();
|
||||
if (success) {
|
||||
EXPECT_EQ(
|
||||
pref_service->GetString(prefs::kBraveAccountEmailAddress),
|
||||
kEmailAddress);
|
||||
EXPECT_EQ(pref_service->GetString(
|
||||
prefs::kBraveAccountAuthenticationToken),
|
||||
ASSERT_TRUE(state->is_logged_in());
|
||||
EXPECT_EQ(state->get_logged_in()->email, kEmailAddress);
|
||||
EXPECT_FALSE(state->get_logged_in()->verification);
|
||||
EXPECT_EQ(account_state_prefs.GetAuthenticationToken(),
|
||||
EncryptedAuthenticationToken());
|
||||
EXPECT_TRUE(
|
||||
pref_service
|
||||
->GetString(prefs::kBraveAccountVerificationToken)
|
||||
.empty());
|
||||
} else {
|
||||
EXPECT_TRUE(
|
||||
pref_service->GetString(prefs::kBraveAccountEmailAddress)
|
||||
.empty());
|
||||
EXPECT_TRUE(
|
||||
pref_service
|
||||
->GetString(prefs::kBraveAccountAuthenticationToken)
|
||||
.empty());
|
||||
EXPECT_EQ(pref_service->GetString(
|
||||
prefs::kBraveAccountVerificationToken),
|
||||
initial_verification_token);
|
||||
ASSERT_TRUE(state->is_logged_out());
|
||||
if (initial_verification_token.empty()) {
|
||||
EXPECT_FALSE(state->get_logged_out()->verification);
|
||||
} else {
|
||||
ASSERT_TRUE(state->get_logged_out()->verification);
|
||||
EXPECT_EQ(state->get_logged_out()->verification->intent,
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
EXPECT_EQ(
|
||||
account_state_prefs.GetVerificationToken(
|
||||
mojom::LoggedOutVerificationIntent::kRegistration),
|
||||
initial_verification_token);
|
||||
}
|
||||
}
|
||||
},
|
||||
base::Unretained(&pref_service),
|
||||
@@ -994,7 +1010,7 @@ const RegisterVerifyTestCase* RegisterVerifyVerificationTokenEmpty() {
|
||||
base::unexpected(mojom::RegisterError::NewClientError(
|
||||
mojom::RegisterClientError::New(
|
||||
mojom::RegisterClientErrorCode::
|
||||
kUserNotInTheVerificationState))),
|
||||
kNoRegistrationInProgress))),
|
||||
});
|
||||
return kRegisterVerifyVerificationTokenEmpty.get();
|
||||
}
|
||||
@@ -1353,8 +1369,10 @@ struct ResendConfirmationEmailTestCase {
|
||||
mojom::Authentication& authentication,
|
||||
base::OnceCallback<void(MojoExpected)> callback) {
|
||||
if (!test_case.encrypted_verification_token.empty()) {
|
||||
pref_service.SetString(prefs::kBraveAccountVerificationToken,
|
||||
test_case.encrypted_verification_token);
|
||||
AccountStatePrefs(pref_service)
|
||||
.SetLoggedOutWithVerification(
|
||||
test_case.encrypted_verification_token,
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
}
|
||||
|
||||
authentication.ResendConfirmationEmail(std::move(callback));
|
||||
@@ -1381,7 +1399,7 @@ ResendConfirmationEmailVerificationTokenEmpty() {
|
||||
mojom::ResendConfirmationEmailError::NewClientError(
|
||||
mojom::ResendConfirmationEmailClientError::New(
|
||||
mojom::ResendConfirmationEmailClientErrorCode::
|
||||
kUserNotInTheVerificationState))),
|
||||
kNoRegistrationInProgress))),
|
||||
});
|
||||
return kResendConfirmationEmailVerificationTokenEmpty.get();
|
||||
}
|
||||
@@ -1609,19 +1627,24 @@ struct AuthValidateTestCase {
|
||||
PrefService& pref_service,
|
||||
base::test::TaskEnvironment& task_environment,
|
||||
base::OneShotTimer& auth_validate_timer) {
|
||||
AccountStatePrefs account_state_prefs(pref_service);
|
||||
if (test_case.logged_in) {
|
||||
pref_service.SetString(prefs::kBraveAccountEmailAddress, kEmailAddress);
|
||||
pref_service.SetString(prefs::kBraveAccountAuthenticationToken,
|
||||
EncryptedAuthenticationToken());
|
||||
account_state_prefs.SetLoggedIn(kEmailAddress,
|
||||
EncryptedAuthenticationToken());
|
||||
}
|
||||
|
||||
task_environment.FastForwardBy(kAuthValidatePollInterval -
|
||||
base::Seconds(1));
|
||||
|
||||
EXPECT_EQ(pref_service.GetString(prefs::kBraveAccountEmailAddress),
|
||||
test_case.expected_email);
|
||||
EXPECT_EQ(pref_service.GetString(prefs::kBraveAccountAuthenticationToken),
|
||||
test_case.expected_authentication_token);
|
||||
const auto state = account_state_prefs.GetAccountState();
|
||||
if (test_case.expected_authentication_token.empty()) {
|
||||
EXPECT_TRUE(state->is_logged_out());
|
||||
} else {
|
||||
ASSERT_TRUE(state->is_logged_in());
|
||||
EXPECT_EQ(state->get_logged_in()->email, test_case.expected_email);
|
||||
EXPECT_EQ(account_state_prefs.GetAuthenticationToken(),
|
||||
test_case.expected_authentication_token);
|
||||
}
|
||||
if (test_case.expected_auth_validate_timer_delay.is_zero()) {
|
||||
EXPECT_FALSE(auth_validate_timer.IsRunning());
|
||||
} else {
|
||||
@@ -1813,16 +1836,20 @@ struct CancelRegistrationTestCase {
|
||||
static void Run(const CancelRegistrationTestCase& test_case,
|
||||
PrefService& pref_service,
|
||||
mojom::Authentication& authentication) {
|
||||
pref_service.SetString(prefs::kBraveAccountVerificationToken,
|
||||
test_case.encrypted_verification_token);
|
||||
AccountStatePrefs account_state_prefs(pref_service);
|
||||
if (!test_case.encrypted_verification_token.empty()) {
|
||||
account_state_prefs.SetLoggedOutWithVerification(
|
||||
test_case.encrypted_verification_token,
|
||||
mojom::LoggedOutVerificationIntent::kRegistration);
|
||||
}
|
||||
authentication.CancelRegistration();
|
||||
EXPECT_EQ(pref_service.GetString(prefs::kBraveAccountVerificationToken),
|
||||
test_case.expected_verification_token);
|
||||
const auto state = account_state_prefs.GetAccountState();
|
||||
ASSERT_TRUE(state->is_logged_out());
|
||||
EXPECT_FALSE(state->get_logged_out()->verification);
|
||||
}
|
||||
|
||||
std::string test_name;
|
||||
std::string encrypted_verification_token;
|
||||
std::string expected_verification_token;
|
||||
};
|
||||
|
||||
namespace {
|
||||
@@ -1832,7 +1859,6 @@ const CancelRegistrationTestCase* CancelRegistrationVerificationTokenEmpty() {
|
||||
kCancelRegistrationVerificationTokenEmpty({
|
||||
.test_name = "cancel_registration_verification_token_empty",
|
||||
.encrypted_verification_token = "",
|
||||
.expected_verification_token = "",
|
||||
});
|
||||
return kCancelRegistrationVerificationTokenEmpty.get();
|
||||
}
|
||||
@@ -1843,7 +1869,6 @@ CancelRegistrationVerificationTokenNonEmpty() {
|
||||
kCancelRegistrationVerificationTokenNonEmpty({
|
||||
.test_name = "cancel_registration_verification_token_non_empty",
|
||||
.encrypted_verification_token = EncryptedVerificationToken(),
|
||||
.expected_verification_token = "",
|
||||
});
|
||||
return kCancelRegistrationVerificationTokenNonEmpty.get();
|
||||
}
|
||||
@@ -1869,19 +1894,20 @@ struct LogOutTestCase {
|
||||
static void Run(const LogOutTestCase& test_case,
|
||||
PrefService& pref_service,
|
||||
mojom::Authentication& authentication) {
|
||||
pref_service.SetString(prefs::kBraveAccountEmailAddress,
|
||||
test_case.email_address);
|
||||
pref_service.SetString(prefs::kBraveAccountAuthenticationToken,
|
||||
test_case.encrypted_authentication_token);
|
||||
AccountStatePrefs account_state_prefs(pref_service);
|
||||
if (!test_case.encrypted_authentication_token.empty()) {
|
||||
account_state_prefs.SetLoggedIn(test_case.email_address,
|
||||
test_case.encrypted_authentication_token);
|
||||
}
|
||||
authentication.LogOut();
|
||||
EXPECT_EQ(pref_service.GetString(prefs::kBraveAccountAuthenticationToken),
|
||||
test_case.expected_authentication_token);
|
||||
const auto state = account_state_prefs.GetAccountState();
|
||||
ASSERT_TRUE(state->is_logged_out());
|
||||
EXPECT_FALSE(state->get_logged_out()->verification);
|
||||
}
|
||||
|
||||
std::string test_name;
|
||||
std::string email_address;
|
||||
std::string encrypted_authentication_token;
|
||||
std::string expected_authentication_token;
|
||||
};
|
||||
|
||||
namespace {
|
||||
@@ -1892,7 +1918,6 @@ const LogOutTestCase* LogOutAuthenticationTokenEmpty() {
|
||||
.test_name = "log_out_authentication_token_empty",
|
||||
.email_address = "",
|
||||
.encrypted_authentication_token = "",
|
||||
.expected_authentication_token = "",
|
||||
});
|
||||
return kLogOutAuthenticationTokenEmpty.get();
|
||||
}
|
||||
@@ -1903,7 +1928,6 @@ const LogOutTestCase* LogOutAuthenticationTokenNonEmpty() {
|
||||
.test_name = "log_out_authentication_token_non_empty",
|
||||
.email_address = kEmailAddress,
|
||||
.encrypted_authentication_token = EncryptedAuthenticationToken(),
|
||||
.expected_authentication_token = "",
|
||||
});
|
||||
return kLogOutAuthenticationTokenNonEmpty.get();
|
||||
}
|
||||
@@ -2267,12 +2291,16 @@ struct LoginFinalizeTestCase {
|
||||
std::move(callback).Then(base::BindOnce(
|
||||
[](PrefService* pref_service, std::string expected_email,
|
||||
std::string expected_authentication_token) {
|
||||
EXPECT_EQ(
|
||||
pref_service->GetString(prefs::kBraveAccountEmailAddress),
|
||||
expected_email);
|
||||
EXPECT_EQ(pref_service->GetString(
|
||||
prefs::kBraveAccountAuthenticationToken),
|
||||
expected_authentication_token);
|
||||
AccountStatePrefs account_state_prefs(*pref_service);
|
||||
const auto state = account_state_prefs.GetAccountState();
|
||||
if (expected_authentication_token.empty()) {
|
||||
EXPECT_TRUE(state->is_logged_out());
|
||||
} else {
|
||||
ASSERT_TRUE(state->is_logged_in());
|
||||
EXPECT_EQ(state->get_logged_in()->email, expected_email);
|
||||
EXPECT_EQ(account_state_prefs.GetAuthenticationToken(),
|
||||
expected_authentication_token);
|
||||
}
|
||||
},
|
||||
base::Unretained(&pref_service), test_case.expected_email,
|
||||
test_case.expected_authentication_token)));
|
||||
@@ -2701,14 +2729,13 @@ struct GetServiceTokenTestCase {
|
||||
base::test::TaskEnvironment& task_environment,
|
||||
mojom::Authentication& authentication,
|
||||
base::OnceCallback<void(MojoExpected)> callback) {
|
||||
pref_service.SetDict(
|
||||
prefs::kBraveAccountServiceTokens,
|
||||
std::move(test_case.service_tokens_dict).Run(base::Time::Now()));
|
||||
|
||||
if (test_case.logged_in) {
|
||||
pref_service.SetString(prefs::kBraveAccountEmailAddress, kEmailAddress);
|
||||
pref_service.SetString(prefs::kBraveAccountAuthenticationToken,
|
||||
EncryptedAuthenticationToken());
|
||||
AccountStatePrefs(pref_service)
|
||||
.SetLoggedIn(kEmailAddress, EncryptedAuthenticationToken());
|
||||
ScopedDictPrefUpdate(&pref_service, prefs::kBraveAccountState)
|
||||
->Set(
|
||||
prefs::keys::kServiceTokens,
|
||||
std::move(test_case.service_tokens_dict).Run(base::Time::Now()));
|
||||
}
|
||||
|
||||
task_environment.FastForwardBy(test_case.time_advance);
|
||||
@@ -2726,13 +2753,16 @@ struct GetServiceTokenTestCase {
|
||||
std::move(callback).Then(base::BindOnce(
|
||||
[](PrefService* pref_service, std::string expected_service_token) {
|
||||
if (!expected_service_token.empty()) {
|
||||
const auto* service_tokens =
|
||||
pref_service->GetDict(prefs::kBraveAccountState)
|
||||
.FindDict(prefs::keys::kServiceTokens);
|
||||
ASSERT_TRUE(service_tokens);
|
||||
const auto* email_aliases =
|
||||
pref_service->GetDict(prefs::kBraveAccountServiceTokens)
|
||||
.FindDict("email-aliases");
|
||||
EXPECT_TRUE(email_aliases);
|
||||
service_tokens->FindDict("email-aliases");
|
||||
ASSERT_TRUE(email_aliases);
|
||||
const auto* service_token =
|
||||
email_aliases->FindString(prefs::keys::kServiceToken);
|
||||
EXPECT_TRUE(service_token);
|
||||
ASSERT_TRUE(service_token);
|
||||
EXPECT_EQ(*service_token,
|
||||
base::Base64Encode(expected_service_token));
|
||||
}
|
||||
@@ -2744,7 +2774,7 @@ struct GetServiceTokenTestCase {
|
||||
// be processed on the next message pump iteration, so this runs before the
|
||||
// request completes.
|
||||
if (test_case.clear_authentication_token) {
|
||||
pref_service.ClearPref(prefs::kBraveAccountAuthenticationToken);
|
||||
AccountStatePrefs(pref_service).SetLoggedOut();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2778,7 +2808,7 @@ const GetServiceTokenTestCase* GetServiceTokenCacheHit() {
|
||||
.Set(prefs::keys::kLastFetched,
|
||||
base::TimeToValue(mock_now)));
|
||||
}),
|
||||
.logged_in = {}, // not used
|
||||
.logged_in = true,
|
||||
.fail_decryption = {}, // not used
|
||||
.clear_authentication_token = {}, // not used
|
||||
.fail_encryption = {}, // not used
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/* Copyright (c) 2026 The Brave Authors. All rights reserved.
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_account/brave_account_state_prefs.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/json/values_util.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "brave/components/brave_account/brave_account_service_constants.h"
|
||||
#include "components/prefs/scoped_user_pref_update.h"
|
||||
|
||||
namespace brave_account {
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename VerificationPtr>
|
||||
auto MakeVerification(std::optional<int> verification_intent) {
|
||||
VerificationPtr verification;
|
||||
|
||||
if (verification_intent) {
|
||||
if (const auto intent =
|
||||
static_cast<decltype(verification->intent)>(*verification_intent);
|
||||
mojom::IsKnownEnumValue(intent)) {
|
||||
verification = VerificationPtr::Struct::New(intent);
|
||||
}
|
||||
}
|
||||
|
||||
return verification;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AccountStatePrefs::StartObserving(base::RepeatingClosure on_change) {
|
||||
pref_change_registrar_.Init(&*pref_service_);
|
||||
pref_change_registrar_.Add(prefs::kBraveAccountState, std::move(on_change));
|
||||
}
|
||||
|
||||
void AccountStatePrefs::SetLoggedOut() {
|
||||
pref_service_->SetDict(prefs::kBraveAccountState,
|
||||
base::DictValue().Set(prefs::keys::kKind,
|
||||
prefs::state_kinds::kLoggedOut));
|
||||
}
|
||||
|
||||
void AccountStatePrefs::SetLoggedOutWithVerification(
|
||||
const std::string& encrypted_verification_token,
|
||||
mojom::LoggedOutVerificationIntent intent) {
|
||||
CHECK(!encrypted_verification_token.empty());
|
||||
|
||||
pref_service_->SetDict(
|
||||
prefs::kBraveAccountState,
|
||||
base::DictValue()
|
||||
.Set(prefs::keys::kKind, prefs::state_kinds::kLoggedOut)
|
||||
.Set(prefs::keys::kVerification,
|
||||
base::DictValue()
|
||||
.Set(prefs::keys::kVerificationToken,
|
||||
encrypted_verification_token)
|
||||
.Set(prefs::keys::kVerificationIntent,
|
||||
static_cast<int>(intent))));
|
||||
}
|
||||
|
||||
void AccountStatePrefs::SetLoggedIn(
|
||||
const std::string& email,
|
||||
const std::string& encrypted_authentication_token) {
|
||||
CHECK(!email.empty());
|
||||
CHECK(!encrypted_authentication_token.empty());
|
||||
|
||||
pref_service_->SetDict(
|
||||
prefs::kBraveAccountState,
|
||||
base::DictValue()
|
||||
.Set(prefs::keys::kKind, prefs::state_kinds::kLoggedIn)
|
||||
.Set(prefs::keys::kEmail, email)
|
||||
.Set(prefs::keys::kAuthenticationToken,
|
||||
encrypted_authentication_token));
|
||||
}
|
||||
|
||||
mojom::AccountStatePtr AccountStatePrefs::GetAccountState() const {
|
||||
const auto& account_state = pref_service_->GetDict(prefs::kBraveAccountState);
|
||||
const auto* kind = account_state.FindString(prefs::keys::kKind);
|
||||
const auto* verification = account_state.FindDict(prefs::keys::kVerification);
|
||||
const auto intent =
|
||||
verification ? verification->FindInt(prefs::keys::kVerificationIntent)
|
||||
: std::nullopt;
|
||||
|
||||
if (kind && *kind == prefs::state_kinds::kLoggedIn) {
|
||||
const auto* email = account_state.FindString(prefs::keys::kEmail);
|
||||
CHECK(email && !email->empty());
|
||||
return mojom::AccountState::NewLoggedIn(mojom::LoggedInState::New(
|
||||
*email, MakeVerification<mojom::LoggedInVerificationPtr>(intent)));
|
||||
}
|
||||
|
||||
return mojom::AccountState::NewLoggedOut(mojom::LoggedOutState::New(
|
||||
MakeVerification<mojom::LoggedOutVerificationPtr>(intent)));
|
||||
}
|
||||
|
||||
std::string AccountStatePrefs::GetAuthenticationToken() const {
|
||||
const auto* token = pref_service_->GetDict(prefs::kBraveAccountState)
|
||||
.FindString(prefs::keys::kAuthenticationToken);
|
||||
return token ? *token : "";
|
||||
}
|
||||
|
||||
std::string AccountStatePrefs::GetCachedServiceToken(
|
||||
const std::string& service_name) const {
|
||||
CHECK(!service_name.empty());
|
||||
|
||||
const auto* service_tokens = pref_service_->GetDict(prefs::kBraveAccountState)
|
||||
.FindDict(prefs::keys::kServiceTokens);
|
||||
const auto* service =
|
||||
service_tokens ? service_tokens->FindDict(service_name) : nullptr;
|
||||
if (!service) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto* encrypted_service_token =
|
||||
service->FindString(prefs::keys::kServiceToken);
|
||||
const auto* last_fetched_value = service->Find(prefs::keys::kLastFetched);
|
||||
|
||||
if (!encrypted_service_token || !last_fetched_value) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto last_fetched_time = base::ValueToTime(*last_fetched_value);
|
||||
if (!last_fetched_time) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (base::Time::Now() - *last_fetched_time >= kServiceTokenMaxAge) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return *encrypted_service_token;
|
||||
}
|
||||
|
||||
void AccountStatePrefs::UpdateEmail(const std::string& email) {
|
||||
CHECK(!email.empty());
|
||||
|
||||
ScopedDictPrefUpdate(&*pref_service_, prefs::kBraveAccountState)
|
||||
->Set(prefs::keys::kEmail, email);
|
||||
}
|
||||
|
||||
void AccountStatePrefs::CacheServiceToken(const std::string& service_name,
|
||||
std::string encrypted_service_token) {
|
||||
CHECK(!service_name.empty());
|
||||
CHECK(!encrypted_service_token.empty());
|
||||
|
||||
ScopedDictPrefUpdate(&*pref_service_, prefs::kBraveAccountState)
|
||||
->EnsureDict(prefs::keys::kServiceTokens)
|
||||
->Set(service_name, base::DictValue()
|
||||
.Set(prefs::keys::kServiceToken,
|
||||
std::move(encrypted_service_token))
|
||||
.Set(prefs::keys::kLastFetched,
|
||||
base::TimeToValue(base::Time::Now())));
|
||||
}
|
||||
|
||||
} // namespace brave_account
|
||||
@@ -0,0 +1,91 @@
|
||||
/* Copyright (c) 2026 The Brave Authors. All rights reserved.
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_ACCOUNT_BRAVE_ACCOUNT_STATE_PREFS_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_ACCOUNT_BRAVE_ACCOUNT_STATE_PREFS_H_
|
||||
|
||||
#include <concepts>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/check_deref.h"
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/memory/raw_ref.h"
|
||||
#include "brave/components/brave_account/mojom/brave_account.mojom.h"
|
||||
#include "brave/components/brave_account/pref_names.h"
|
||||
#include "components/prefs/pref_change_registrar.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
|
||||
namespace brave_account {
|
||||
|
||||
// Typed view onto the kBraveAccountState pref dict.
|
||||
// Encapsulates the storage schema so callers (the service, tests)
|
||||
// don't have to know how the dict is laid out.
|
||||
class AccountStatePrefs {
|
||||
public:
|
||||
explicit AccountStatePrefs(PrefService& pref_service)
|
||||
: pref_service_(pref_service) {}
|
||||
|
||||
AccountStatePrefs(const AccountStatePrefs&) = delete;
|
||||
AccountStatePrefs& operator=(const AccountStatePrefs&) = delete;
|
||||
|
||||
void StartObserving(base::RepeatingClosure on_change);
|
||||
|
||||
void SetLoggedOut();
|
||||
|
||||
void SetLoggedOutWithVerification(
|
||||
const std::string& encrypted_verification_token,
|
||||
mojom::LoggedOutVerificationIntent intent);
|
||||
|
||||
void SetLoggedIn(const std::string& email,
|
||||
const std::string& encrypted_authentication_token);
|
||||
|
||||
mojom::AccountStatePtr GetAccountState() const;
|
||||
|
||||
std::string GetAuthenticationToken() const;
|
||||
|
||||
template <typename Intent>
|
||||
requires std::same_as<Intent, mojom::LoggedOutVerificationIntent> ||
|
||||
std::same_as<Intent, mojom::LoggedInVerificationIntent>
|
||||
std::string GetVerificationToken(Intent intent) const {
|
||||
const auto verification = [&] {
|
||||
const auto account_state = GetAccountState();
|
||||
if constexpr (std::same_as<Intent, mojom::LoggedOutVerificationIntent>) {
|
||||
return account_state->is_logged_out()
|
||||
? std::move(account_state->get_logged_out()->verification)
|
||||
: nullptr;
|
||||
} else {
|
||||
return account_state->is_logged_in()
|
||||
? std::move(account_state->get_logged_in()->verification)
|
||||
: nullptr;
|
||||
}
|
||||
}();
|
||||
|
||||
if (!verification || verification->intent != intent) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto* token =
|
||||
CHECK_DEREF(pref_service_->GetDict(prefs::kBraveAccountState)
|
||||
.FindDict(prefs::keys::kVerification))
|
||||
.FindString(prefs::keys::kVerificationToken);
|
||||
return token ? *token : "";
|
||||
}
|
||||
|
||||
std::string GetCachedServiceToken(const std::string& service_name) const;
|
||||
|
||||
void UpdateEmail(const std::string& email);
|
||||
|
||||
void CacheServiceToken(const std::string& service_name,
|
||||
std::string encrypted_service_token);
|
||||
|
||||
private:
|
||||
const raw_ref<PrefService> pref_service_;
|
||||
PrefChangeRegistrar pref_change_registrar_;
|
||||
};
|
||||
|
||||
} // namespace brave_account
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_ACCOUNT_BRAVE_ACCOUNT_STATE_PREFS_H_
|
||||
@@ -5,17 +5,40 @@
|
||||
|
||||
module brave_account.mojom;
|
||||
|
||||
struct LoggedOutState {};
|
||||
// These enum values are persisted to Preferences. Never reorder, repurpose,
|
||||
// or recycle a value — only append new ones with the next unused number.
|
||||
// When removing an enumerator, leave its number reserved as a comment.
|
||||
enum LoggedOutVerificationIntent {
|
||||
kRegistration = 0,
|
||||
kResetPassword = 1,
|
||||
};
|
||||
|
||||
struct VerificationState {};
|
||||
// These enum values are persisted to Preferences. Never reorder, repurpose,
|
||||
// or recycle a value — only append new ones with the next unused number.
|
||||
// When removing an enumerator, leave its number reserved as a comment.
|
||||
enum LoggedInVerificationIntent {
|
||||
kChangePassword = 0,
|
||||
};
|
||||
|
||||
struct LoggedOutVerification {
|
||||
LoggedOutVerificationIntent intent;
|
||||
};
|
||||
|
||||
struct LoggedInVerification {
|
||||
LoggedInVerificationIntent intent;
|
||||
};
|
||||
|
||||
struct LoggedOutState {
|
||||
LoggedOutVerification? verification;
|
||||
};
|
||||
|
||||
struct LoggedInState {
|
||||
string email;
|
||||
LoggedInVerification? verification;
|
||||
};
|
||||
|
||||
union AccountState {
|
||||
LoggedOutState logged_out;
|
||||
VerificationState verification;
|
||||
LoggedInState logged_in;
|
||||
};
|
||||
|
||||
@@ -39,7 +62,7 @@ enum RegisterClientErrorCode {
|
||||
kOpaqueError,
|
||||
kVerificationTokenEncryptionFailed,
|
||||
kVerificationTokenDecryptionFailed,
|
||||
kUserNotInTheVerificationState,
|
||||
kNoRegistrationInProgress,
|
||||
kAuthenticationTokenEncryptionFailed,
|
||||
};
|
||||
|
||||
@@ -158,7 +181,7 @@ struct ResendConfirmationEmailResult {
|
||||
|
||||
enum ResendConfirmationEmailClientErrorCode {
|
||||
kUnexpected,
|
||||
kUserNotInTheVerificationState,
|
||||
kNoRegistrationInProgress,
|
||||
kVerificationTokenDecryptionFailed,
|
||||
};
|
||||
|
||||
|
||||
@@ -8,57 +8,102 @@
|
||||
|
||||
namespace brave_account::prefs {
|
||||
|
||||
// This preference will store (`OSCrypt`-encrypted) the `verificationToken`
|
||||
// returned by the POST /v2/accounts/password/init endpoint.
|
||||
// It is then used for:
|
||||
// - calling POST /v2/accounts/password/finalize
|
||||
// to complete the registration flow
|
||||
// - polling POST /v2/verify/result
|
||||
// to exchange the `verificationToken` for the `authToken`
|
||||
// after the user has verified their email
|
||||
inline constexpr char kBraveAccountVerificationToken[] =
|
||||
"brave.account.verification_token";
|
||||
|
||||
// This preference will store (`OSCrypt`-encrypted) the (JWT) `authToken`
|
||||
// returned by the POST /v2/verify/result endpoint.
|
||||
// It is then used for:
|
||||
// - authenticating subsequent Brave Account requests
|
||||
// - creating new service tokens
|
||||
inline constexpr char kBraveAccountAuthenticationToken[] =
|
||||
"brave.account.authentication_token";
|
||||
|
||||
// This preference will store the email address of the authenticated user
|
||||
// returned by the GET /v2/auth/validate endpoint.
|
||||
inline constexpr char kBraveAccountEmailAddress[] =
|
||||
"brave.account.email_address";
|
||||
|
||||
// This preference will store a dictionary of service tokens with their
|
||||
// fetch times. Each entry maps a service name to a dict containing:
|
||||
// - "service_token": the service token (`OSCrypt`-encrypted)
|
||||
// - "last_fetched": when the service token was retrieved (base::Time as
|
||||
// base::Value via base::TimeToValue())
|
||||
// This preference stores the entire account state as a single dictionary,
|
||||
// keyed by "kind" ("logged-out" or "logged-in"). All state transitions write
|
||||
// the whole dictionary in one shot, so observers see one consistent state per
|
||||
// notification.
|
||||
//
|
||||
// Example:
|
||||
// ...
|
||||
// "service_tokens": {
|
||||
// "email-aliases": {
|
||||
// "last_fetched": "...",
|
||||
// "service_token": "..."
|
||||
// },
|
||||
// ...
|
||||
// First launch, no Brave Account ever used — equivalent to logged-out:
|
||||
// The "account" dict in Preferences doesn't exist.
|
||||
//
|
||||
// Registration in progress — logged-out, with verification:
|
||||
// "account": {
|
||||
// "state": {
|
||||
// "kind": "logged-out",
|
||||
// "verification": {
|
||||
// "intent": 0,
|
||||
// "token": "..."
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// ...
|
||||
inline constexpr char kBraveAccountServiceTokens[] =
|
||||
"brave.account.service_tokens";
|
||||
//
|
||||
// Email verified, or returning user logged in — logged-in,
|
||||
// optionally including service tokens:
|
||||
// "account": {
|
||||
// "state": {
|
||||
// "authentication_token": "...",
|
||||
// "email": "...",
|
||||
// "kind": "logged-in",
|
||||
// "service_tokens": {
|
||||
// "email-aliases": {
|
||||
// "last_fetched": "13422130435353472",
|
||||
// "service_token": "..."
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
//
|
||||
// Password change in progress — logged-in, with verification:
|
||||
// "account": {
|
||||
// "state": {
|
||||
// "authentication_token": "...",
|
||||
// "email": "...",
|
||||
// "kind": "logged-in"
|
||||
// "verification": {
|
||||
// "intent": 0,
|
||||
// "token": "..."
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
//
|
||||
// Logged out — logged-out:
|
||||
// "account": {
|
||||
// "state": {
|
||||
// "kind": "logged-out"
|
||||
// }
|
||||
// },
|
||||
//
|
||||
// Password reset in progress — logged-out, with verification:
|
||||
// "account": {
|
||||
// "state": {
|
||||
// "kind": "logged-out",
|
||||
// "verification": {
|
||||
// "intent": 1,
|
||||
// "token": "..."
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
inline constexpr char kBraveAccountState[] = "brave.account.state";
|
||||
|
||||
namespace keys {
|
||||
|
||||
// Dictionary keys used within kBraveAccountServiceTokens.
|
||||
inline constexpr char kServiceToken[] = "service_token";
|
||||
// Top-level dictionary keys used within kBraveAccountState.
|
||||
inline constexpr char kAuthenticationToken[] = "authentication_token";
|
||||
inline constexpr char kEmail[] = "email";
|
||||
inline constexpr char kKind[] = "kind";
|
||||
inline constexpr char kServiceTokens[] = "service_tokens";
|
||||
inline constexpr char kVerification[] = "verification";
|
||||
|
||||
// Dictionary keys used within the "verification" sub-dict of
|
||||
// kBraveAccountState.
|
||||
inline constexpr char kVerificationIntent[] = "intent";
|
||||
inline constexpr char kVerificationToken[] = "token";
|
||||
|
||||
// Dictionary keys used within entries of the "service_tokens" sub-dict of
|
||||
// kBraveAccountState.
|
||||
inline constexpr char kLastFetched[] = "last_fetched";
|
||||
inline constexpr char kServiceToken[] = "service_token";
|
||||
|
||||
} // namespace keys
|
||||
|
||||
namespace state_kinds {
|
||||
|
||||
// Values for the kKind field within kBraveAccountState.
|
||||
inline constexpr char kLoggedIn[] = "logged-in";
|
||||
inline constexpr char kLoggedOut[] = "logged-out";
|
||||
|
||||
} // namespace state_kinds
|
||||
|
||||
} // namespace brave_account::prefs
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_ACCOUNT_PREF_NAMES_H_
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "brave/components/brave_account/prefs.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "brave/components/brave_account/features.h"
|
||||
#include "brave/components/brave_account/pref_names.h"
|
||||
@@ -16,12 +14,7 @@ namespace brave_account::prefs {
|
||||
|
||||
void RegisterPrefs(PrefRegistrySimple* registry) {
|
||||
if (features::IsBraveAccountEnabled()) {
|
||||
registry->RegisterStringPref(kBraveAccountVerificationToken, std::string());
|
||||
registry->RegisterStringPref(kBraveAccountAuthenticationToken,
|
||||
std::string());
|
||||
registry->RegisterStringPref(kBraveAccountEmailAddress, std::string());
|
||||
registry->RegisterDictionaryPref(kBraveAccountServiceTokens,
|
||||
base::DictValue());
|
||||
registry->RegisterDictionaryPref(kBraveAccountState, base::DictValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,8 +68,8 @@ export class BraveAccountDialogsElement extends CrLitElement {
|
||||
// </if>
|
||||
|
||||
// Handle account state changes.
|
||||
// LOGGED_OUT: show the ENTRY dialog
|
||||
// VERIFICATION: show the OTP dialog
|
||||
// LOGGED_OUT (no verification): show the ENTRY dialog
|
||||
// LOGGED_OUT (with verification): show the OTP dialog
|
||||
// LOGGED_IN: close the native dialog
|
||||
// Since account state is profile-wide, this automatically updates dialogs
|
||||
// across all tabs.
|
||||
@@ -78,10 +78,7 @@ export class BraveAccountDialogsElement extends CrLitElement {
|
||||
(state: AccountState) => {
|
||||
switch (whichAccountState(state)) {
|
||||
case AccountStateFieldTags.LOGGED_OUT:
|
||||
this.dialog = 'ENTRY'
|
||||
break
|
||||
case AccountStateFieldTags.VERIFICATION:
|
||||
this.dialog = 'OTP'
|
||||
this.dialog = state.loggedOut!.verification ? 'OTP' : 'ENTRY'
|
||||
break
|
||||
case AccountStateFieldTags.LOGGED_IN:
|
||||
this.onCloseDialog()
|
||||
|
||||
@@ -53,6 +53,7 @@ static_library("service") {
|
||||
"//base",
|
||||
"//brave/brave_domains",
|
||||
"//brave/components/brave_account",
|
||||
"//brave/components/brave_account:internal",
|
||||
"//brave/components/brave_account/endpoint_client",
|
||||
"//brave/components/brave_account/mojom",
|
||||
"//brave/components/constants",
|
||||
|
||||
@@ -28,17 +28,10 @@ EmailAliasesAuth::EmailAliasesAuth(
|
||||
base::Unretained(
|
||||
this))); // Unretained is safe because we own the remote<>
|
||||
|
||||
// TODO(https://github.com/brave/brave-browser/issues/55179)
|
||||
pref_change_registrar_.Init(&prefs_service_.get());
|
||||
pref_change_registrar_.Add(
|
||||
brave_account::prefs::kBraveAccountServiceTokens,
|
||||
base::BindRepeating(&EmailAliasesAuth::OnPrefChanged,
|
||||
base::Unretained(this)));
|
||||
pref_change_registrar_.Add(
|
||||
brave_account::prefs::kBraveAccountAuthenticationToken,
|
||||
base::BindRepeating(&EmailAliasesAuth::OnPrefChanged,
|
||||
base::Unretained(this)));
|
||||
pref_change_registrar_.Add(
|
||||
brave_account::prefs::kBraveAccountEmailAddress,
|
||||
brave_account::prefs::kBraveAccountState,
|
||||
base::BindRepeating(&EmailAliasesAuth::OnPrefChanged,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
@@ -54,8 +47,10 @@ std::string EmailAliasesAuth::GetAuthEmail() const {
|
||||
CHECK_IS_TEST();
|
||||
return auth_email_for_testing_.value();
|
||||
}
|
||||
return prefs_service_->GetString(
|
||||
brave_account::prefs::kBraveAccountEmailAddress);
|
||||
const auto* email =
|
||||
prefs_service_->GetDict(brave_account::prefs::kBraveAccountState)
|
||||
.FindString(brave_account::prefs::keys::kEmail);
|
||||
return email ? *email : "";
|
||||
}
|
||||
|
||||
void EmailAliasesAuth::GetServiceToken(
|
||||
|
||||
@@ -447,7 +447,7 @@ class SettingsViewController: TableViewController, BraveAccountAuthenticationObs
|
||||
),
|
||||
]
|
||||
)
|
||||
case .verification:
|
||||
case .loggedOut where braveAccountState.loggedOut!.verification != nil:
|
||||
return Static.Section(
|
||||
header: .title(L10nUtils.string(messageId: .BRAVE_ACCOUNT_TITLE)),
|
||||
rows: [
|
||||
|
||||
Reference in New Issue
Block a user