d4rkbot: API v1 mit Key-System, Env-Diät, Rebranding

- API-Keys (SHA-256-Hash, Scopes, last_used) — Verwaltung auf der Setup-Seite,
  Klartext-Key wird genau einmal angezeigt
- /api/v1: message, dm, roles (add/remove), member/:id, stats — Bearer-Auth
  mit Scope-Prüfung, Embed-Sanitizing, README-Doku mit Python-Beispiel
- Env-Diät: PUBLIC_URL + GITEA_URL jetzt Settings (Env nur Fallback),
  OAuth-Redirect dynamisch; Env enthält nur noch Secrets/Bootstrap
- Rebranding ecobot → d4rkbot (Packages, Container, Cookies, README);
  Volume-Name bleibt ecobot_data (Datenerhalt), Portainer-Stack-Name bleibt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 11:56:48 +02:00
co-authored by Claude Opus 4.8
parent eb51be4ebc
commit 143288affa
19 changed files with 468 additions and 37 deletions
+3 -2
View File
@@ -1,5 +1,6 @@
// Minimaler Gitea-API-Client (Token-Auth) — für /bug → Issues
import { config } from './config.js';
import { giteaUrl } from './runtime-settings.js';
function headers(extra = {}) {
return {
@@ -11,7 +12,7 @@ function headers(extra = {}) {
/** Issue anlegen; gibt { number, html_url } zurück */
export async function createIssue(repo, title, body) {
const res = await fetch(`${config.giteaUrl}/api/v1/repos/${repo}/issues`, {
const res = await fetch(`${giteaUrl()}/api/v1/repos/${repo}/issues`, {
method: 'POST',
headers: headers({ 'Content-Type': 'application/json' }),
body: JSON.stringify({ title, body }),
@@ -28,7 +29,7 @@ export async function uploadIssueAsset(repo, issueNumber, filename, buffer) {
const form = new FormData();
form.append('attachment', new Blob([buffer]), filename);
const res = await fetch(
`${config.giteaUrl}/api/v1/repos/${repo}/issues/${issueNumber}/assets?name=${encodeURIComponent(filename)}`,
`${giteaUrl()}/api/v1/repos/${repo}/issues/${issueNumber}/assets?name=${encodeURIComponent(filename)}`,
{ method: 'POST', headers: headers(), body: form }
);
if (!res.ok) {