69 Commits

Author SHA1 Message Date
Nirodan ac31290a87 Reject tokens missing required fields to prevent KeyError crashes
Tokens issued before 'id' was added to the JWT payload pass signature
verification but cause a KeyError when endpoints access user['id'].
verify_token() now returns None for any token missing id/username/role,
triggering a 401 → the frontend interceptor clears localStorage and
redirects to /login so a fresh token is issued automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v2.0
2026-05-06 10:33:11 +02:00
Nirodan 9db922703b Add versioned DB migration system with automatic backup
migrations.py
- schema_migrations table tracks applied versions (version, description, applied_at)
- MIGRATIONS list is append-only; each entry is (version, description, sql)
- backup() dumps all user-data tables to a timestamped JSON file in backups/
  before any schema changes so data can be recovered if something goes wrong
- run_migrations() is idempotent: already-applied versions are skipped

Integration
- app.py calls _run_startup_migrations() at module load so every restart
  applies any pending migrations (no-op if schema is current)
- setup_routes.py calls run_migrations() after the initial setup form is
  submitted so all tables exist before the user hits the main page for the
  first time
- notes.py and admin.py: removed all per-request CREATE TABLE DDL; schema is
  now owned entirely by the migration system

Docker
- docker-compose.dev.yml: add backups-data volume so JSON backups survive
  container restarts and rebuilds
- Dockerfile: pre-create /app/backend/logs and /app/backend/backups so the
  directories exist even before volumes are mounted

Adding future schema changes
- Append a new (version, description, sql) tuple to MIGRATIONS in migrations.py
- The next restart will detect it as pending, back up first, then apply it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 10:27:11 +02:00
Nirodan 20cdbd69eb Fix Notes feature: correct auto-save logic and missing CSS
Functional fixes:
- Add isDirtyRef to distinguish user edits from note selection; auto-save now
  only fires after the user actually modifies content, not on every click
- Add selected and isNew to auto-save effect deps so the closure is never stale
  when switching between notes (previously could save to the wrong note)
- Double-check isDirtyRef inside the debounce callback to handle rapid note
  switches within the 1-second window
- Reset isDirtyRef to false after every successful save (manual and auto)

CSS fixes:
- Add button.ghost and button.ghost.danger styles to buttons.css; delete button
  was invisible/identical to the save button because .ghost was never defined
- Add select element styling to base.css to match input/textarea theming;
  language picker was unstyled browser-default in both dark and light mode
- Add .error class (red text) to base.css; error messages had no colour
- Add .notes-layout grid class with responsive media query (stacks below 680px);
  remove inline gridTemplateColumns that overflowed on small screens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 10:19:40 +02:00
Nirodan 7827cda224 Add targeted comments for non-obvious constraints and invariants
- logger.py: note why log path uses abspath(__file__) instead of a relative path
- token.py: note why [7:] slice is safe (startswith already verified)
- ipcalc.py: explain /32 single-host and /31 RFC-3021 point-to-point special
  cases; explain why (~netmask) must be masked with 0xFFFFFFFF (Python ~int
  returns a negative arbitrary-precision value, not a 32-bit unsigned integer)
- notes.py: document the module-level _table_ready flag lifetime; explain why
  tzinfo is stripped before passing datetime to mysql-connector
- admin.py: document the module-level _tables_initialized flag lifetime

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 10:08:55 +02:00
Nirodan 98bb34f094 Fix bugs, add log rotation, and optimize hot paths
- Fix AttributeError crash on empty request body in md5, hasher, textdiff,
  jwtdecoder, timestamp, passwordgen (get_json without silent=True / or {})
- Fix memory exhaustion in ipcalc: replace list(network.hosts()) with direct
  arithmetic — safe for /8 and larger networks
- Fix O(1M) loop in cronexplainer.get_next_runs: rewrite to skip by
  month/day/hour instead of iterating every minute
- Fix connection leak in notes.ensure_table: add try/finally around conn.close
- Fix admin._ensure_tables / notes._ensure_table running DDL on every request:
  guard with module-level flags (_tables_initialized, _table_ready)
- Fix update_website returning 200 when no row matched; delete_website returning
  success when nothing was deleted; add rowcount checks for both
- Add role validation in admin create_user / update_user (_VALID_ROLES guard)
- Add delimiter length guard in csvviewer (csv.reader requires single char)
- Fix loremipsum: wrap int(count) in try/except ValueError → 400 response
- Fix auth/token: use auth_header[7:] instead of fragile .replace()
- Fix app.py: remove duplicate import sys; cache DB liveness check with 30s TTL
  to avoid a new TCP connection on every frontend page load; move api/setup
  path guard before DB check
