From ad4b553bb1edec6387b0b6418f6204f61ff2a499 Mon Sep 17 00:00:00 2001 From: leileizhang Date: Fri, 14 Nov 2025 16:15:15 +0800 Subject: [PATCH] Remove all AdvancedPaste stored keys during uninstall (#43563) ## Summary of the Pull Request Remove all AdvancedPaste stored keys during uninstall ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../CustomAction.cpp | 66 +++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/installer/PowerToysSetupCustomActionsVNext/CustomAction.cpp b/installer/PowerToysSetupCustomActionsVNext/CustomAction.cpp index 0cfc3b1765..968fcc2530 100644 --- a/installer/PowerToysSetupCustomActionsVNext/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActionsVNext/CustomAction.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "../../src/common/logger/logger.h" #include "../../src/common/utils/gpo.h" @@ -856,14 +857,69 @@ UINT __stdcall UnsetAdvancedPasteAPIKeyCA(MSIHANDLE hInstall) try { - winrt::Windows::Security::Credentials::PasswordVault vault; - winrt::Windows::Security::Credentials::PasswordCredential cred; - hr = WcaInitialize(hInstall, "UnsetAdvancedPasteAPIKey"); ExitOnFailure(hr, "Failed to initialize"); - cred = vault.Retrieve(L"https://platform.openai.com/api-keys", L"PowerToys_AdvancedPaste_OpenAIKey"); - vault.Remove(cred); + winrt::Windows::Security::Credentials::PasswordVault vault; + + auto hasPrefix = [](std::wstring_view value, wchar_t const* prefix) { + std::wstring_view prefixView{ prefix }; + return value.compare(0, prefixView.size(), prefixView) == 0; + }; + + const wchar_t* resourcePrefixes[] = { + L"https://platform.openai.com/api-keys", + L"https://azure.microsoft.com/products/ai-services/openai-service", + L"https://azure.microsoft.com/products/ai-services/ai-inference", + L"https://console.mistral.ai/account/api-keys", + L"https://ai.google.dev/", + }; + + const wchar_t* usernamePrefixes[] = { + L"PowerToys_AdvancedPaste_", + }; + + auto credentials = vault.RetrieveAll(); + for (auto const& credential : credentials) + { + bool shouldRemove = false; + + std::wstring resource{ credential.Resource() }; + for (auto const prefix : resourcePrefixes) + { + if (hasPrefix(resource, prefix)) + { + shouldRemove = true; + break; + } + } + + if (!shouldRemove) + { + std::wstring username{ credential.UserName() }; + for (auto const prefix : usernamePrefixes) + { + if (hasPrefix(username, prefix)) + { + shouldRemove = true; + break; + } + } + } + + if (!shouldRemove) + { + continue; + } + + try + { + vault.Remove(credential); + } + catch (...) + { + } + } } catch (...) {