fix: Remove plain text password from code, use sessionStorage for security

- Remove hardcoded Nextcloud credentials from app.js
- Remove pre-filled password from HTML form
- Store password in sessionStorage (cleared on browser close) instead of localStorage
- Store only URL, username, and path in localStorage
- Update README with security notes
- Update quick start guide to reflect manual password entry
- Add autocomplete attribute to password field

Security improvement: Password is now only stored temporarily in sessionStorage
and must be entered manually by the user on first use or after browser restart.

Generated by Vibe Code

Co-authored-by: trevor1969 <trevor1969@users.noreply.github.com>
This commit is contained in:
Vibe Nuage Agent
2026-06-04 12:27:10 +00:00
parent 990ebb134d
commit 233647be4a
3 changed files with 52 additions and 60 deletions

73
app.js
View File

@ -200,57 +200,35 @@ class TeeTracker {
initStorage() {
// Load Nextcloud configuration from localStorage
const ncConfig = localStorage.getItem(STORAGE_KEY_NC_CONFIG);
const ncPassword = sessionStorage.getItem(STORAGE_KEY_NC_CONFIG + '_password');
if (ncConfig) {
try {
const config = JSON.parse(ncConfig);
this.nextcloudStorage = new NextcloudStorage(
config.baseUrl,
config.username,
config.password,
config.path || '/TeeTracker/'
);
this.useNextcloud = true;
this.updateSyncStatus();
// Load password from sessionStorage (more secure than localStorage)
const password = ncPassword || '';
if (password) {
this.nextcloudStorage = new NextcloudStorage(
config.baseUrl,
config.username,
password,
config.path || '/TeeTracker/'
);
this.useNextcloud = true;
this.updateSyncStatus();
} else {
// Password not available, user needs to re-enter it
this.useNextcloud = false;
this.showStatusMessage('Bitte gib dein Nextcloud-Passwort erneut ein.', 'info');
}
} catch (error) {
console.error('Invalid Nextcloud config:', error);
this.useNextcloud = false;
}
} else {
// Check if we have predefined Nextcloud credentials
const predefinedConfig = {
baseUrl: 'https://wralto.org/nextcloud3',
username: 'teetracker',
password: 'ruebennasenhausen!2026',
path: '/TeeTracker/'
};
// Test the predefined connection
this.nextcloudStorage = new NextcloudStorage(
predefinedConfig.baseUrl,
predefinedConfig.username,
predefinedConfig.password,
predefinedConfig.path
);
// Test connection asynchronously
this.nextcloudStorage.testConnection().then(connected => {
if (connected) {
this.useNextcloud = true;
localStorage.setItem(STORAGE_KEY_NC_CONFIG, JSON.stringify(predefinedConfig));
this.updateSyncStatus();
// Reload data from Nextcloud
this.loadData().then(() => {
this.renderAll();
this.updateSettingsStats();
});
} else {
this.useNextcloud = false;
this.updateSyncStatus();
}
}).catch(() => {
this.useNextcloud = false;
this.updateSyncStatus();
});
// Don't pre-fill credentials - user must enter them manually
this.useNextcloud = false;
}
}
@ -800,10 +778,14 @@ class TeeTracker {
return;
}
// Save config
const config = { baseUrl: url, username, password, path };
// Save config WITHOUT password for security
// Password will be requested each time or stored in sessionStorage
const config = { baseUrl: url, username, path };
localStorage.setItem(STORAGE_KEY_NC_CONFIG, JSON.stringify(config));
// Store password in sessionStorage (cleared when browser closes)
sessionStorage.setItem(STORAGE_KEY_NC_CONFIG + '_password', password);
// Update app state
this.nextcloudStorage = ncStorage;
this.useNextcloud = true;
@ -815,6 +797,7 @@ class TeeTracker {
} else {
// Disable Nextcloud
localStorage.removeItem(STORAGE_KEY_NC_CONFIG);
sessionStorage.removeItem(STORAGE_KEY_NC_CONFIG + '_password');
this.useNextcloud = false;
this.nextcloudStorage = null;
this.showStatusMessage('✅ Nextcloud-Synchronisation deaktiviert. Daten werden lokal gespeichert.', 'success');