- Replace FileHandler with RotatingFileHandler (5 MB / 3 backups) in logger;
  fix relative log paths to absolute paths anchored to __file__
- Wrap all DB connections in try/finally conn.close() throughout admin and notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 10:06:29 +02:00
Nirodan 31494c9dab Fix login: include user id in JWT payload for notes tool
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 09:51:59 +02:00
Nirodan dedde400e1 Add entrypoint.sh: wait for MariaDB before starting Flask
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 09:37:01 +02:00
Nirodan 75062dbf5e Add 8 new tools: Hash Verifier, URL Tool, String Utils, Cron Explainer, IP Calc, Lorem Ipsum, CSV Viewer, Notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 09:10:25 +02:00
Nirodan ef03e76950 Fix requirements.txt: add trailing newline
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 18:27:51 +02:00
Nirodan 34c82f3dca Add 5 new tools: QR-Code, Markdown, Color Converter, JSON Formatter, Regex Tester
- backend/tools/qrcode_gen.py: POST /api/qrcode/generate, returns base64 PNG (qrcode[pil])
- backend/tools/markdown_tool.py: POST /api/markdown/render, extensions: tables/fenced_code/nl2br
- backend/tools/colorconverter.py: POST /api/color/convert, HEX/RGB/HSL via colorsys (no deps)
- backend/tools/jsonformatter.py: POST /api/json/format, returns formatted JSON with line/col errors
- backend/tools/regextester.py: POST /api/regex/test, flags i/m/s, returns matches with positions
- QrCodeTool.jsx: generate + download PNG button
- MarkdownTool.jsx: split editor/preview, debounce 500ms, white preview bg
- ColorConverterTool.jsx: color swatch preview, per-format copy buttons
- JsonFormatterTool.jsx: indent toggle 2/4, pre result box with copy
- RegexTesterTool.jsx: debounce 400ms, yellow match highlighting, flag checkboxes
- All blueprints registered in app.py; qrcode[pil] + markdown added to requirements.txt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 18:19:34 +02:00
Nirodan 45e1934bee Fix App.jsx: remove dead comment, make auth state reactive
- Remove leftover commented-out AdminDashboard import
- Replace static localStorage reads with useState + useEffect
  so isLoggedIn/role update automatically on storage events
  (e.g. token deleted in another tab)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 18:02:15 +02:00
