Add settings page with CSV export, SQL dump export/import
New /settings page (linked from the header's burger menu) offers: - CSV export of the user's links, for spreadsheet apps. - SQL dump export as INSERT INTO links (...) statements, scoped to the current user only — never a raw full-database dump, since that would leak other accounts' password hashes and data. Embeddings are excluded (regenerated via "KI neu beschreiben lassen" if needed). - SQL import that re-adds a previously exported dump to the current account (additive, doesn't touch existing links). Import safety (app/backup.py): uploaded SQL is never executed against the real database. Each non-comment line is required to start with "insert into links" and is run one statement at a time against an isolated in-memory SQLite database with only a whitelisted `links` schema (no id/user_id columns) — sqlite3.execute() also rejects multiple statements per call. Only after that succeeds are rows copied into the real DB via the ORM, with user_id forced to the logged-in user. Verified this rejects DROP TABLE, ATTACH DATABASE, stacked statements, cross-table subqueries, and user_id injection. Upload is capped at 2 MB. Also adds download/upload icons and a proper file-input styling pattern (visually-hidden input + <label> trigger + filename readout), since the browser's ::file-selector-button pseudo-element didn't render reliably in testing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,9 +27,9 @@
|
||||
<button type="button" class="dropdown-item" disabled>
|
||||
{{ icons.tag(size=15) }} Tags verwalten <span class="soon">bald</span>
|
||||
</button>
|
||||
<button type="button" class="dropdown-item" disabled>
|
||||
{{ icons.sliders(size=15) }} Einstellungen <span class="soon">bald</span>
|
||||
</button>
|
||||
<a href="/settings" class="dropdown-item" style="text-decoration:none;">
|
||||
{{ icons.sliders(size=15) }} Einstellungen
|
||||
</a>
|
||||
<div class="dropdown-sep"></div>
|
||||
<form method="post" action="/logout" style="margin:0;">
|
||||
<button type="submit" class="dropdown-item">{{ icons.log_out(size=15) }} Abmelden</button>
|
||||
|
||||
Reference in New Issue
Block a user