feat(portable): add secure Windows portable release (#15)

Implement marker-based portable storage, portable WebView and log paths, secure queue and migration sanitization, and Windows portable ZIP validation while preserving the NSIS installer path.

Refs #15
This commit is contained in:
NimBold
2026-07-12 23:08:48 +03:30
parent 56b4c9f511
commit a0f44b79ad
20 changed files with 905 additions and 82 deletions
+13 -6
View File
@@ -1214,9 +1214,13 @@ className="app-button px-3 py-1.5 text-[12px] flex items-center gap-1.5 disabled
<Check size={16} strokeWidth={2.5} />
</div>
<div className="flex-1">
<h4 className="text-sm font-semibold text-green-500 m-0">Credential Storage Available</h4>
<h4 className="text-sm font-semibold text-green-500 m-0">
{platform.portable ? 'Portable Pairing Enabled' : 'Credential Storage Available'}
</h4>
<p className="text-xs text-text-secondary m-0 mt-0.5">
Your pairing token is securely saved in this system's credential store and will persist across restarts.
{platform.portable
? 'Your pairing token is stored with this portable Firelink folder and will persist when the folder is moved. Treat the folder as sensitive.'
: "Your pairing token is securely saved in this system's credential store and will persist across restarts."}
</p>
</div>
</div>
@@ -1224,16 +1228,19 @@ className="app-button px-3 py-1.5 text-[12px] flex items-center gap-1.5 disabled
<div className="bg-orange-500/10 border border-orange-500/20 rounded-lg p-4 flex items-start gap-3">
<ShieldAlert className="w-5 h-5 text-orange-500 flex-shrink-0 mt-0.5" />
<div className="flex-1">
<h4 className="text-sm font-semibold text-text-primary mb-1">Credential Storage Needed</h4>
<h4 className="text-sm font-semibold text-text-primary mb-1">
{platform.portable ? 'Portable Pairing Available' : 'Credential Storage Needed'}
</h4>
<p className="text-xs text-text-secondary mb-3">
Firelink needs access to this system's credential store to securely save your pairing token across app restarts.
Currently, your extension will only stay connected for this session.
{platform.portable
? 'Your pairing token is stored with this portable Firelink folder and will persist across restarts. Enable it here to review the portable-storage warning.'
: "Firelink needs access to this system's credential store to securely save your pairing token across app restarts. Currently, your extension will only stay connected for this session."}
</p>
<button
onClick={() => settings.setShowKeychainModal(true)}
className="px-4 py-1.5 rounded-md text-xs font-medium transition-colors bg-accent text-white hover:bg-accent/90 shadow-sm"
>
Grant Credential Access
{platform.portable ? 'Review Portable Pairing' : 'Grant Credential Access'}
</button>
</div>
</div>