diff --git a/components/record_replay/services/auth_token/public/cpp/auth_token_service.cc b/components/record_replay/services/auth_token/public/cpp/auth_token_service.cc index 6b529e8299e4bd..95c2917f07353c 100644 --- a/components/record_replay/services/auth_token/public/cpp/auth_token_service.cc +++ b/components/record_replay/services/auth_token/public/cpp/auth_token_service.cc @@ -3,11 +3,20 @@ // found in the LICENSE file. #include "components/record_replay/services/auth_token/public/cpp/auth_token_service.h" + +#include "chrome/browser/profiles/profile.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/scoped_user_pref_update.h" #include "content/public/browser/service_process_host.h" +namespace { + const char kRecordReplayPrefsKey[] = "record_replay"; +} + namespace auth_token { -RecordReplayAuthTokenService::RecordReplayAuthTokenService() = default; +RecordReplayAuthTokenService::RecordReplayAuthTokenService(Profile* profile) + : profile_(profile) {} RecordReplayAuthTokenService::~RecordReplayAuthTokenService() = default; void RecordReplayAuthTokenService::BindAuthTokenStore( @@ -16,19 +25,37 @@ void RecordReplayAuthTokenService::BindAuthTokenStore( auth_token_stores_.Add(this, std::move(store)); } -void RecordReplayAuthTokenService::SetToken(const std::string& token) { - token_ = token; - NotifyObservers(); +void RecordReplayAuthTokenService::SetUserToken(const std::string& user_token) { + ScopedDictPrefUpdate record_replay_prefs(profile_->GetPrefs(), + kRecordReplayPrefsKey); + record_replay_prefs->SetByDottedPath("user_token", user_token); + user_token_ = user_token; + NotifyObserversAboutUserToken(); +} + +void RecordReplayAuthTokenService::SetRefreshToken(const std::string& refresh_token) { + ScopedDictPrefUpdate record_replay_prefs(profile_->GetPrefs(), + kRecordReplayPrefsKey); + record_replay_prefs->SetByDottedPath("refresh_token", refresh_token); + refresh_token_ = refresh_token; + NotifyObserversAboutRefreshToken(); } void RecordReplayAuthTokenService::AddObserver(mojo::PendingRemote observer) { observers_.Add(std::move(observer)); - NotifyObservers(); + NotifyObserversAboutUserToken(); + NotifyObserversAboutRefreshToken(); +} + +void RecordReplayAuthTokenService::NotifyObserversAboutUserToken() { + for (auto& observer : observers_) { + observer->OnRecordReplayAuthTokenChanged(user_token_); + } } -void RecordReplayAuthTokenService::NotifyObservers() { +void RecordReplayAuthTokenService::NotifyObserversAboutRefreshToken() { for (auto& observer : observers_) { - observer->OnRecordReplayAuthTokenChanged(token_); + observer->OnRecordReplayRefreshTokenChanged(refresh_token_); } } diff --git a/components/record_replay/services/auth_token/public/cpp/auth_token_service.h b/components/record_replay/services/auth_token/public/cpp/auth_token_service.h index 1d5b20d9b7e211..7342c5a6fefbed 100644 --- a/components/record_replay/services/auth_token/public/cpp/auth_token_service.h +++ b/components/record_replay/services/auth_token/public/cpp/auth_token_service.h @@ -13,11 +13,13 @@ #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote_set.h" +class Profile; + namespace auth_token { class RecordReplayAuthTokenService : public KeyedService, public mojom::RecordReplayAuthTokenStore { public: - RecordReplayAuthTokenService(); + RecordReplayAuthTokenService(Profile* profile); RecordReplayAuthTokenService(const RecordReplayAuthTokenService&) = delete; RecordReplayAuthTokenService& operator=(const RecordReplayAuthTokenService&) = delete; ~RecordReplayAuthTokenService() override; @@ -26,15 +28,19 @@ class RecordReplayAuthTokenService : public KeyedService, public mojom::RecordRe mojo::PendingReceiver store); // mojom::RecordReplayAuthTokenStore: - void SetToken(const std::string& token) override; + void SetUserToken(const std::string& user_token) override; + void SetRefreshToken(const std::string& refresh_token) override; void AddObserver(mojo::PendingRemote observer) override; private: + raw_ptr profile_; mojo::ReceiverSet auth_token_stores_; - std::string token_; + std::string user_token_; + std::string refresh_token_; - void NotifyObservers(); + void NotifyObserversAboutUserToken(); + void NotifyObserversAboutRefreshToken(); mojo::RemoteSet observers_; }; diff --git a/components/record_replay/services/auth_token/public/cpp/auth_token_service_factory.cc b/components/record_replay/services/auth_token/public/cpp/auth_token_service_factory.cc index ba4d2acdbea692..8b4ab3b5f3568f 100644 --- a/components/record_replay/services/auth_token/public/cpp/auth_token_service_factory.cc +++ b/components/record_replay/services/auth_token/public/cpp/auth_token_service_factory.cc @@ -4,6 +4,7 @@ #include "components/record_replay/services/auth_token/public/cpp/auth_token_service_factory.h" +#include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_context.h" @@ -31,8 +32,9 @@ RecordReplayAuthTokenServiceFactory::RecordReplayAuthTokenServiceFactory() RecordReplayAuthTokenServiceFactory::~RecordReplayAuthTokenServiceFactory() = default; KeyedService* RecordReplayAuthTokenServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* /*context*/) const { - return new auth_token::RecordReplayAuthTokenService(); + content::BrowserContext* context) const { + return new auth_token::RecordReplayAuthTokenService( + Profile::FromBrowserContext(context)); } // Incognito profiles should use their own instance. diff --git a/components/record_replay/services/auth_token/public/mojom/auth_token.mojom b/components/record_replay/services/auth_token/public/mojom/auth_token.mojom index 9e07f60bec78d0..ecb93361507124 100644 --- a/components/record_replay/services/auth_token/public/mojom/auth_token.mojom +++ b/components/record_replay/services/auth_token/public/mojom/auth_token.mojom @@ -2,7 +2,8 @@ module auth_token.mojom; // Interface to passing updated token around interface RecordReplayAuthTokenStore { - SetToken(string token); + SetUserToken(string user_token); + SetRefreshToken(string refresh_token); AddObserver(pending_remote observer); // how do we remove? @@ -10,4 +11,5 @@ interface RecordReplayAuthTokenStore { interface RecordReplayAuthTokenStoreObserver { OnRecordReplayAuthTokenChanged(string token); + OnRecordReplayRefreshTokenChanged(string refresh_token); }; diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index 805f7937fb1272..c1357f87dde9b3 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc @@ -1522,4 +1522,51 @@ void LocalFrameMojoHandler::OnRecordReplayAuthTokenChanged(const WTF::String& to ); } +void LocalFrameMojoHandler::OnRecordReplayRefreshTokenChanged(const WTF::String& token) { + v8::Isolate* isolate = ToIsolate(frame_); + v8::HandleScope handle_scope(isolate); + + ScriptState* script_state = ToScriptStateForMainWorld(frame_); + v8::Local context = script_state->GetContext(); + v8::Context::Scope context_scope(context); + + // build up a JS object corresponding to the structure the devtools + // expects to receive: + // + // detail = { + // message: { + // token: "...", + // error?: "...", + // } + // } + // + // we don't currently receive an error from the auth token service, so we don't fill it in. + // if there was an error, presumably we wouldn't be called here. + + v8::Local message = v8::Object::New(isolate); + message->Set(context, V8String(isolate, "token"), + V8String(isolate, token)) + .Check(); + + v8::Local detail = v8::Object::New(isolate); + detail->Set(context, V8String(isolate, "message"), message) + .Check(); + + + ExceptionState exception_state(isolate, ExceptionState::kExecutionContext, + "LocalFrameMojoHandler", "OnTokenChanged"); + + CustomEventInit* ev_init = CustomEventInit::Create(isolate, v8::Null(isolate), exception_state); + // bail if the creator of the event threw an exception + if (exception_state.HadException()) { + return; + } + + ev_init->setDetail(ScriptValue::From(script_state, detail)); + + frame_->DomWindow()->DispatchEvent( + *CustomEvent::Create(script_state, "WebChannelMessageToContent", ev_init) + ); +} + } // namespace blink diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h index 9004b7d7537e0a..6f5486e40186a0 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h @@ -251,6 +251,7 @@ class LocalFrameMojoHandler // RecordReplayAuthTokenStoreObserver implementation: void OnRecordReplayAuthTokenChanged(const WTF::String& token) final; + void OnRecordReplayRefreshTokenChanged(const WTF::String& token) final; Member frame_;