diff --git a/app_check/src/desktop/debug_provider_desktop.cc b/app_check/src/desktop/debug_provider_desktop.cc index e7658ee371..dcccc47f1e 100644 --- a/app_check/src/desktop/debug_provider_desktop.cc +++ b/app_check/src/desktop/debug_provider_desktop.cc @@ -15,8 +15,11 @@ #include "app_check/src/desktop/debug_provider_desktop.h" #include +#include +#include #include #include +#include #include #include @@ -26,6 +29,7 @@ #include "app/rest/util.h" #include "app/src/log.h" #include "app/src/scheduler.h" +#include "app/src/uuid.h" #include "app_check/src/desktop/debug_token_request.h" #include "app_check/src/desktop/token_response.h" #include "firebase/app_check/debug_provider.h" @@ -34,6 +38,22 @@ namespace firebase { namespace app_check { namespace internal { +namespace { +std::string GenerateUuidString() { + firebase::internal::Uuid uuid; + uuid.Generate(); + char uuid_str[37]; + snprintf( + uuid_str, sizeof(uuid_str), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.data[0], uuid.data[1], uuid.data[2], uuid.data[3], uuid.data[4], + uuid.data[5], uuid.data[6], uuid.data[7], uuid.data[8], uuid.data[9], + uuid.data[10], uuid.data[11], uuid.data[12], uuid.data[13], uuid.data[14], + uuid.data[15]); + return std::string(uuid_str); +} +} // namespace + class DebugAppCheckProvider : public AppCheckProvider { public: DebugAppCheckProvider(App* app, const std::string& token); @@ -115,23 +135,56 @@ void DebugAppCheckProvider::GetTokenInternal( bool limited_use, std::function completion_callback) { - // Identify the user's debug token - const char* debug_token_cstr; - if (!debug_token_.empty()) { - debug_token_cstr = debug_token_.c_str(); - } else { - debug_token_cstr = std::getenv("APP_CHECK_DEBUG_TOKEN"); + static std::mutex token_mutex; + static bool logged_token = false; + std::string message_to_log; + + { + std::lock_guard lock(token_mutex); + if (debug_token_.empty()) { + if (const char* env_token = std::getenv("APP_CHECK_DEBUG_TOKEN")) { + debug_token_ = env_token; + } else { + debug_token_ = GenerateUuidString(); + } + } + + if (!logged_token && !debug_token_.empty()) { + logged_token = true; + std::string app_id = app_->options().app_id(); + std::string project_id = app_->options().project_id(); + message_to_log = + std::string("\nWARNING: Firebase App Check debug token: ") + + debug_token_ + "\n\n" + + "To use this token for app debugging, register it with your " + "project.\n\n" + + "You can do so in the Firebase Console: \n" + + "https://console.firebase.google.com/project/" + project_id + + "/appcheck/apps?selectedAppId=" + app_id + " \n\n" + + "Or using the Firebase CLI: \n" + + "firebase appcheck:debugtokens:create " + debug_token_ + " --app " + + app_id + "\n\n" + + "Note: To keep your project secure, please revoke and delete this " + "token using the \n" + + "Firebase Console or the CLI (`firebase " + "appcheck:debugtokens:delete`) " + "when you finish debugging.\n\n" + + "Warning: This debug token is a secret and should not be shared or " + "uploaded to source code.\n\n" + + "Debug Token Guide: " + "https://firebase.google.com/docs/app-check/ios/debug-provider\n" + + "Firebase CLI install instructions: " + "https://firebase.google.com/docs/cli\n"; + } } - if (!debug_token_cstr) { - completion_callback({}, kAppCheckErrorInvalidConfiguration, - "Missing debug token"); - return; + if (!message_to_log.empty()) { + firebase::LogWarning("%s", message_to_log.c_str()); } // Exchange debug token with the backend to get a proper attestation token. auto request = std::make_shared(app_); - request->SetDebugToken(debug_token_cstr); + request->SetDebugToken(debug_token_); request->SetLimitedUse(limited_use); // Use an async call, since we don't want to block on the server response. diff --git a/release_build_files/readme.md b/release_build_files/readme.md index 2fef1d63ac..854766d082 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -615,6 +615,7 @@ code. ## Release Notes ### Upcoming - Changes + - App Check (Desktop): The App Check Debug Provider will now automatically generate a local debug token if one isn't provided, and print instructions for registering it via the Firebase Console or CLI. - General (iOS): Fixed an issue where prebuilt iOS/tvOS frameworks had an incorrect minimum deployment target (minos), which caused linker warnings. - Auth (Desktop): Fixed log spam and high CPU utilization when offline by moving `USE_AUTH_EMULATOR` environment variable check to initialization and eliminating per-request logging (#1629). - Messaging: Added new Registration methods using Installation Ids.