From 7a9bc23084f5619831e776d7033a73c89d3894a2 Mon Sep 17 00:00:00 2001 From: PiEgg Date: Mon, 5 Oct 2026 20:26:32 +0800 Subject: [PATCH] :sparkles: Feature(gui): configure server upload secret in settings (#1451) * :sparkles: Feature(gui): configure server upload secret in settings PicGo Core already supports authenticating `POST /upload` with a shared secret (`Authorization: Bearer `, `X-PicGo-Secret` or `?secret=`), resolved from `PICGO_SERVER_SECRET` or `settings.server.secret`, but the GUI offered no way to set it. Add a masked secret field with a show/hide toggle to the PicGo Server dialog, next to host and port. The dialog saves the trimmed value as `settings.server.secret`; an empty value disables authentication. Saving already restarts the server, and Core reads the secret from config on `listen()`, so the main process needs no change and `PICGO_SERVER_SECRET` still takes precedence. The secret value is never added to the settings search index. * :bug: Fix(gui): keep server secret when normalizing settings normalizeSettingsConfig only copied host, port and enable from `settings.server`, so after a reload the renderer state had no secret: the server dialog reopened with an empty secret field, and saving it again (e.g. after changing the port) would have silently cleared the secret and disabled authentication. Keep `secret` (falling back to an empty string) and cover it with a test. * :pencil: Docs: document renderer config normalizer whitelist in AGENTS.md The server secret was dropped from renderer state because normalizeSettingsConfig only copies listed fields, and the server dialog re-saves the whole object. Record the rule for future changes: when adding a persisted config field, update the shared types, renderer state type, default value and normalizer, and add a round-trip normalizer test. Also give `settings.server.secret` an explicit empty default to follow that rule. * :pencil: Docs: require English PRs and squash merges in AGENTS.md --- AGENTS.md | 3 + public/i18n/en.yml | 5 + public/i18n/ja.yml | 5 + public/i18n/ko.yml | 5 + public/i18n/zh-CN.yml | 5 + public/i18n/zh-TW.yml | 5 + .../settings-dialog-server.spec.tsx | 93 +++++++++++++++++++ .../renderer/store/settings-normalize.spec.ts | 30 ++++++ .../main/settings/settings-dialog-server.tsx | 50 +++++++++- .../settings/settings-section-network.tsx | 4 + .../components/main/settings/utils.ts | 5 +- src/renderer/store/utils.ts | 4 +- src/universal/types/i18n.d.ts | 5 + src/universal/types/types.d.ts | 1 + src/universal/types/view.d.ts | 1 + 15 files changed, 216 insertions(+), 5 deletions(-) create mode 100644 src/__tests__/renderer/components/settings-dialog-server.spec.tsx create mode 100644 src/__tests__/renderer/store/settings-normalize.spec.ts diff --git a/AGENTS.md b/AGENTS.md index 9dfe27a..2217e15 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,6 +49,7 @@ Static assets are served from `public/`. In the main process use `getStaticPath` - Renderer-side date/time formatting should use `dayjs` and shared format constants from `src/renderer/utils/consts.ts` (for example `DEFAULT_DATE_TIME_FORMAT`) instead of `Intl.DateTimeFormat` or ad-hoc inline format strings. - Enum-like object constants declared with `as const` (for example status maps, option maps, and value registries) must use PascalCase names, not camelCase. Prefer names like `PicGoCloudRequestStatusValues`, `SettingsAppearanceValues`, or `AppPlatformValues`. - If a renderer → main request mutates persisted config/state without using `saveConfig`, call `notifyAppConfigUpdated()` in main to inform renderers. +- Renderer config normalization is a whitelist: `normalizeAppConfig` / `normalizeSettingsConfig` in `src/renderer/store/utils.ts` copy only the fields they list (for example `settings.server` → `host`, `port`, `enable`, `secret`), and anything not listed is silently dropped from renderer state after every reload. When adding a new persisted config field, update all of: the shared types (`src/universal/types/types.d.ts` / `view.d.ts`), the renderer state type (e.g. `SettingsConfigState` in `src/renderer/components/main/settings/utils.ts`), its default value, and the normalizer. Settings dialogs re-save the whole object (e.g. `settings.server`), so a field missing from the normalizer is not just invisible in the UI but gets overwritten with an empty value on the next save. Add a round-trip test (raw config → normalizer → field still present) next to `src/__tests__/renderer/store/settings-normalize.spec.ts`; a component test that feeds drafts directly will not catch this. - Prefer enums over union types for discrete value sets (e.g., encryption methods). Avoid introducing new string literal union types. - Renderer page/component styles should prefer Tailwind utility classes; avoid adding new Vue `