fix: dedupe Tokens Studio OAuth sync providers#3878
Conversation
Tokens Studio OAuth providers are derived live from the user's organizations on every load. A regression in BranchSelector was persisting them to clientStorage when switching branches, which caused the same workspace to appear twice in Sync Settings (one live row + one stale persisted row) and pinned sync operations to the stale entry. - Short-circuit updateCredentials for TOKENS_STUDIO_OAUTH so OAuth providers are never persisted. - Strip any legacy persisted OAuth entries when reading apiProviders to clean up existing users without requiring manual deletion. - Defensively dedupe apiProviders against live studioProviders by internalId in SyncSettings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
|
|
Commit SHA:f12213f19357da92f8757f81696f68c9c83d3b35 Test coverage results 🧪
|
|
Commit SHA:f12213f19357da92f8757f81696f68c9c83d3b35 |
|
🛡️ Hyma Compliance Check
Full finding details[Access Control] OAuth providers stripped from Figma storage persistence and UI
|
|
🛡️ Hyma Compliance Check
Full finding details[Access Control] OAuth sync credentials are no longer persisted to clientStorage and legacy entries are stripped on read
|
|
🛡️ Hyma Compliance Check ✅ No compliance-relevant changes detected Files scanned · 0 findings No new external calls, personal data processing changes, or authentication/authorization modifications detected. No compliance action required.
|
|
🛡️ Hyma Compliance Check
Full finding details[Access Control] OAuth credentials no longer persisted to client storage; legacy entries stripped
|
|
🛡️ Hyma Compliance Check
Full finding details[Access Control] Tokens Studio OAuth provider entries are no longer persisted to Figma clientStorage and legacy entries are stripped on read
|
Problem
Some users on the new Studio (OAuth) sync see the same workspace listed twice under Settings → Sync providers, and sync silently uses a stale entry.
Repro
Root cause
OAuth sync providers (
TOKENS_STUDIO_OAUTH) are designed to be derived live on every plugin load from the user's organizations (SyncSettings.tsx→studioProvidersmemo). They should never live infigma.clientStorage.BranchSelector.tsxcallsAsyncMessageTypes.CREDENTIALSon every branch switch — including for OAuth providers — which routes throughupdateCredentialsand persists the OAuth credential intoapiProvidersclientStorage. On the next load:studioProvidersre-derives the OAuth row fromorganizations(correct, live).apiProvidersis loaded from clientStorage and includes the now-stale OAuth row.Whichever entry happens to win
storageTypemay carry a stale token / branch / context, which is why sync also "stops working" for affected users.Fix
utils/credentials.ts– short-circuitupdateCredentialsforTOKENS_STUDIO_OAUTH. OAuth providers must never be persisted.figmaStorage/ApiProvidersProperty.ts– strip anyTOKENS_STUDIO_OAUTHentries when readingapiProviders. This auto-cleans existing affected users on next plugin load — no manual intervention needed.app/components/SyncSettings.tsx– defensively filterapiProvidersagainst livestudioProvidersinternalIds (and drop OAuth) so even a stale in-memory state can never render duplicates.Tests
updateCredentialstest asserting OAuth providers are not persisted.Notes
Did not modify the offending
BranchSelectorcall site directly becauseupdateCredentialsis the right place to enforce this invariant —BranchSelectorlegitimately needs to persist branch changes for non-OAuth providers, and there are other callers (jsonbin, github, gitlab, ado, bitbucket, supernova, generic versioned, tokensStudio PAT) that should keep persisting.