Encrypt credentials at rest; unify clipboard-link suggestions
Encrypt proxy / youtubePoToken / updateToken on disk via safeStorage (DPAPI on Windows), with a one-time launch migration for legacy plaintext. Decrypted before reaching callers/renderer; backup export still writes clear, as documented. Harden updater token handling to refuse cross-origin redirects on the authenticated REST check. Extract the clipboard-link logic from DownloadBar into the shared useClipboardLink hook: add an optional filter (library skips single-video links), an offer() for external aerofetch:// / .url links, and a source field driving banner wording. Add looksLikeSingleVideo plus its unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+10
-2
@@ -15,8 +15,12 @@ import {
|
||||
* Authorization header for the update host. Empty unless the user has set an
|
||||
* updateToken in Settings — needed when the release repo is private or the Gitea
|
||||
* instance requires sign-in for anonymous access (the default on this instance).
|
||||
* Only ever sent to the host-pinned UPDATE_HOST (see isTrustedDownloadUrl), so a
|
||||
* redirect can never leak the token to another origin.
|
||||
*
|
||||
* The token must never reach an origin other than the host-pinned UPDATE_HOST.
|
||||
* Every request that carries it guards against that on its own terms: the REST
|
||||
* check refuses to follow redirects (`redirect: 'error'`), and the download paths
|
||||
* use `redirect: 'manual'` and re-validate each hop with isTrustedDownloadUrl. So
|
||||
* a redirect can't bounce the header to another host on any path.
|
||||
*/
|
||||
function authHeader(): Record<string, string> {
|
||||
const tok = getSettings().updateToken?.trim()
|
||||
@@ -123,6 +127,10 @@ export async function checkForAppUpdate(): Promise<AppUpdateInfo> {
|
||||
try {
|
||||
const res = await fetch(RELEASE_API, {
|
||||
headers: { Accept: 'application/json', ...authHeader() },
|
||||
// The API lives at an exact pinned URL and answers 200 directly. Refusing
|
||||
// redirects keeps an authenticated check from ever forwarding the token to
|
||||
// another origin; a stray redirect fails safe into the catch below.
|
||||
redirect: 'error',
|
||||
signal: controller.signal
|
||||
})
|
||||
if (!res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user