Remember Password¶
The "Remember password" feature allows users to opt-in to persisting their sync password in localStorage, so they don't need to re-enter it when starting a new browser session.
Security Warning¶
Plaintext Storage
Remembered passwords are stored in plaintext in localStorage. This means:
- Any JavaScript running on the page can access them
- They are vulnerable to XSS attacks
- Browser extensions with page access can read them
- Anyone with physical access to the device can view them in DevTools
Users should only enable this feature on trusted, personal devices.
Storage Format¶
Passwords are stored in localStorage under the key difflog-remembered-passwords:
This is a simple key-value map from profile ID to password string.
Password Resolution Order¶
When the app needs the sync password, it checks these sources in order:
- Session storage - Current tab's cached password
- Remembered passwords - localStorage, keyed by active profile ID
- User prompt - Show password input in sync dropdown
If a remembered password is found, it's automatically promoted to session storage for the current tab:
get _syncPassword(): string | null {
const sessionPwd = getSyncPassword();
if (sessionPwd) return sessionPwd;
if (this.activeProfileId) {
const remembered = getRememberedPassword(this.activeProfileId);
if (remembered) {
// Promote to session storage for this tab
setSyncPassword(remembered);
return remembered;
}
}
return null;
}
Lifecycle¶
| Event | Action |
|---|---|
| User checks "Remember password" + syncs successfully | Password saved to localStorage |
| User clicks "forget saved password" | Cleared from both session and localStorage |
| User deletes profile | Password cleared from localStorage |
| User switches profiles | Session storage cleared (remembered stays) |
| Browser session ends | Session storage cleared (remembered stays) |
| Sync fails with invalid password (401) | Cleared from both session and localStorage |
Password Validation¶
Passwords are only cached (in session or localStorage) after a successful sync. This prevents the app from repeatedly retrying with an invalid password:
- User enters password in sync dropdown
- App attempts to sync with server
- If successful: Password is cached in session storage (and localStorage if "Remember" was checked)
- If 401 Invalid Password: Error is shown, no password is cached, any remembered password for this profile is cleared
Multi-Device Password Changes¶
If you change your sync password on one device, other devices with a remembered (now invalid) password will:
- Attempt auto-sync with the remembered password
- Receive 401 "Invalid password" from server
- Automatically clear the remembered password
- Show the password prompt with "Invalid password" error
- Stop retrying until user enters the correct password
This prevents the app from hammering the server with invalid credentials and triggering rate limits.
UI Elements¶
Password Form (when password needed)¶
When the user needs to enter their password, a checkbox appears:
<label class="sync-dropdown-remember">
<input type="checkbox" x-model="remember" />
<span class="sync-dropdown-remember-text">Remember password</span>
</label>
Forget Button (when logged in)¶
The "forget password" button text changes based on whether the password is remembered:
- Session only: "forget password"
- Remembered: "forget saved password"
Clicking either clears both session and remembered passwords.
API¶
sync.ts¶
// Get remembered password for a profile
getRememberedPassword(profileId: string): string | null
// Save password for a profile
setRememberedPassword(profileId: string, password: string): void
// Clear password for a profile
clearRememberedPassword(profileId: string): void
// Check if a profile has a remembered password
hasRememberedPassword(profileId: string): boolean
store.ts¶
// Check if current profile has a remembered password
get hasRememberedPassword(): boolean
// Remember password for current profile
rememberPassword(password: string): void
// Forget password for current profile (session + remembered)
forgetPassword(): void
Related¶
- Sync System - How sync works
- Encryption - How content is encrypted (password still needed for decryption)