Repository navigation
refactor(credentials): derive API key handling from one table - #537
Merged
Merged
Conversation
Each test passes on the hand-written code. Together they catch wrong derivations that no existing test sees: the -1 SecretStorage ID suffix that released versions accept, the provider an export error names, the kind a settings key row adopts a secret for, and the key migration notices.
CREDENTIALS in src/types/Credentials.ts holds each kind's settings field, export key and label. The credential repository, settings decoder, settings transfer, settings tab and key migration notice loop over it. IPodNotesSettings takes its key fields from it, so a kind with no default in DEFAULT_SETTINGS fails typecheck. The plaintext key map from before 2.19.0 stays fixed.
Deploying podnotes with
|
| Latest commit: |
1a2b833
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://ed3f59f0.podnotes.pages.dev |
| Branch Preview URL: | https://refactor-credentials-table.podnotes.pages.dev |
chhoumann
marked this pull request as ready for review
November 14, 2026 14:49
Owner
Author
|
PASS+NOTES
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PodNotes is moving transcription to more providers (OpenAI, ElevenLabs, OpenRouter, Deepgram), and adding a provider's API key should take one table row. This is step 1 of that plan, with no change in behavior.
CREDENTIALSinsrc/types/Credentials.tsholds each kind's settings field, export key, and label.CredentialKindis the table's keys.IPodNotesSettingstakes its key fields from the table, so a kind with no default inDEFAULT_SETTINGSfails typecheck.podnotes-<kind>-api-key, with an optional-<n>suffix. The validator still accepts-1.openAIApiKey,diarizationApiKey) stays fixed.The first commit adds five tests that pass on the old code. They cover derivations that no existing test checked.
Verification
Commands, with Node 22 (
fnm exec --using 22.23.2):npm run lint,npm run format:check,npm run typecheck,npm run build: pass.npm run test: svelte-check 0 errors and 0 warnings, 2831 tests pass. The tests-only commit also passes all 2831 on the old source.npm run test:tooling: 47 tests pass.npm run build && npm run size: gzip (level 9) 103,371 bytes before, 103,332 after. Raw 318,892 before, 318,544 after.Plants, each run with
npm run plant. Every plant fails its named test and passes once restored:exports only values whose referenced secrets still exist(CredentialRepository.test.ts).stores credentials under fixed PodNotes IDs and verifies them(CredentialRepository.test.ts).preserves provider-owned SecretStorage IDs and removes tampered v2 references(podNotesData.test.ts).rejects a malformed v2 secrets payload(settingsTransfer.test.ts).parses the v2 secrets payload separately from settings(settingsTransfer.test.ts).an API key's button keeps its own words and adds its row's name(PodNotesSettingsTab.test.ts).-1, as the design sketch proposed. Caught by newkeeps every numbered SecretStorage ID that released versions accept(podNotesData.test.ts).-0and-01. Caught by the same new test.openai) instead of the label. Caught by newnames the provider whose configured key is missing from an explicit export(CredentialRepository.test.ts).copies a secret selected in each key row into that row's provider ID(PodNotesSettingsTab.import.test.ts).names exactly the legacy keys it moved into SecretStorage(main.persistence.test.ts).says its API keys could not move when only a Deepgram key fails to migrate(main.persistence.test.ts).No test that existed before this PR catches any of the plants that the new tests catch. With each one planted, the full suite shows only the new test failing. The one exception is the notice that names every kind, which three feed migration tests also catch.
These wrong derivations do not compile, so typecheck rejects them before any test runs:
src/constants.ts.PodNotesSettingsTab.ts.DEFAULT_SETTINGS: TS2741, "Property 'elevenLabsSecretId' is missing", insrc/constants.ts.Obsidian 1.14.4 on Linux, in this worktree's isolated instance, from a fresh vault each run. I seeded one foreign secret,
verify-shared-key. Then in Settings > PodNotes I linked it to the OpenAI API key row through the real Select secret picker. I turned on Speaker diarization, chose Deepgram, and linked it to the Deepgram API key row. The script picks Deepgram with the dropdown's change event, because CDP cannot open a native select menu. I ran the same script on a bundle built frommasterand on this build.data.jsonand SecretStorage match exactly on both bundles.openAISecretIdispodnotes-openai-api-keyanddeepgramSecretIdispodnotes-deepgram-api-key. Each holds the selected value.Release impact
None.
Note
Derive API key handling from a single credential metadata table
Replaces the hard-coded OpenAI and Deepgram credential handling with one shared metadata record in Credentials.ts. Each entry defines the settings key, export key, and provider label, and the credential types derive from it.
secretBaseIdhelper, andisPodNotesSecretIdbuilds its regex from it. IDs keep the positive, non-zero numeric suffix format.Macroscope summarized 1a2b833.
Note
Low Risk
Refactor-only for existing OpenAI/Deepgram keys; no new providers or SecretStorage format changes beyond shared validation helpers and added test coverage.
Overview
Centralizes OpenAI and Deepgram API key handling in a single
CREDENTIALStable (settingsKey,exportKey,label, andpodnotes-<kind>-api-keyIDs).CredentialKindand related types are derived from that table so adding a provider later is meant to be one row, not edits everywhere.Replaces hand-coded provider pairs with loops over
CREDENTIAL_KINDSinCredentialRepository, settings decode/transfer, schema migration notices inmain.ts, and the settings tab secret rows.IPodNotesSettingsnow picks up secret reference fields viaCredentialReferenceSettings.SecretStorage ID rules are built from shared
secretBaseId/isPodNotesSecretId(still accepts positive numeric suffixes like-1; rejects-0/ leading-zero forms).Adds tests for migration/user-facing copy, numbered ID acceptance, provider-specific export errors, and per-row secret adoption in the settings UI. No new transcription providers in this PR—behavior for the two existing keys should match prior releases.
Reviewed by Cursor Bugbot for commit 1a2b833. Bugbot is set up for automated code reviews on this repo. Configure here.