Nirodan 1a6f476dc8 Merge pull request 'Clean release: drop local startup scripts and agent stub' (#1) from release into main
Reviewed-on: #1
2026-04-24 17:42:00 +02:00
Nirodan 955bc9a7bf Fix 8 bugs found in code review
- auth/login.py: guard against missing JSON body (get_json silent=True, empty-string check)
- app.py: replace infinite redirect with 404 for unknown /api/* and /setup/* paths
- tools/jwtdecoder.py: add algorithms list to jwt.decode() for PyJWT 2.x compatibility
- util/setup_routes.py: call reset_pool() after save_config() so pool re-initialises with new DB credentials
- util/logger.py: set ERROR level on error.log handler so it no longer receives INFO/WARNING messages
- LoginForm.jsx: remove dead navigate() call that was immediately overridden by window.location.href
- main.jsx: remove base.css, dark.css, light.css that were already imported in App.jsx (duplicate imports)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 17:38:51 +02:00
Nirodan 7f9c5c874a Add 6 new tools: Hasher, Base64, JWT Decoder, Password Gen, Timestamp, Text Diff
- backend/tools/hasher.py: POST /api/hash/sha256 and /api/hash/bcrypt (bcrypt added to requirements)
- backend/tools/base64tool.py: POST /api/base64/encode and /api/base64/decode
- backend/tools/jwtdecoder.py: POST /api/jwt/decode (signature verification disabled)
- backend/tools/passwordgen.py: POST /api/password/generate with charset and length options
- backend/tools/timestamp.py: POST /api/timestamp/convert (unix<->date, ISO 8601 + German format)
- backend/tools/textdiff.py: POST /api/text/diff returning structured added/removed/unchanged lines
- All blueprints registered in app.py and tools/__init__.py
- React components with copy button, dark/light mode support via CSS variables
- ToolOverview rebuilt as card grid; App.jsx routes added for all tools

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 14:28:18 +02:00
Nirodan 80ec5eca7b Security, code quality and frontend improvements
- Move SECRET_KEY out of docker-compose into .env (env_file), add .env.example
- Add flask-limiter with 10 req/min on login route; introduce util/limiter.py
- Replace direct mysql.connector.connect() calls with MySQLConnectionPool via util/db_pool.py
- Fix deprecated datetime.utcnow() -> datetime.now(timezone.utc) in auth/login.py
- Remove dead /api/scripts 410 route from admin.py
- Add MD5 security warning in Md5Tool.jsx
- Add ErrorBoundary component and wrap App.jsx
- Expand README with setup guide, screenshot and project structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 13:52:53 +02:00
Nirodan 8e2c2d740e Clean release: drop local startup scripts and agent stub v1.0 2026-01-22 16:43:14 +01:00
Nirodan 923c1984f5 v1.0 2026-01-22 15:35:38 +01:00
Nirodan a3c3967903 Reduce admin input padding to avoid overflow 2026-01-22 15:34:33 +01:00
Nirodan 206102db36 Let admin cards show full rounded inputs 2026-01-22 15:28:47 +01:00
Nirodan baa8b17ab2 Force admin forms single-column to stop overflow 2026-01-22 15:25:51 +01:00
Nirodan c24a0df4b2 Prevent input overflow in admin forms 2026-01-22 15:22:45 +01:00
Nirodan edc5fa7fd0 Stack admin forms to prevent overflow 2026-01-22 13:05:47 +01:00
Nirodan 7af1ca32ed Tighten admin form layout and responsive tables 2026-01-22 12:36:43 +01:00
Nirodan 450e184cf3 Clean admin layout, drop scripts, keep admin out of tools list 2026-01-22 12:31:19 +01:00
Nirodan e3b34bfc47 Extend admin for websites/scripts and surface links 2026-01-22 12:26:21 +01:00
Nirodan 0699158486 Add admin dashboard and tool icons 2026-01-22 12:18:27 +01:00
Nirodan a944f7dd5d Restyle UI with modern glassy theme 2026-01-22 12:12:47 +01:00
Nirodan 3d1bb93dfd Deleted old faststart setup 2026-01-22 12:03:36 +01:00
Nirodan 9d7e0023f4 Fix auth redirects and add rebuild startup scripts 2026-01-22 12:02:37 +01:00
Nirodan 1263f9d2ef Fix dev compose volume mounts 2026-01-22 07:57:05 +01:00
Nirodan c0aaa86546 Fix config path, env secrets, and align API calls 2026-01-22 07:56:27 +01:00
Nirodan 73d487255a Einfügen einer setup.css noch nicht run fähig, Design wird nicht angezeigt 2025-07-07 12:24:57 +02:00
Nirodan cf838ee9b1 Logout Button Fix immer noch zu weit rechts gewesen 2025-07-07 11:50:21 +02:00
Nirodan 96b5fc1a81 Bug Fixing, buttons nicht sichtbar im hellen modus, Logout zu weit rechts. Von hell auf dunkel standard 2025-07-07 11:39:47 +02:00
Nirodan 8d7b254306 NavBar v.0.1 etnfernen von altem LogoutButton in ToolOverview 2025-07-07 11:19:00 +02:00
Nirodan d927679667 NavBar v.0.0.1 2025-07-07 10:57:18 +02:00
Nirodan 537df29737 Hinzufügen des Styles, verschieben und löschen der alten CSS Dateien. Umschalten auf Modulares Design 2025-07-07 10:23:29 +02:00
Nirodan c6f4522d2c Sichtbare DockerLogs im Dev, änderungen an der python version gegen angriffe 2025-06-17 14:35:55 +02:00
Nirodan 263ac52454 setup_routes wieder util 2025-06-17 14:22:32 +02:00
Nirodan e680776bc4 Bug fixing fehlende oder Fehlerhafte Module korrigiert 2025-06-17 14:18:14 +02:00
Nirodan 4c6872a866 neuschreiben der app.py nach refectoring 2025-06-17 11:36:12 +02:00
Nirodan e0b77c890e Funktionsverschiebungen 1.1 2025-06-17 11:33:47 +02:00
Nirodan 8ca650cf11 Funktionstrennung 1.0 2025-06-17 11:28:06 +02:00
Nirodan 97acda1d2b Umstruckturieren, trennen vom Logger in eine eigene Datei 2025-06-17 11:20:00 +02:00
Nirodan e15f6a4ccf Trennen von errorlogs und normalen logs 2025-06-17 11:09:20 +02:00
Nirodan 6ca9cf77ac Logging in App.py 2025-06-17 11:05:55 +02:00
Nirodan ce36859cf0 Logger in login + token verify 2025-06-17 11:01:33 +02:00
Nirodan bbb1a70b9c MD5 hasher Bug Fix + Logger 2025-06-17 11:00:26 +02:00
Nirodan b6399f8b52 Docker compose. dev.yml erstellt 2025-06-17 10:43:22 +02:00
Nirodan 2961081c06 In docker umgewandelt zwar mit erros im frontend aber ja 2025-06-16 12:15:13 +02:00