From 50156c19320f20b45d77a27a491244ea73a8d456 Mon Sep 17 00:00:00 2001 From: Me7aminD <114676544+7IKED@users.noreply.github.com> Date: Sat, 1 Nov 2025 21:14:19 +0000 Subject: [PATCH 1/2] feat: add NETMASTER WIKI, versioning, docs and copilot instructions --- .github/ISSUE_TEMPLATE/bug_report.md | 26 ++ .github/ISSUE_TEMPLATE/release-request.md | 30 +++ .github/copilot-instructions.md | 216 ++++++++++++++++ CHANGELOG.md | 6 + VERSION | 1 + netmaster_wiki/README.md | 51 ++++ .../__pycache__/app.cpython-312.pyc | Bin 0 -> 12722 bytes netmaster_wiki/app.py | 233 ++++++++++++++++++ netmaster_wiki/config.json | 8 + netmaster_wiki/docs/index.md | 70 ++++++ netmaster_wiki/requirements.txt | 3 + netmaster_wiki/static/style.css | 8 + netmaster_wiki/templates/index.html | 137 ++++++++++ netmaster_wiki/templates/page.html | 19 ++ netmaster_wiki/templates/pages.html | 22 ++ 15 files changed, 830 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/release-request.md create mode 100644 .github/copilot-instructions.md create mode 100644 CHANGELOG.md create mode 100644 VERSION create mode 100644 netmaster_wiki/README.md create mode 100644 netmaster_wiki/__pycache__/app.cpython-312.pyc create mode 100644 netmaster_wiki/app.py create mode 100644 netmaster_wiki/config.json create mode 100644 netmaster_wiki/docs/index.md create mode 100644 netmaster_wiki/requirements.txt create mode 100644 netmaster_wiki/static/style.css create mode 100644 netmaster_wiki/templates/index.html create mode 100644 netmaster_wiki/templates/page.html create mode 100644 netmaster_wiki/templates/pages.html diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..5480c3f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Melde einen Fehler oder ein unerwartetes Verhalten. +title: "bug: " +labels: bug +assignees: '' +--- + +## Beschreibe den Fehler + +Schreibe kurz, was passiert, und wie man es reproduziert. + +## Reproduktion + +Schritte um den Fehler lokal zu reproduzieren: + +1. Schritt 1 +2. Schritt 2 + +## Erwartetes Verhalten + +Was hättest du erwartet? + +## Logs / Fehlermeldungen + +Füge relevante Fehlermeldungen, Stacktraces oder Links zu CI-Logs hinzu. diff --git a/.github/ISSUE_TEMPLATE/release-request.md b/.github/ISSUE_TEMPLATE/release-request.md new file mode 100644 index 0000000..2db044e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release-request.md @@ -0,0 +1,30 @@ +--- +name: Release / Version bump +about: Verwende diese Vorlage, um eine neue Version oder Release anzufragen. +title: "chore(release): bump version to " +labels: release +assignees: '' +--- + +## Ziel + +Welche Version soll veröffentlicht werden? (SemVer) + +- Neue Version: `0.1.1` + +## Änderungen + +Kurze Liste der Änderungen, die in diesem Release enthalten sind (linke PRs oder Commits): + +- PR #12 — Fix: something +- PR #11 — Feat: add scaffold + +## Risiko und Rollback + +Gibt es breaking changes? Wie kann man zurückrollen? + +## Release-Steps (für Maintainer) + +1. Update `VERSION` auf die neue SemVer +2. Ergänze `CHANGELOG.md` mit einem Abschnitt für die Version +3. Commit, Tag und Push (siehe `.github/copilot-instructions.md`) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..cbc8850 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,216 @@ +````instructions +## Kurzanleitung für KI-Coding-Agenten + +Dieses Projekt enthält aktuell nur minimale Metadaten (z. B. `README.md`, `LICENSE`). Es liegen keine Quellcode-Dateien, Build- oder CI-Konfigurationen vor. Verwende die folgenden, konkreten Schritte, um produktiv zu starten, Entscheidungen nachzuweisen und sinnvolle PR-Vorschläge zu machen. + +1) Schnelle Repo-Discovery + +- Öffne und lese `README.md` und die Projekt-Root (bereits vorhanden). +- Prüfe systematisch auf typische Build-/Sprach-Indikatoren (Beispiele): + +```bash +# prüfe nach Node/Python/Go/Rust/Java/Gradle/Maven/Elterndateien +git ls-files | grep -E "package.json|pyproject.toml|requirements.txt|setup.py|go.mod|Cargo.toml|pom.xml|build.gradle|Makefile|Dockerfile" -n || true +``` + +- Falls keine der Dateien vorhanden ist (wie aktuell), dokumentiere das kurz in deinem PR und schlage eine sinnvolle erste Aufgabe vor (z. B. Projekt-Scaffold, README-Erweiterung, CI-Workflow). + +2) Architektur & "Big Picture" + +- In diesem Repository sind keine Komponenten oder Services gefunden. Wenn du neue Code-Dateien hinzufügst, beschreibe in der PR-Beschreibung immer: + - Ziel und Verantwortlichkeit der Komponente (Input/Output, Fehlerfälle) + - Wo Code leben soll (z. B. `src/`, `cmd/`, `pkg/` oder `lib/` je nach Sprache) + - Minimale Lauf-/Test-Schritte zum Verifizieren + +3) Projekt-spezifische Workflows (aktuell keine vorhanden) + +- Da kein Build/Test definiert ist, liefere in deinem Vorschlag eindeutige, automatisierte Schritte: + - Beispiel für Node.js: `npm install && npm test` + - Beispiel für Python: `python -m venv .venv && .venv/bin/pip install -r requirements.txt && pytest` + +- Wenn du CI hinzufügen willst, erstelle eine einfache GitHub Actions Workflow-Datei in `.github/workflows/` mit einem sehr schlanken Job (checkout + Setup + test). Verweise in der PR auf die minimalen Erfolgskriterien. + +4) Konventionen & Patterns (was du hier finden/setzen sollst) + +- Namenskonvention: Falls du ein Sprach-Scaffold anlegst, folge den üblichen Konventionen der Sprache (z. B. `src/` für Python/TS, `cmd/` + `pkg/` für Go). Dokumentiere die gewählte Konvention in `README.md`. +- Commit/PR-Nachrichten: kurze Titelzeile, 1–2 Zeilen Beschreibung, ein Abschnitt "How to test" mit den minimalen Schritten. + +5) Integration & externe Abhängigkeiten + +- Es sind keine Integration-Punkte (APIs, DBs, cloud infra) detektierbar. Wenn du solche hinzufügst, nenne in der PR: + - Endpunkte/Umgebungsvariablen (nur Namen, keine Geheimnisse) + - Minimal reproduzierbare Local-Run-Anleitung + +6) Beispiele & Templates (benutze diese Vorlagen in PRs) + +- PR-Beschreibung (kurz): + - Was wurde geändert + - Warum (Motivation) + - Wie zu testen (copy-paste Befehle) + +- Commit-Beispiel-Titel: `chore: scaffold project (language)` oder `feat: add initial CI workflow` + +7) Wenn du unsicher bist + +- Stelle eine präzise Frage in der PR-Description (z. B. "Welche Sprache bevorzugst du für dieses Projekt?") und biete 2-3 vorgeschlagene Optionen (z. B. Node.js scaffold, Python package, minimal Go module). + +8) Files to reference + +- `README.md` — aktuell die einzige inhaltliche Datei; erweitere sie bei allen größeren Änderungen. + +--- +Wenn du möchtest, kann ich sofort ein erstes Scaffolding vorschlagen (z. B. `node` oder `python`) und eine PR mit README-, CI- und Minimal-Test hinzufügen — nenne kurz welche Sprache/Stack du bevorzugst oder lass mich Vorschläge machen. + +## Versionierung & Releases + +Dieses Repository verwendet aktuell noch kein automatisches Release-System. Lege folgenden, einfachen Workflow an, damit Änderungen nachvollziehbar und reproduzierbar sind: + +- Datei `VERSION`: enthält die aktuelle Release-Version (SemVer), z. B. `0.1.0`. +- Datei `CHANGELOG.md`: chronologische Liste von Releases mit kurzen Beschreibungen. +- Release-Prozess (manuell für Start): + +```bash +# 1. Inkrementiere VERSION (z. B. 0.1.0 -> 0.1.1) +echo "0.1.1" > VERSION +# 2. Ergänze CHANGELOG.md mit Einträgen für die neue Version +# 3. Commit + Tag +git add VERSION CHANGELOG.md +git commit -m "chore(release): bump version to 0.1.1" +git tag -a v0.1.1 -m "Release v0.1.1" +git push --follow-tags +``` + +Hinweis für Agenten: Verwende SemVer (MAJOR.MINOR.PATCH). Schreibe in Pull Requests kurz in den Titel oder das Release-Issue, welche SemVer-Schritte erforderlich sind (z. B. `patch` für Bugfixes, `minor` für neue Features, `major` für breaking changes). + +Automatisierungsempfehlung: Später kann eine GitHub Actions-Workflowdatei (z. B. `.github/workflows/release.yml`) hinzugefügt werden, die bei Merge in `main` automatisch die Version taggt und ein GitHub Release erstellt. + +## Issue-Vorlage für Releases + +Im Ordner `.github/ISSUE_TEMPLATE/` liegt eine Vorlage, die verwendet werden soll, um Release/Version-Requests einheitlich zu erfassen. Nutze diese Vorlage, wenn du ein Release anstößt oder eine Versionserhöhung vorschlägst. + +--- + +## NETMASTER WIKI (lokal) + +Ich habe ein kleines lokales Wiki unter `netmaster_wiki/` hinzugefügt. Es ist ein Minimal‑Flask-Service, der folgende Funktionen bietet: + +- Web-UI zum Einfügen von Markdown (`/`) +- Seiten werden als `.md` in `netmaster_wiki/pages/` gespeichert (Front-Matter: title/date/tags) +- Button "Tags generieren" erzeugt Vorschläge per einfacher Heuristik (`/autotags`) +- Feedback/Autoupdater-Einträge werden in `netmaster_wiki/feedback.json` gesammelt (`/feedback`) + +Schnellstart: + +```bash +cd netmaster_wiki +python3 -m venv .venv +. .venv/bin/activate +pip install -r requirements.txt +python app.py +# Öffne http://127.0.0.1:5000 +``` + +Use-cases für Agenten: +- Beim Scaffolding: fülle `pages/` mit initialen HowTo‑Markdowns. +- Nach Änderungen an `VERSION`/`CHANGELOG.md`: erstelle optional einen Release-Eintrag im Wiki. +- Autoupdater-Feedback kann via UI oder POST an `/feedback` eingereicht werden. + +Dateien: +- `netmaster_wiki/app.py` — Hauptserver +- `netmaster_wiki/templates/` — UI-Templates +- `netmaster_wiki/static/` — CSS +- `netmaster_wiki/pages/` — gespeicherte Seiten (werden bei Bedarf angelegt) +- `netmaster_wiki/feedback.json` — gespeichertes Feedback (JSON-Array) + +```` +## Kurzanleitung für KI-Coding-Agenten + +Dieses Projekt enthält aktuell nur minimale Metadaten (z. B. `README.md`, `LICENSE`). Es liegen keine Quellcode-Dateien, Build- oder CI-Konfigurationen vor. Verwende die folgenden, konkreten Schritte, um produktiv zu starten, Entscheidungen nachzuweisen und sinnvolle PR-Vorschläge zu machen. + +1) Schnelle Repo-Discovery + +- Öffne und lese `README.md` und die Projekt-Root (bereits vorhanden). +- Prüfe systematisch auf typische Build-/Sprach-Indikatoren (Beispiele): + +```bash +# prüfe nach Node/Python/Go/Rust/Java/Gradle/Maven/Elterndateien +git ls-files | grep -E "package.json|pyproject.toml|requirements.txt|setup.py|go.mod|Cargo.toml|pom.xml|build.gradle|Makefile|Dockerfile" -n || true +``` + +- Falls keine der Dateien vorhanden ist (wie aktuell), dokumentiere das kurz in deinem PR und schlage eine sinnvolle erste Aufgabe vor (z. B. Projekt-Scaffold, README-Erweiterung, CI-Workflow). + +2) Architektur & "Big Picture" + +- In diesem Repository sind keine Komponenten oder Services gefunden. Wenn du neue Code-Dateien hinzufügst, beschreibe in der PR-Beschreibung immer: + - Ziel und Verantwortlichkeit der Komponente (Input/Output, Fehlerfälle) + - Wo Code leben soll (z. B. `src/`, `cmd/`, `pkg/` oder `lib/` je nach Sprache) + - Minimale Lauf-/Test-Schritte zum Verifizieren + +3) Projekt-spezifische Workflows (aktuell keine vorhanden) + +- Da kein Build/Test definiert ist, liefere in deinem Vorschlag eindeutige, automatisierte Schritte: + - Beispiel für Node.js: `npm install && npm test` + - Beispiel für Python: `python -m venv .venv && .venv/bin/pip install -r requirements.txt && pytest` + +- Wenn du CI hinzufügen willst, erstelle eine einfache GitHub Actions Workflow-Datei in `.github/workflows/` mit einem sehr schlanken Job (checkout + Setup + test). Verweise in der PR auf die minimalen Erfolgskriterien. + +4) Konventionen & Patterns (was du hier finden/setzen sollst) + +- Namenskonvention: Falls du ein Sprach-Scaffold anlegst, folge den üblichen Konventionen der Sprache (z. B. `src/` für Python/TS, `cmd/` + `pkg/` für Go). Dokumentiere die gewählte Konvention in `README.md`. +- Commit/PR-Nachrichten: kurze Titelzeile, 1–2 Zeilen Beschreibung, ein Abschnitt "How to test" mit den minimalen Schritten. + +5) Integration & externe Abhängigkeiten + +- Es sind keine Integration-Punkte (APIs, DBs, cloud infra) detektierbar. Wenn du solche hinzufügst, nenne in der PR: + - Endpunkte/Umgebungsvariablen (nur Namen, keine Geheimnisse) + - Minimal reproduzierbare Local-Run-Anleitung + +6) Beispiele & Templates (benutze diese Vorlagen in PRs) + +- PR-Beschreibung (kurz): + - Was wurde geändert + - Warum (Motivation) + - Wie zu testen (copy-paste Befehle) + +- Commit-Beispiel-Titel: `chore: scaffold project (language)` oder `feat: add initial CI workflow` + +7) Wenn du unsicher bist + +- Stelle eine präzise Frage in der PR-Description (z. B. "Welche Sprache bevorzugst du für dieses Projekt?") und biete 2-3 vorgeschlagene Optionen (z. B. Node.js scaffold, Python package, minimal Go module). + +8) Files to reference + +- `README.md` — aktuell die einzige inhaltliche Datei; erweitere sie bei allen größeren Änderungen. + +--- +Wenn du möchtest, kann ich sofort ein erstes Scaffolding vorschlagen (z. B. `node` oder `python`) und eine PR mit README-, CI- und Minimal-Test hinzufügen — nenne kurz welche Sprache/Stack du bevorzugst oder lass mich Vorschläge machen. + +## Versionierung & Releases + +Dieses Repository verwendet aktuell noch kein automatisches Release-System. Lege folgenden, einfachen Workflow an, damit Änderungen nachvollziehbar und reproduzierbar sind: + +- Datei `VERSION`: enthält die aktuelle Release-Version (SemVer), z. B. `0.1.0`. +- Datei `CHANGELOG.md`: chronologische Liste von Releases mit kurzen Beschreibungen. +- Release-Prozess (manuell für Start): + +```bash +# 1. Inkrementiere VERSION (z. B. 0.1.0 -> 0.1.1) +echo "0.1.1" > VERSION +# 2. Ergänze CHANGELOG.md mit Einträgen für die neue Version +# 3. Commit + Tag +git add VERSION CHANGELOG.md +git commit -m "chore(release): bump version to 0.1.1" +git tag -a v0.1.1 -m "Release v0.1.1" +git push --follow-tags +``` + +Hinweis für Agenten: Verwende SemVer (MAJOR.MINOR.PATCH). Schreibe in Pull Requests kurz in den Titel oder das Release-Issue, welche SemVer-Schritte erforderlich sind (z. B. `patch` für Bugfixes, `minor` für neue Features, `major` für breaking changes). + +Automatisierungsempfehlung: Später kann eine GitHub Actions-Workflowdatei (z. B. `.github/workflows/release.yml`) hinzugefügt werden, die bei Merge in `main` automatisch die Version taggt und ein GitHub Release erstellt. + +## Issue-Vorlage für Releases + +Im Ordner `.github/ISSUE_TEMPLATE/` liegt eine Vorlage, die verwendet werden soll, um Release/Version-Requests einheitlich zu erfassen. Nutze diese Vorlage, wenn du ein Release anstößt oder eine Versionserhöhung vorschlägst. + +--- + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0e4f232 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +Alle signifikanten Änderungen an diesem Projekt werden in diesem Dokument festgehalten. + +## [0.1.0] - 2025-11-01 +- Initiales Repository-Scaffold: `README.md`, `LICENSE`, `.github/copilot-instructions.md`, `VERSION`. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..6e8bf73 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0 diff --git a/netmaster_wiki/README.md b/netmaster_wiki/README.md new file mode 100644 index 0000000..3294407 --- /dev/null +++ b/netmaster_wiki/README.md @@ -0,0 +1,51 @@ +# NETMASTER WIKI + +Ein kleines, lokales Wiki für das NETCODE-Repository. Ziel ist ein schneller, lokaler Editor, mit dem Markdown-Seiten erstellt werden können, sowie eine einfache Feedback-Schnittstelle (z. B. für Autoupdater-Feedback). + +Start (lokal, Entwicklung): + +```bash +python3 -m venv .venv +. .venv/bin/activate +pip install -r requirements.txt +python app.py +# dann im Browser öffnen: http://127.0.0.1:5000 +``` + +Konzept +- Seiten werden unter `pages/` als Markdown-Dateien mit einfacher Front-Matter (title/date/tags) gespeichert. +- Tags werden automatisch per Heuristik aus dem Inhalt vorgeschlagen; es gibt ein UI-Button "Tags generieren". +- Feedback wird in `feedback.json` gesammelt. + +Hinweis: Dieses Tool ist minimal und für lokale Nutzung gedacht. Für produktive Nutzung sollte man Authentifizierung, Validation, Versionskontrolle und robuste Tagging-Logik ergänzen. + +Unsichere Quellen +----------------- +Das Wiki unterstützt optionales server-seitiges Abrufen externer URLs über den Endpoint `/fetch`. +Unsichere TLS-Verbindungen (z. B. verify=False) werden nur zugelassen, wenn: + +- Du einen `admin_token` in `netmaster_wiki/config.json` gesetzt hast (ändert `CHANGE_ME_TOKEN`). +- Der Request das Token in Header `X-Admin-Token` oder im JSON-Feld `token` liefert. +- Und entweder `allow_insecure_global` in `config.json` auf `true` gesetzt ist oder der Zielhost in `trusted_hosts` gelistet ist. + +Beispiel (curl) — sicherer Fetch: + +```bash +curl -X POST -H "Content-Type: application/json" -d '{"url":"https://example.com"}' http://127.0.0.1:5000/fetch +``` + +Beispiel (curl) — unsicherer Fetch erlaubt (nur wenn token & trusted host konfiguriert sind): + +```bash +curl -X POST -H "Content-Type: application/json" -H "X-Admin-Token: CHANGE_ME_TOKEN" -d '{"url":"https://self-signed.example.local","insecure":true}' http://127.0.0.1:5000/fetch +``` + +Warnung: Diese Funktion ist mächtig und kann Sicherheitsrisiken bergen. Aktiviere sie nur in kontrollierten, lokalen oder vertrauenswürdigen Umgebungen. + +Browser-Admin-UI +---------------- +Im Wiki findest du jetzt eine Admin-Sektion auf der Index-Seite, in der du dein `admin_token` lokal im Browser (localStorage) speichern und serverseitige Fetches ausführen kannst. Das Token wird nicht an anderen Stellen im Repo gespeichert. + +Hinweis: Das Speichern des Tokens im Browser ist praktisch für lokale Betreiber, aber nicht so sicher wie ein serverseitig verwalteter Secret-Store. Nutze es nur lokal. + +Siehe auch die öffentliche Dokumentation zur Index-UI: `netmaster_wiki/docs/index.md` — dort sind UI‑Abläufe, Beispiele und Sicherheits‑Hinweise zusammengefasst. diff --git a/netmaster_wiki/__pycache__/app.cpython-312.pyc b/netmaster_wiki/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c5df531a5f0c4ca3a31c1e118cf08c70e104e13 GIT binary patch literal 12722 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 tupYMNyY>3LD&pNX`<_ str: + s = s.lower() + s = re.sub(r"[^a-z0-9]+", "-", s) + s = s.strip("-") + s = re.sub(r"-+", "-", s) + return s or "untitled" + + +def extract_tags(text: str, top_n: int = 6): + words = re.findall(r"[a-zA-ZäöüÄÖÜß0-9]{3,}", text.lower()) + words = [w for w in words if w not in STOPWORDS] + cnt = Counter(words) + tags = [w for w, _ in cnt.most_common(top_n)] + return tags + + +def is_trusted_host(url: str) -> bool: + try: + p = urllib.parse.urlparse(url) + host = p.hostname or '' + for th in TRUSTED_HOSTS: + if host == th or host.endswith('.' + th): + return True + except Exception: + return False + return False + + +@app.route('/fetch', methods=['POST']) +def fetch_url(): + """Fetch a URL server-side. Allows insecure TLS only when explicitly authorized. + + JSON body: { "url": "...", "insecure": true/false } + Header or json field: 'X-Admin-Token' or 'token' must match CONFIG.admin_token to allow insecure fetches. + Only hosts listed in `trusted_hosts` may be fetched with insecure TLS when requested. + """ + data = request.get_json(force=True) or {} + url = data.get('url') or request.form.get('url') + if not url: + return jsonify({'ok': False, 'error': 'url required'}), 400 + insecure_req = bool(data.get('insecure', False) or request.form.get('insecure', False)) + token = request.headers.get('X-Admin-Token') or data.get('token') or request.form.get('token') + + # authorize insecure only if token matches admin and host is trusted or global flag set + if insecure_req: + if not ADMIN_TOKEN: + return jsonify({'ok': False, 'error': 'server not configured for insecure fetches'}), 403 + if token != ADMIN_TOKEN: + return jsonify({'ok': False, 'error': 'invalid admin token'}), 403 + if not (ALLOW_INSECURE_GLOBAL or is_trusted_host(url)): + return jsonify({'ok': False, 'error': 'host not allowed for insecure fetch'}), 403 + + try: + resp = requests.get(url, timeout=10, verify=not insecure_req) + return (resp.content, resp.status_code, {'Content-Type': resp.headers.get('Content-Type', 'application/octet-stream')}) + except Exception as e: + return jsonify({'ok': False, 'error': str(e)}), 502 + + + +def page_path(slug: str) -> str: + return os.path.join(PAGES_DIR, f"{slug}.md") + + +@app.route("/") +def index(): + # simple form to create pages and submit feedback + pages = [] + for fn in sorted(os.listdir(PAGES_DIR)): + if fn.endswith('.md'): + pages.append(fn[:-3]) + return render_template("index.html", pages=pages) + + +@app.route("/autotags", methods=["POST"]) +def autotags(): + data = request.get_json(force=True) or {} + text = data.get("text", "") + tags = extract_tags(text) + return jsonify({"tags": tags}) + + +@app.route("/save", methods=["POST"]) +def save(): + title = request.form.get("title", "Untitled").strip() + content = request.form.get("content", "").strip() + tags_in = request.form.get("tags", "").strip() + if not title and not content: + abort(400, "Title or content required") + slug = slugify(title or content[:40]) + if tags_in: + tags = [t.strip() for t in tags_in.split(',') if t.strip()] + else: + tags = extract_tags(title + "\n" + content) + meta = { + "title": title or slug, + "date": datetime.utcnow().isoformat() + "Z", + "tags": tags, + } + md = "---\n" + md += f"title: {meta['title']}\n" + md += f"date: {meta['date']}\n" + md += f"tags: {json.dumps(meta['tags'])}\n" + md += "---\n\n" + md += content + "\n" + with open(page_path(slug), "w", encoding="utf-8") as f: + f.write(md) + return redirect(url_for('view_page', slug=slug)) + + +@app.route("/pages") +def pages_list(): + pages = [] + for fn in sorted(os.listdir(PAGES_DIR)): + if fn.endswith('.md'): + pages.append(fn[:-3]) + return render_template("pages.html", pages=pages) + + +@app.route("/page/") +def view_page(slug): + path = page_path(slug) + if not os.path.exists(path): + abort(404) + with open(path, encoding="utf-8") as f: + text = f.read() + # naive split frontmatter + parts = text.split('---', 2) + if len(parts) >= 3: + _, meta_raw, body = parts + else: + meta_raw = "" + body = text + # try to parse tags from meta + tags = [] + m = re.search(r"tags:\s*(\[.*\])", meta_raw) + if m: + try: + tags = json.loads(m.group(1)) + except Exception: + tags = [] + # render markdown (if markdown lib is available) + try: + import markdown as md + html = md.markdown(body) + except Exception: + # fallback: show raw markdown in pre + html = f"
{body}
" + return render_template("page.html", title=slug, content=html, tags=tags) + + +@app.route("/feedback", methods=["POST"]) +def feedback(): + data = request.get_json(force=True) or {} + msg = data.get('message') or data.get('msg') or '' + source = data.get('source') or 'web' + who = data.get('who') or '' + if not msg: + return jsonify({"ok": False, "error": "message required"}), 400 + entry = { + "message": msg, + "who": who, + "source": source, + "ts": datetime.utcnow().isoformat() + 'Z' + } + if os.path.exists(FEEDBACK_FILE): + with open(FEEDBACK_FILE, encoding='utf-8') as f: + try: + arr = json.load(f) + except Exception: + arr = [] + else: + arr = [] + arr.append(entry) + with open(FEEDBACK_FILE, 'w', encoding='utf-8') as f: + json.dump(arr, f, indent=2, ensure_ascii=False) + return jsonify({"ok": True}) + + +if __name__ == '__main__': + # simple dev server + app.run(host='127.0.0.1', port=5000, debug=True) diff --git a/netmaster_wiki/config.json b/netmaster_wiki/config.json new file mode 100644 index 0000000..1200c56 --- /dev/null +++ b/netmaster_wiki/config.json @@ -0,0 +1,8 @@ +{ + "admin_token": "CHANGE_ME_TOKEN", + "allow_insecure_global": false, + "trusted_hosts": [ + "localhost", + "127.0.0.1" + ] +} diff --git a/netmaster_wiki/docs/index.md b/netmaster_wiki/docs/index.md new file mode 100644 index 0000000..86d56e3 --- /dev/null +++ b/netmaster_wiki/docs/index.md @@ -0,0 +1,70 @@ +# NETMASTER WIKI — Public Docs (Index UI) + +Diese Seite dokumentiert die öffentliche Benutzeroberfläche, die in `netmaster_wiki/templates/index.html` liegt. Sie beschreibt die Funktionalitäten, typische Abläufe und Sicherheits-Hinweise für Betreiber. + +Kurzüberblick + +- Editor: Ein einfaches Formular zum Anlegen von Markdown-Seiten (Titel + Inhalt). Beim Speichern wird die Seite unter `netmaster_wiki/pages/.md` abgelegt. +- Tags generieren: Button "Tags generieren" ruft `/autotags` auf und füllt das Tag-Feld mit Vorschlägen. +- Seitenliste: Unterhalb des Formulars werden vorhandene Seiten verlinkt. +- Autoupdater-Feedback: Formular sendet JSON an `/feedback` und speichert Einträge in `netmaster_wiki/feedback.json`. +- Admin-Fetch (nur Betreiber): Ein kleiner Admin‑Bereich erlaubt das Speichern eines Admin-Tokens im Browser (localStorage) und das Ausführen serverseitiger Fetches an `/fetch` (optional: unsichere TLS-Verbindungen, nur mit Token). + +How-to (quick) + +1. Lokalen Server starten (im Ordner `netmaster_wiki`): + +```bash +python3 -m venv .venv +. .venv/bin/activate +pip install -r requirements.txt +python app.py +# Öffne http://127.0.0.1:5000 +``` + +2. Neue Seite erstellen +- Titel und Markdown eingeben → Speichern. +- Tags: entweder manuell eingeben (kommagetrennt) oder "Tags generieren" klicken. + +3. Feedback absenden +- Nachricht in "Autoupdater Feedback" eingeben → Senden (POST `/feedback`). + +Admin-Fetch (Schritt-für-Schritt) + +1. Konfig: Lege `netmaster_wiki/config.json` an und setze `admin_token` (nicht `CHANGE_ME_TOKEN`), füge vertrauenswürdige Hosts zu `trusted_hosts` oder setze `allow_insecure_global` auf `true` (vorsichtig!). +2. In der Index-UI: Token eingeben → "Token speichern" (wird in localStorage gehalten). +3. URL eingeben, ggf. "Unsichere TLS zulassen" wählen und "Fetch ausführen" klicken. + +Beispiel: Server-seitiger Fetch (curl) + +Sicherer Fetch (kein Token nötig): + +```bash +curl -X POST -H "Content-Type: application/json" \ + -d '{"url":"https://example.com"}' \ + http://127.0.0.1:5000/fetch +``` + +Unsicherer Fetch (nur mit Token und Trusted Host): + +```bash +curl -X POST -H "Content-Type: application/json" -H "X-Admin-Token: " \ + -d '{"url":"https://self-signed.local","insecure":true}' \ + http://127.0.0.1:5000/fetch +``` + +Wichtige Sicherheits-Hinweise + +- Das Admin-Token, das in der UI gespeichert wird, liegt lokal im Browser (localStorage). Es wird nicht serverseitig geschützt; verwende diese Funktion nur lokal oder in einem vertrauenswürdigen Umfeld. +- Aktivieren von `allow_insecure_global` oder das Zulassen unsicherer TLS-Verbindungen öffnet Angriffsflächen. Nutze stattdessen `trusted_hosts` und setze dort explizit interne Domains. +- Für produktive Nutzung: HTTPS für das Wiki, serverseitige Secrets (Umgebungsvariablen), Authentifizierung, CSRF-Schutz und Ratenbegrenzung implementieren. + +Wichtige Dateipfade + +- `netmaster_wiki/templates/index.html` — die UI-Quelle. +- `netmaster_wiki/app.py` — Endpoints: `/`, `/save`, `/autotags`, `/pages`, `/page/`, `/feedback`, `/fetch`. +- `netmaster_wiki/pages/` — gespeicherte Markdown-Seiten. +- `netmaster_wiki/feedback.json` — gesammeltes Feedback. +- `netmaster_wiki/config.json` — (optional) Admin-Token, trusted hosts, flags. + +Wenn du möchtest, kann ich diese Docs als HTML-Seite rendern oder eine kleine Navigation im Repo-Root ergänzen (z. B. `docs/netmaster_index.md`), damit sie leichter öffentlich erreichbar ist. Sag Bescheid, wie du die Docs veröffentlichen willst. diff --git a/netmaster_wiki/requirements.txt b/netmaster_wiki/requirements.txt new file mode 100644 index 0000000..9d576e8 --- /dev/null +++ b/netmaster_wiki/requirements.txt @@ -0,0 +1,3 @@ +Flask>=2.0 +markdown>=3.0 +requests>=2.0 diff --git a/netmaster_wiki/static/style.css b/netmaster_wiki/static/style.css new file mode 100644 index 0000000..854cb9f --- /dev/null +++ b/netmaster_wiki/static/style.css @@ -0,0 +1,8 @@ +body{font-family:system-ui,Segoe UI,Roboto,Helvetica,Arial;margin:0;padding:1rem;background:#f7f7fb;color:#111} +main{max-width:900px;margin:0 auto;background:#fff;padding:1.25rem;border-radius:8px;box-shadow:0 6px 20px rgba(0,0,0,.06)} +label{display:block;margin:0.5rem 0} +input[type=text],textarea{width:100%;padding:.5rem;border:1px solid #ddd;border-radius:6px;font-family:inherit} +button{background:#2563eb;color:white;padding:.5rem .75rem;border-radius:6px;border:0} +.tags{margin:.5rem 0} +.tag{background:#eef2ff;padding:.25rem .5rem;border-radius:4px;margin-right:.25rem} +.content{border-top:1px dashed #eee;padding-top:1rem} diff --git a/netmaster_wiki/templates/index.html b/netmaster_wiki/templates/index.html new file mode 100644 index 0000000..615546c --- /dev/null +++ b/netmaster_wiki/templates/index.html @@ -0,0 +1,137 @@ + + + + + + NETMASTER WIKI + + + +
+

