mirror of
https://github.com/trevor1969/teatracker.git
synced 2026-08-09 10:41:59 +00:00
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:
33
README.md
33
README.md
@ -115,19 +115,18 @@
|
|||||||
### Option 3: Mit Nextcloud-Synchronisation (empfohlen!)
|
### Option 3: Mit Nextcloud-Synchronisation (empfohlen!)
|
||||||
|
|
||||||
1. **App öffnen** (lokal oder über GitHub Pages)
|
1. **App öffnen** (lokal oder über GitHub Pages)
|
||||||
2. **Automatische Verbindung**: Die App testet automatisch die Verbindung zu deiner Nextcloud
|
2. Gehe zum Tab **⚙️ Einstellungen**
|
||||||
3. **Fertig!** 🎉 Deine Daten werden jetzt automatisch synchronisiert
|
3. Aktiviere **Nextcloud-Synchronisation**
|
||||||
|
4. Trage deine Nextcloud-Daten ein:
|
||||||
|
- **URL**: `https://wralto.org/nextcloud3`
|
||||||
|
- **Benutzername**: `teetracker`
|
||||||
|
- **App-Passwort**: (dein App-Passwort aus Nextcloud)
|
||||||
|
- **Speicherpfad**: `/TeeTracker/` (Standard)
|
||||||
|
5. Klicke auf **🔍 Verbindung testen**
|
||||||
|
6. Speichere die Konfiguration mit **💾 Speichern**
|
||||||
|
7. **Fertig!** 🎉 Deine Daten werden jetzt automatisch synchronisiert
|
||||||
|
|
||||||
**Oder manuell einrichten:**
|
**Hinweis:** Aus Sicherheitsgründen musst du dein Passwort manuell eingeben. Es wird nicht in der App gespeichert (nur temporär in sessionStorage).
|
||||||
1. Gehe zum Tab **⚙️ Einstellungen**
|
|
||||||
2. Aktiviere **Nextcloud-Synchronisation**
|
|
||||||
3. Trage deine Nextcloud-Daten ein:
|
|
||||||
- **URL**: `https://wralto.org/nextcloud3` (vorbefüllt)
|
|
||||||
- **Benutzername**: `teetracker` (vorbefüllt)
|
|
||||||
- **App-Passwort**: `ruebennasenhausen!2026` (vorbefüllt)
|
|
||||||
- **Speicherpfad**: `/TeeTracker/` (vorbefüllt)
|
|
||||||
4. Klicke auf **🔍 Verbindung testen**
|
|
||||||
5. Speichere die Konfiguration mit **💾 Speichern**
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -185,6 +184,14 @@ Falls Nextcloud nicht erreichbar ist:
|
|||||||
2. Änderungen werden **lokal gespeichert**
|
2. Änderungen werden **lokal gespeichert**
|
||||||
3. Beim nächsten erfolgreichen Verbindungsaufbau werden die Daten **automatisch synchronisiert**
|
3. Beim nächsten erfolgreichen Verbindungsaufbau werden die Daten **automatisch synchronisiert**
|
||||||
|
|
||||||
|
### 🔐 Sicherheitshinweise
|
||||||
|
|
||||||
|
**WICHTIG:** Aus Sicherheitsgründen wird dein Passwort **NICHT** im Klartext in der App oder im localStorage gespeichert!
|
||||||
|
|
||||||
|
- **sessionStorage**: Das Passwort wird nur in `sessionStorage` gespeichert (wird beim Schließen des Browsers gelöscht)
|
||||||
|
- **Keine Vorbefüllung**: Du musst dein Passwort manuell eingeben
|
||||||
|
- **Kein Klartext in Dateien**: Das Passwort erscheint nirgends im Code
|
||||||
|
|
||||||
### App-Passwort erstellen
|
### App-Passwort erstellen
|
||||||
|
|
||||||
Falls du ein neues Passwort brauchst:
|
Falls du ein neues Passwort brauchst:
|
||||||
@ -194,6 +201,8 @@ Falls du ein neues Passwort brauchst:
|
|||||||
4. Erstelle ein neues Passwort mit dem Namen **"TeeTracker"**
|
4. Erstelle ein neues Passwort mit dem Namen **"TeeTracker"**
|
||||||
5. Kopiere das Passwort und trage es in den Einstellungen ein
|
5. Kopiere das Passwort und trage es in den Einstellungen ein
|
||||||
|
|
||||||
|
**Tipp:** Speichere das App-Passwort in einem Passwort-Manager, da es nach dem Erstellen nicht mehr angezeigt wird.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🎨 Design
|
## 🎨 Design
|
||||||
|
|||||||
57
app.js
57
app.js
@ -200,57 +200,35 @@ class TeeTracker {
|
|||||||
initStorage() {
|
initStorage() {
|
||||||
// Load Nextcloud configuration from localStorage
|
// Load Nextcloud configuration from localStorage
|
||||||
const ncConfig = localStorage.getItem(STORAGE_KEY_NC_CONFIG);
|
const ncConfig = localStorage.getItem(STORAGE_KEY_NC_CONFIG);
|
||||||
|
const ncPassword = sessionStorage.getItem(STORAGE_KEY_NC_CONFIG + '_password');
|
||||||
|
|
||||||
if (ncConfig) {
|
if (ncConfig) {
|
||||||
try {
|
try {
|
||||||
const config = JSON.parse(ncConfig);
|
const config = JSON.parse(ncConfig);
|
||||||
|
// Load password from sessionStorage (more secure than localStorage)
|
||||||
|
const password = ncPassword || '';
|
||||||
|
|
||||||
|
if (password) {
|
||||||
this.nextcloudStorage = new NextcloudStorage(
|
this.nextcloudStorage = new NextcloudStorage(
|
||||||
config.baseUrl,
|
config.baseUrl,
|
||||||
config.username,
|
config.username,
|
||||||
config.password,
|
password,
|
||||||
config.path || '/TeeTracker/'
|
config.path || '/TeeTracker/'
|
||||||
);
|
);
|
||||||
this.useNextcloud = true;
|
this.useNextcloud = true;
|
||||||
this.updateSyncStatus();
|
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) {
|
} catch (error) {
|
||||||
console.error('Invalid Nextcloud config:', error);
|
console.error('Invalid Nextcloud config:', error);
|
||||||
this.useNextcloud = false;
|
this.useNextcloud = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check if we have predefined Nextcloud credentials
|
// Don't pre-fill credentials - user must enter them manually
|
||||||
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.useNextcloud = false;
|
||||||
this.updateSyncStatus();
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
this.useNextcloud = false;
|
|
||||||
this.updateSyncStatus();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,10 +778,14 @@ class TeeTracker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save config
|
// Save config WITHOUT password for security
|
||||||
const config = { baseUrl: url, username, password, path };
|
// 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));
|
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
|
// Update app state
|
||||||
this.nextcloudStorage = ncStorage;
|
this.nextcloudStorage = ncStorage;
|
||||||
this.useNextcloud = true;
|
this.useNextcloud = true;
|
||||||
@ -815,6 +797,7 @@ class TeeTracker {
|
|||||||
} else {
|
} else {
|
||||||
// Disable Nextcloud
|
// Disable Nextcloud
|
||||||
localStorage.removeItem(STORAGE_KEY_NC_CONFIG);
|
localStorage.removeItem(STORAGE_KEY_NC_CONFIG);
|
||||||
|
sessionStorage.removeItem(STORAGE_KEY_NC_CONFIG + '_password');
|
||||||
this.useNextcloud = false;
|
this.useNextcloud = false;
|
||||||
this.nextcloudStorage = null;
|
this.nextcloudStorage = null;
|
||||||
this.showStatusMessage('✅ Nextcloud-Synchronisation deaktiviert. Daten werden lokal gespeichert.', 'success');
|
this.showStatusMessage('✅ Nextcloud-Synchronisation deaktiviert. Daten werden lokal gespeichert.', 'success');
|
||||||
|
|||||||
@ -137,17 +137,17 @@
|
|||||||
<div id="nc-config" style="display: none;">
|
<div id="nc-config" style="display: none;">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nc-url">Nextcloud-URL *</label>
|
<label for="nc-url">Nextcloud-URL *</label>
|
||||||
<input type="url" id="nc-url" placeholder="https://deine-nextcloud.de" value="https://wralto.org/nextcloud3">
|
<input type="url" id="nc-url" placeholder="https://deine-nextcloud.de">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nc-username">Benutzername *</label>
|
<label for="nc-username">Benutzername *</label>
|
||||||
<input type="text" id="nc-username" placeholder="Dein Nextcloud-Benutzername" value="teetracker">
|
<input type="text" id="nc-username" placeholder="Dein Nextcloud-Benutzername">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="nc-password">App-Passwort *</label>
|
<label for="nc-password">App-Passwort *</label>
|
||||||
<input type="password" id="nc-password" placeholder="App-Passwort aus Nextcloud" value="ruebennasenhausen!2026">
|
<input type="password" id="nc-password" placeholder="App-Passwort aus Nextcloud" autocomplete="current-password">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
Reference in New Issue
Block a user