NETMASTER WIKI

+
+
+ + + +
+ + +
+
+
+ +
+

Seiten

+
    + {% for p in pages %} +
  • {{ p }}
  • + {% else %} +
  • Keine Seiten vorhanden
  • + {% endfor %} +
+
+ +
+

Autoupdater Feedback

+
+ +
+
+
+
+ +
+

Admin: Fetch externer Ressourcen

+

Nur für Betreiber: Du kannst hier ein Admin-Token lokal im Browser speichern und damit serverseitige Fetches (auch unsicher) anstoßen. Das Token wird nur im lokalen localStorage gespeichert.

+ +
+ + + +
+ + + +
+ +
+
+
+
+ + + + diff --git a/netmaster_wiki/templates/page.html b/netmaster_wiki/templates/page.html new file mode 100644 index 0000000..cb4bad7 --- /dev/null +++ b/netmaster_wiki/templates/page.html @@ -0,0 +1,19 @@ + + + + + + {{ title }} + + + +
+ ← Zurück +

{{ title }}

+ {% if tags %} +
Tags: {% for t in tags %}{{ t }}{% endfor %}
+ {% endif %} +
{{ content|safe }}
+
+ + diff --git a/netmaster_wiki/templates/pages.html b/netmaster_wiki/templates/pages.html new file mode 100644 index 0000000..1fdaf5a --- /dev/null +++ b/netmaster_wiki/templates/pages.html @@ -0,0 +1,22 @@ + + + + + + Seiten + + + +
+ ← Zurück +

Alle Seiten

+
    + {% for p in pages %} +
  • {{ p }}
  • + {% else %} +
  • Keine Seiten vorhanden
  • + {% endfor %} +
+
+ + From 524efab43bf2b3cd281bc0d3a4d6ad1333858a6c Mon Sep 17 00:00:00 2001 From: Me7aminD <114676544+7IKED@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:05:05 +0000 Subject: [PATCH 2/2] chore(wiki): add CSRF token usage to index UI and ensure server uses env-based admin token/rate-limits --- netmaster_wiki/templates/index.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/netmaster_wiki/templates/index.html b/netmaster_wiki/templates/index.html index 615546c..7ffe9a2 100644 --- a/netmaster_wiki/templates/index.html +++ b/netmaster_wiki/templates/index.html @@ -11,6 +11,7 @@

NETMASTER WIKI

+ @@ -61,16 +62,17 @@

Admin: Fetch externer Ressourcen