alvin-bot 4.12.0 → 4.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,385 @@
1
+ ---
2
+ name: social-fetch
3
+ description: Use when the user shares an Instagram, TikTok, YouTube, or Twitter/X URL and wants the content analyzed, fact-checked, and optionally saved. Also use when user says "check this", "was sagst du dazu", "schau dir das an", "analyze this post", "is this legit", or pastes a social media link without further instruction.
4
+ user-invocable: true
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Edit
9
+ - Bash
10
+ - Glob
11
+ - Grep
12
+ - Agent
13
+ - WebSearch
14
+ - WebFetch
15
+ ---
16
+
17
+ # Social Media Fetch & Intelligence
18
+
19
+ Analysiert Social-Media-Content ganzheitlich: Download, Transkription, Bildanalyse, Faktencheck, Safety-Check, Nutzwert-Bewertung.
20
+
21
+ ## URL-Erkennung
22
+
23
+ Trigger bei URLs von:
24
+ - **Instagram:** `instagram.com/p/`, `instagram.com/reel/`, `instagram.com/stories/`
25
+ - **TikTok:** `tiktok.com/@`, `vm.tiktok.com/`
26
+ - **YouTube:** `youtube.com/watch`, `youtu.be/`, `youtube.com/shorts/`
27
+ - **Twitter/X:** `twitter.com/`, `x.com/`
28
+
29
+ ## Workflow
30
+
31
+ ```dot
32
+ digraph social_fetch {
33
+ rankdir=TB;
34
+ node [shape=box];
35
+
36
+ "URL erhalten" -> "1. Metadata extrahieren";
37
+ "1. Metadata extrahieren" -> "2. Content-Typ erkennen";
38
+ "2. Content-Typ erkennen" -> "3a. Video/Audio transkribieren" [label="Video/Reel"];
39
+ "2. Content-Typ erkennen" -> "3b. Bilder analysieren" [label="Bild/Carousel"];
40
+ "2. Content-Typ erkennen" -> "3a+3b" [label="Kombi"];
41
+ "3a. Video/Audio transkribieren" -> "4. Faktencheck";
42
+ "3b. Bilder analysieren" -> "4. Faktencheck";
43
+ "3a+3b" -> "4. Faktencheck";
44
+ "4. Faktencheck" -> "5. Tech/Safety Check" [label="Tech-Content?"];
45
+ "4. Faktencheck" -> "6. Nutzwert-Bewertung" [label="Sonstiges"];
46
+ "5. Tech/Safety Check" -> "6. Nutzwert-Bewertung";
47
+ "6. Nutzwert-Bewertung" -> "7. Report an User";
48
+ "7. Report an User" -> "8. Download-Frage";
49
+ }
50
+ ```
51
+
52
+ ## Phase 1: Metadata extrahieren
53
+
54
+ ```bash
55
+ # Universell via yt-dlp (funktioniert fuer YT, TikTok, IG, Twitter)
56
+ yt-dlp --dump-json --no-download "<URL>" > /tmp/social-meta.json
57
+
58
+ # Relevante Felder extrahieren
59
+ python3 -c "
60
+ import json
61
+ d = json.load(open('/tmp/social-meta.json'))
62
+ print(f'Title: {d.get(\"title\", \"?\")}' )
63
+ print(f'Uploader: {d.get(\"uploader\", d.get(\"channel\", \"?\"))}' )
64
+ print(f'Platform: {d.get(\"extractor_key\", \"?\")}' )
65
+ print(f'Duration: {d.get(\"duration\", 0)}s' )
66
+ print(f'Views: {d.get(\"view_count\", \"?\")}' )
67
+ print(f'Likes: {d.get(\"like_count\", \"?\")}' )
68
+ print(f'Upload date: {d.get(\"upload_date\", \"?\")}' )
69
+ print(f'Description: {d.get(\"description\", \"\")[:500]}' )
70
+ print(f'Thumbnails: {len(d.get(\"thumbnails\", []))}' )
71
+ print(f'Formats: {len(d.get(\"formats\", []))}' )
72
+ # Detect content type
73
+ has_video = d.get('duration', 0) > 0
74
+ has_images = 'carousel' in str(d).lower() or d.get('_type') == 'playlist'
75
+ print(f'Has video: {has_video}')
76
+ print(f'Has images: {has_images}')
77
+ "
78
+ ```
79
+
80
+ **Wenn yt-dlp fehlschlaegt** (private IG Posts etc.):
81
+ 1. Tier 2 CDP Browser: `~/.claude/hub/SCRIPTS/browser.sh cdp goto <url>` + Screenshot
82
+ 2. Cookies exportieren fuer yt-dlp: `--cookies /tmp/ig-cookies.txt`
83
+ 3. Oder `instaloader` fuer Instagram: `python3 -m instaloader -- -<shortcode>`
84
+
85
+ ## Phase 2: Content-Typ erkennen
86
+
87
+ | Signal | Typ | Naechster Schritt |
88
+ |--------|-----|-------------------|
89
+ | `duration > 0` | Video/Reel/Clip | Transkription + Bildanalyse (Thumbnails/Frames) |
90
+ | Carousel/Multi-Image | Bilderkarussell | Alle Bilder analysieren |
91
+ | Einzelbild, duration=0 | Statisches Bild | Bildanalyse |
92
+ | duration > 0 + Carousel | Kombi | Beides |
93
+
94
+ ## Phase 3a: Video/Audio transkribieren
95
+
96
+ ```bash
97
+ # 1. Audio extrahieren
98
+ yt-dlp -x --audio-format mp3 -o "/tmp/social-audio.%(ext)s" "<URL>"
99
+
100
+ # 2. Transkription via Groq Whisper (schnell + kostenlos)
101
+ curl -s https://api.groq.com/openai/v1/audio/transcriptions \
102
+ -H "Authorization: Bearer $GROQ_API_KEY" \
103
+ -F "file=@/tmp/social-audio.mp3" \
104
+ -F "model=whisper-large-v3-turbo" \
105
+ -F "response_format=text" > /tmp/social-transcript.txt
106
+
107
+ # 3. Falls >25MB: Erst komprimieren
108
+ ffmpeg -i /tmp/social-audio.mp3 -b:a 64k -ar 16000 /tmp/social-audio-small.mp3
109
+ ```
110
+
111
+ **Sprache:** Auto-Detect (kein `language` Parameter). Ergebnis in Originalsprache.
112
+
113
+ ## Phase 3b: Bilder analysieren
114
+
115
+ ```bash
116
+ # Thumbnail/Frame als Bild speichern
117
+ yt-dlp --write-thumbnail --skip-download -o "/tmp/social-thumb" "<URL>"
118
+
119
+ # Oder: Keyframes aus Video extrahieren (1 Frame pro 10s)
120
+ ffmpeg -i /tmp/social-video.mp4 -vf "fps=1/10" /tmp/social-frame-%03d.jpg
121
+ ```
122
+
123
+ **Bildanalyse** via Read-Tool (multimodal):
124
+ - Text im Bild lesen (OCR-artig)
125
+ - UI-Screenshots interpretieren
126
+ - Diagramme/Charts verstehen
127
+ - Code-Snippets erkennen
128
+ - Personen/Kontext beschreiben
129
+
130
+ ## Phase 4: Faktencheck
131
+
132
+ ### Allgemeiner Faktencheck
133
+ Fuer JEDEN Post durchfuehren:
134
+
135
+ 1. **Behauptungen extrahieren** — Was wird konkret behauptet? (Zahlen, Statistiken, Zitate, Fakten)
136
+ 2. **Quellen pruefen** — WebSearch nach jeder zentralen Behauptung
137
+ 3. **Bias erkennen** — Wer postet? Welches Interesse? Affiliate-Links? Sponsored?
138
+ 4. **Aktualitaet** — Stimmen die Infos noch? Veraltet?
139
+ 5. **Kontext** — Fehlt Kontext der die Aussage relativiert?
140
+
141
+ ### Bewertungsskala
142
+
143
+ | Emoji | Bewertung | Bedeutung |
144
+ |-------|-----------|-----------|
145
+ | :check: | Verifiziert | Fakten geprueft und korrekt |
146
+ | :warning: | Teilweise | Kern stimmt, aber Nuancen fehlen oder uebertrieben |
147
+ | :x: | Falsch/Irrefuehrend | Zentrale Behauptungen widerlegt |
148
+ | :question: | Nicht verifizierbar | Keine zuverlaessigen Quellen gefunden |
149
+
150
+ ## Phase 5: Tech/Safety Check (nur bei Tech-Content)
151
+
152
+ Wenn der Post ein **Tool, Library, GitHub-Repo, SaaS, API** bewirbt:
153
+
154
+ ### Repository finden
155
+ ```bash
156
+ # GitHub-Suche
157
+ gh search repos "<tool-name>" --sort=stars --limit=5
158
+ # Oder direkt wenn URL im Post
159
+ gh repo view <owner/repo> --json name,description,stargazersCount,forkCount,updatedAt,license,openIssues
160
+ ```
161
+
162
+ ### Safety-Checklist (Repo-Level)
163
+
164
+ | Check | Command | Red Flag |
165
+ |-------|---------|----------|
166
+ | Stars/Forks | `gh repo view --json stargazersCount` | <100 Stars bei "populaerem" Tool |
167
+ | Letzter Commit | `gh repo view --json updatedAt` | >6 Monate her |
168
+ | Lizenz | `gh repo view --json license` | Keine Lizenz / proprietaer |
169
+ | Issues | `gh repo view --json openIssues` | Viele offene Security-Issues |
170
+ | Dependencies | `gh api repos/{owner}/{repo}/dependency-graph/sbom` | Bekannte CVEs |
171
+ | README | Content pruefen | Kein README, kein Docs |
172
+ | Maintainer | `gh api users/{owner}` | Neuer Account, keine Historie |
173
+ | Funding/Sponsor | Check README/FUNDING.yml | Crypto/Scam-Signale |
174
+
175
+ ### Code Security Audit (PFLICHT bei Tools die man installieren/ausfuehren wuerde)
176
+
177
+ **Ziel:** Sicherstellen dass kein Schadcode, keine versteckten Backdoors, keine Datenexfiltration.
178
+
179
+ #### Quick Scan (immer durchfuehren)
180
+ ```bash
181
+ # 1. Repo klonen in temp
182
+ REPO_DIR=$(mktemp -d)
183
+ git clone --depth=1 <repo-url> "$REPO_DIR"
184
+
185
+ # 2. Verdaechtige Patterns suchen
186
+ grep -rn --include="*.{js,ts,py,sh,go,rs}" \
187
+ -E "(eval\(|exec\(|child_process|subprocess|os\.system|fetch\(|XMLHttpRequest|curl |wget |nc |reverse.shell|bind.shell)" \
188
+ "$REPO_DIR" | head -30
189
+
190
+ # 3. Hardcoded Secrets/IPs/Domains suchen
191
+ grep -rn --include="*.{js,ts,py,json,yml,yaml,toml}" \
192
+ -E "([0-9]{1,3}\.){3}[0-9]{1,3}|https?://[a-z0-9]+([\-\.][a-z0-9]+)*\.[a-z]{2,}" \
193
+ "$REPO_DIR" | grep -v "node_modules\|\.git\|localhost\|127\.0\.0\.1\|example\.com\|github\.com\|npmjs\|pypi" | head -20
194
+
195
+ # 4. Obfuscated Code erkennen
196
+ grep -rn --include="*.{js,ts}" \
197
+ -E "(atob\(|btoa\(|Buffer\.from\(.*base64|\\\\x[0-9a-f]{2}|\\\\u[0-9a-f]{4}|fromCharCode)" \
198
+ "$REPO_DIR" | head -10
199
+
200
+ # 5. Netzwerk-Calls in unerwarteten Stellen
201
+ grep -rn --include="*.{js,ts,py}" \
202
+ -E "(\.send\(|\.post\(|requests\.(get|post)|urllib|aiohttp|axios\.(get|post)|fetch\()" \
203
+ "$REPO_DIR" | grep -v "test\|spec\|__test__\|mock" | head -20
204
+
205
+ # 6. Aufraumen
206
+ rm -rf "$REPO_DIR"
207
+ ```
208
+
209
+ #### Deep Scan (bei verdaechtigen Findings oder bei Tools die Systemzugriff brauchen)
210
+ ```bash
211
+ # Package-Manager Checks
212
+ # NPM: postinstall Scripts sind ein beliebter Angriffsvektor
213
+ cat "$REPO_DIR/package.json" | python3 -c "
214
+ import json, sys
215
+ pkg = json.load(sys.stdin)
216
+ scripts = pkg.get('scripts', {})
217
+ for key in ['preinstall', 'postinstall', 'prepare', 'prepublish']:
218
+ if key in scripts:
219
+ print(f'⚠️ {key}: {scripts[key]}')
220
+ deps = {**pkg.get('dependencies', {}), **pkg.get('devDependencies', {})}
221
+ print(f'Dependencies: {len(deps)}')
222
+ "
223
+
224
+ # Python: setup.py kann beliebigen Code ausfuehren
225
+ grep -n "os\.\|subprocess\.\|exec\|eval\|import.*requests" "$REPO_DIR/setup.py" 2>/dev/null
226
+
227
+ # Docker: Was wird im Container ausgefuehrt?
228
+ grep -n "RUN\|CMD\|ENTRYPOINT\|EXPOSE\|ENV" "$REPO_DIR/Dockerfile" 2>/dev/null | head -15
229
+
230
+ # GitHub Actions: Workflow-Injection?
231
+ grep -rn "run:\|uses:" "$REPO_DIR/.github/workflows/" 2>/dev/null | head -20
232
+ ```
233
+
234
+ #### Red Flags Matrix
235
+
236
+ | Severity | Signal | Bedeutung |
237
+ |----------|--------|-----------|
238
+ | **KRITISCH** | `eval()` mit User-Input / Netzwerk-Daten | Remote Code Execution moeglich |
239
+ | **KRITISCH** | Obfuscated Code (base64-encoded Scripts) | Versteckter Payload |
240
+ | **KRITISCH** | Outbound HTTP in postinstall | Datenexfiltration bei Installation |
241
+ | **KRITISCH** | Hardcoded IPs/Domains (nicht Docs/Tests) | C2 Server / Exfiltration |
242
+ | **HOCH** | Uebermässige Permissions (root, sudo, alle Env-Vars) | Privilege Escalation |
243
+ | **HOCH** | Liest ~/.ssh, ~/.aws, ~/.config, Keychain | Credential Theft |
244
+ | **HOCH** | Schreibt in /etc, /usr, ~/.bashrc, ~/.zshrc | Persistence / Manipulation |
245
+ | **MITTEL** | Viele Dependencies mit wenig Stars | Supply Chain Risk |
246
+ | **MITTEL** | Minified Source ohne Build-Pipeline | Schwer zu auditieren |
247
+ | **NIEDRIG** | Kein SECURITY.md / keine CVE Policy | Unreifes Projekt |
248
+
249
+ #### Empfehlung formulieren
250
+
251
+ Nach dem Security-Check IMMER eine klare Empfehlung:
252
+
253
+ - **SAFE** — Code sauber, bekannte Maintainer, transparente Dependencies
254
+ - **CAUTION** — Einige Findings, aber erklaerbar (z.B. eval in Template-Engine). Nur in Sandbox nutzen.
255
+ - **AVOID** — Verdaechtige Patterns, nicht vertrauenswuerdig. Nicht installieren.
256
+ - **MALWARE** — Eindeutig schaedlicher Code. Nicht anfassen. Ggf. GitHub Report.
257
+
258
+ ### SaaS/Closed-Source Tools
259
+ - **Pricing transparent?** Oder Bait-and-Switch?
260
+ - **Datenschutz:** Wo werden Daten gespeichert? DSGVO?
261
+ - **Alternativen:** Gibt es Open-Source-Alternativen?
262
+ - **Track Record:** Wie lange existiert das Unternehmen?
263
+ - **Permissions:** Was will die App/Extension fuer Rechte? Proportional zum Nutzen?
264
+
265
+ ## Phase 6: Nutzwert-Bewertung
266
+
267
+ ### Fuer Ali/Alev-B bewerten
268
+
269
+ | Dimension | Fragen |
270
+ |-----------|--------|
271
+ | **Relevanz** | Passt es zu IT-Delivery, Consulting, SaaS, DevOps, AI? |
272
+ | **Einsatz** | Koennen wir es direkt nutzen? In einem Projekt? Als Content-Inspiration? |
273
+ | **ROI** | Lohnt sich der Zeitaufwand? Kostenlos vs. Paid? |
274
+ | **Qualitaet** | Ist der Content gut gemacht? Substanz oder Hype? |
275
+ | **Sharing** | Lohnt es sich, den Content weiterzuteilen oder darauf zu reagieren? |
276
+
277
+ ### Bewertungs-Rating
278
+
279
+ - **S-Tier:** Sofort einsetzen / Must-have Tool
280
+ - **A-Tier:** Sehr nuetzlich, bei Gelegenheit einbauen
281
+ - **B-Tier:** Interessant, merken fuer spaeter
282
+ - **C-Tier:** Nett zu wissen, kein Handlungsbedarf
283
+ - **F-Tier:** Muell / Scam / Zeitverschwendung
284
+
285
+ ## Phase 7: Report
286
+
287
+ Dem User IMMER einen strukturierten Report liefern:
288
+
289
+ ```
290
+ ## [Platform-Emoji] [Titel/Thema]
291
+
292
+ **Creator:** @username (X Follower, Y Posts)
293
+ **Typ:** Video/Reel/Carousel (Xs / N Bilder)
294
+ **Datum:** TT.MM.JJJJ
295
+
296
+ ### Inhalt
297
+ [Zusammenfassung in 3-5 Saetzen]
298
+
299
+ ### Transkript (Kurzfassung)
300
+ [Wichtigste Aussagen, bei Video]
301
+
302
+ ### Faktencheck [Emoji]
303
+ - Behauptung 1: [Status + Quelle]
304
+ - Behauptung 2: [Status + Quelle]
305
+
306
+ ### Tech-Check (falls zutreffend)
307
+ - Repo: [Link] | Stars | Lizenz | Letzter Commit
308
+ - Safety: [OK/Warnung/Kritisch]
309
+ - Alternativen: [Falls vorhanden]
310
+
311
+ ### Nutzwert [Rating]
312
+ [1-2 Saetze warum nuetzlich/nicht]
313
+
314
+ ### Empfehlung
315
+ [Konkreter Vorschlag: nutzen/merken/ignorieren]
316
+ ```
317
+
318
+ ## Phase 8: Download-Frage
319
+
320
+ **IMMER am Ende fragen:**
321
+
322
+ > Soll ich die Assets (Video/Bilder) nach `~/Desktop/SocialMedia-Fetch/[ordner-name]/` downloaden?
323
+
324
+ Erst bei Bestaetigung:
325
+
326
+ ```bash
327
+ # Ordner anlegen
328
+ FOLDER=~/Desktop/SocialMedia-Fetch/<kurzer-name>
329
+ mkdir -p "$FOLDER"
330
+
331
+ # Video (beste Qualitaet)
332
+ yt-dlp -o "$FOLDER/video.%(ext)s" "<URL>"
333
+
334
+ # Thumbnail
335
+ yt-dlp --write-thumbnail --skip-download -o "$FOLDER/thumb" "<URL>"
336
+
337
+ # Beschreibung + Metadaten
338
+ yt-dlp --dump-json --no-download "<URL>" | python3 -c "
339
+ import json, sys
340
+ d = json.load(sys.stdin)
341
+ with open('$FOLDER/info.md', 'w') as f:
342
+ f.write(f'# {d.get(\"title\", \"?\")}\n\n')
343
+ f.write(f'**URL:** {d.get(\"webpage_url\", \"?\")}\n')
344
+ f.write(f'**Creator:** {d.get(\"uploader\", \"?\")}\n')
345
+ f.write(f'**Datum:** {d.get(\"upload_date\", \"?\")}\n')
346
+ f.write(f'**Views:** {d.get(\"view_count\", \"?\")}\n\n')
347
+ f.write(f'## Beschreibung\n\n{d.get(\"description\", \"\")}\n')
348
+ "
349
+
350
+ # Transkript speichern (falls vorhanden)
351
+ cp /tmp/social-transcript.txt "$FOLDER/transcript.txt" 2>/dev/null
352
+
353
+ # Faktencheck-Report
354
+ # (wird vom Agent aus Phase 7 Report generiert und als report.md gespeichert)
355
+ ```
356
+
357
+ ### Ordner-Benennung
358
+
359
+ Format: `YYYY-MM-DD_platform_kurzname`
360
+
361
+ Beispiele:
362
+ - `2026-04-13_youtube_cursor-ai-review`
363
+ - `2026-04-13_instagram_devops-metrics-carousel`
364
+ - `2026-04-13_tiktok_claude-code-hack`
365
+
366
+ Max 50 Zeichen, lowercase, Bindestriche, keine Sonderzeichen.
367
+
368
+ ## Eskalation bei Problemen
369
+
370
+ | Problem | Loesung |
371
+ |---------|---------|
372
+ | yt-dlp 403/Login required | Tier 2 CDP Cookies exportieren |
373
+ | Instagram private Post | `instaloader --login=<user>` oder CDP |
374
+ | TikTok Geo-Block | VPN-Hinweis an User |
375
+ | Video >25MB fuer Whisper | ffmpeg Kompression auf 64kbps |
376
+ | Kein Audio (Slideshow) | Nur Bildanalyse, Captions lesen |
377
+ | Rate Limited | Pause + Retry mit Backoff |
378
+
379
+ ## Erweiterungen (nach Ermessen)
380
+
381
+ - **Hashtag-Analyse:** Welche Hashtags? Trending? Nische?
382
+ - **Engagement-Metriken:** Like/View Ratio als Qualitaetssignal
383
+ - **Creator-Profil:** Schneller Check wer der Creator ist (Expertise, Follower, Posting-Frequenz)
384
+ - **Vergleichbare Posts:** Gibt es bessere/ausfuehrlichere Quellen zum gleichen Thema?
385
+ - **Content-Inspiration:** Falls relevant fuer Alev-B Social — als Inspiration vormerken?
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: webcheck
3
+ description: Use when the user wants a security/SEO audit of a website, says "webcheck", "check die seite", "security audit", "site audit", "pruef mal", or provides a domain/URL to analyze. Runs DNS, SSL, headers, performance, tech stack, data leaks, and SEO checks via CLI tools.
4
+ user-invocable: true
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Grep
10
+ - Agent
11
+ - WebSearch
12
+ - WebFetch
13
+ ---
14
+
15
+ # WebCheck — Website Security & SEO Audit
16
+
17
+ Fuehrt einen umfassenden WebCheck-Style Audit durch — komplett via CLI, kein externer Service noetig.
18
+
19
+ ## Trigger
20
+
21
+ - "webcheck fuer X", "check mal X", "security audit X", "wie steht X da"
22
+ - Jede Domain/URL die der User zur Analyse gibt
23
+
24
+ ## Audit-Checks (alle via Bash)
25
+
26
+ ### 1. DNS Records
27
+ ```bash
28
+ DOMAIN="example.com"
29
+ dig +short $DOMAIN A && dig +short $DOMAIN AAAA && dig +short $DOMAIN MX
30
+ dig +short $DOMAIN NS && dig +short $DOMAIN TXT && dig +short $DOMAIN CAA
31
+ dig +short www.$DOMAIN CNAME
32
+ ```
33
+
34
+ ### 2. SSL/TLS
35
+ ```bash
36
+ echo | openssl s_client -connect $DOMAIN:443 -servername $DOMAIN 2>/dev/null | \
37
+ openssl x509 -noout -subject -issuer -dates -ext subjectAltName
38
+ ```
39
+
40
+ ### 3. HTTP Headers + Security Headers (7-Check)
41
+ ```bash
42
+ curl -sI https://$DOMAIN | grep -iE "strict-transport|content-security|x-frame|x-content-type|x-xss|referrer-policy|permissions-policy|x-powered-by|server:"
43
+ ```
44
+
45
+ Pruefen: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy, HSTS, Permissions-Policy, CSP
46
+
47
+ ### 4. Performance
48
+ ```bash
49
+ curl -s -o /dev/null -w "TTFB: %{time_starttransfer}s | Total: %{time_total}s | Size: %{size_download}B | HTTP: %{http_code}" https://$DOMAIN
50
+ ```
51
+
52
+ ### 5. IP + Geolocation
53
+ ```bash
54
+ IP=$(dig +short $DOMAIN A | head -1)
55
+ curl -s "https://ipapi.co/$IP/json/" | python3 -c "import json,sys; d=json.load(sys.stdin); print(f'{d.get(\"city\")}, {d.get(\"country_name\")} | {d.get(\"org\")}')"
56
+ ```
57
+
58
+ ### 6. robots.txt + Sitemap
59
+ ```bash
60
+ curl -s https://$DOMAIN/robots.txt | head -20
61
+ curl -s https://$DOMAIN/sitemap.xml | head -20
62
+ ```
63
+
64
+ ### 7. Tech Stack (HTML Source Analysis)
65
+ ```bash
66
+ curl -s https://$DOMAIN | python3 -c "
67
+ import sys; html = sys.stdin.read().lower()
68
+ techs = {'React':'react' in html, 'Next.js':'__next' in html or '_next' in html,
69
+ 'Vite':'vite' in html, 'Tailwind':'tailwind' in html,
70
+ 'Stripe':'stripe' in html, 'WordPress':'wp-content' in html,
71
+ 'Umami':'umami' in html or 'analytics.alev' in html,
72
+ 'GA4':'gtag' in html or 'googletagmanager' in html}
73
+ for k,v in techs.items():
74
+ if v: print(f' ✅ {k}')
75
+ "
76
+ ```
77
+
78
+ ### 8. Domain WHOIS
79
+ ```bash
80
+ whois $DOMAIN | grep -iE "registrar|creation|expiry|updated|status" | head -10
81
+ ```
82
+
83
+ ### 9. Redirect Chain
84
+ ```bash
85
+ curl -sIL https://www.$DOMAIN | grep -E "^HTTP|^location|^Location"
86
+ ```
87
+
88
+ ### 10. Data Leaks + Security
89
+ ```bash
90
+ # Secrets in HTML
91
+ curl -s https://$DOMAIN | grep -oiE "(api[_-]?key|secret|token|password)[[:space:]]*[:=][[:space:]]*['\"][^'\"]{8,}" | head -5
92
+ # Mixed Content
93
+ curl -s https://$DOMAIN | grep -c "http://"
94
+ # SRI
95
+ curl -s https://$DOMAIN | grep -c "integrity="
96
+ # Cookies
97
+ curl -sI https://$DOMAIN | grep -i "set-cookie"
98
+ ```
99
+
100
+ ## Report Format
101
+
102
+ ```
103
+ ## 🔍 $DOMAIN — WebCheck Report
104
+
105
+ ### Server & Netzwerk
106
+ | Check | Ergebnis | Status |
107
+ [IP, Server, HTTP/2, TTFB, Size, Redirects]
108
+
109
+ ### SSL/TLS
110
+ [Issuer, Valid until, SAN, HSTS, Mixed Content]
111
+
112
+ ### Security Headers — X/7
113
+ [Table mit allen 7 Headers]
114
+
115
+ ### DNS
116
+ [Alle Records + CAA/DNSSEC Status]
117
+
118
+ ### Tech Stack
119
+ [Erkannte Technologien]
120
+
121
+ ### SEO & Crawlability
122
+ [robots.txt, sitemap, meta tags, schema, leaks, SRI]
123
+
124
+ ### Domain
125
+ [Registrar, created, expires, auto-renewal]
126
+
127
+ ### Score: XX/100
128
+ [Zusammenfassung + Quick Wins]
129
+ ```
130
+
131
+ ## Scoring
132
+
133
+ | Bereich | Max Punkte |
134
+ |---------|-----------|
135
+ | Security Headers (7/7) | 25 |
136
+ | SSL/TLS + HSTS | 15 |
137
+ | DNS (CAA, SPF, DKIM, DMARC) | 15 |
138
+ | Performance (TTFB <200ms) | 10 |
139
+ | SEO (robots, sitemap, schema, meta) | 15 |
140
+ | No Data Leaks | 10 |
141
+ | Tech/Config (HTTP/2, redirects) | 10 |
142
+
143
+ ## Quick Fixes
144
+
145
+ Nach dem Audit immer konkrete Empfehlungen mit Prioritaet:
146
+ - 🔴 HOCH — Security-relevant, sofort fixen
147
+ - 🟡 MITTEL — SEO/Best-Practice, bei Gelegenheit
148
+ - 🟢 NIEDRIG — Nice-to-have
149
+
150
+ Falls Hostinger hPanel noetig (CAA, DKIM, DMARC): CDP Chrome nutzen falls Session aktiv, sonst User fragen.
@@ -0,0 +1,98 @@
1
+ /**
2
+ * v4.12.2 — ALLOWED_USERS startup hard-fail gate.
3
+ *
4
+ * When the Telegram bot token is configured but ALLOWED_USERS is empty,
5
+ * starting the bot would leave it open to any Telegram user sending a DM.
6
+ * Previously this only emitted a console.warn and the bot started anyway.
7
+ *
8
+ * v4.12.2 introduces a pure gate function that decides whether to refuse
9
+ * startup, with two explicit escape hatches:
10
+ * 1. AUTH_MODE=open — user explicitly wants an open bot
11
+ * 2. ALVIN_INSECURE_ACKNOWLEDGED=1 — explicit opt-out for test/scripted envs
12
+ *
13
+ * This test file exercises the pure gate. The actual wiring in src/index.ts
14
+ * is a thin if-block that calls process.exit(1) on deny.
15
+ */
16
+ import { describe, it, expect } from "vitest";
17
+ import { checkAllowedUsersGate } from "../src/services/allowed-users-gate.js";
18
+
19
+ describe("allowed-users-gate (v4.12.2)", () => {
20
+ it("allows startup when ALLOWED_USERS is populated", () => {
21
+ const result = checkAllowedUsersGate({
22
+ hasTelegram: true,
23
+ allowedUsersCount: 1,
24
+ authMode: "allowlist",
25
+ insecureAcknowledged: false,
26
+ });
27
+ expect(result.allowed).toBe(true);
28
+ expect(result.reason).toBeUndefined();
29
+ });
30
+
31
+ it("BLOCKS startup when telegram enabled but allowedUsers empty (allowlist mode)", () => {
32
+ const result = checkAllowedUsersGate({
33
+ hasTelegram: true,
34
+ allowedUsersCount: 0,
35
+ authMode: "allowlist",
36
+ insecureAcknowledged: false,
37
+ });
38
+ expect(result.allowed).toBe(false);
39
+ expect(result.reason).toContain("ALLOWED_USERS");
40
+ });
41
+
42
+ it("BLOCKS startup when telegram enabled but allowedUsers empty (pairing mode)", () => {
43
+ // Pairing mode needs allowedUsers[0] as the admin for approval routing.
44
+ // Empty array breaks the whole pairing flow.
45
+ const result = checkAllowedUsersGate({
46
+ hasTelegram: true,
47
+ allowedUsersCount: 0,
48
+ authMode: "pairing",
49
+ insecureAcknowledged: false,
50
+ });
51
+ expect(result.allowed).toBe(false);
52
+ });
53
+
54
+ it("ALLOWS startup when AUTH_MODE=open explicitly", () => {
55
+ const result = checkAllowedUsersGate({
56
+ hasTelegram: true,
57
+ allowedUsersCount: 0,
58
+ authMode: "open",
59
+ insecureAcknowledged: false,
60
+ });
61
+ expect(result.allowed).toBe(true);
62
+ expect(result.warning).toContain("open");
63
+ });
64
+
65
+ it("ALLOWS startup when ALVIN_INSECURE_ACKNOWLEDGED=1", () => {
66
+ const result = checkAllowedUsersGate({
67
+ hasTelegram: true,
68
+ allowedUsersCount: 0,
69
+ authMode: "allowlist",
70
+ insecureAcknowledged: true,
71
+ });
72
+ expect(result.allowed).toBe(true);
73
+ expect(result.warning).toContain("INSECURE");
74
+ });
75
+
76
+ it("ALLOWS startup when telegram is NOT enabled (bot is WebUI-only)", () => {
77
+ // WebUI-only deployments don't have a BOT_TOKEN and don't need
78
+ // ALLOWED_USERS — the gate only applies when hasTelegram === true.
79
+ const result = checkAllowedUsersGate({
80
+ hasTelegram: false,
81
+ allowedUsersCount: 0,
82
+ authMode: "allowlist",
83
+ insecureAcknowledged: false,
84
+ });
85
+ expect(result.allowed).toBe(true);
86
+ });
87
+
88
+ it("reason message mentions ~/.alvin-bot/.env and @userinfobot for operator guidance", () => {
89
+ const result = checkAllowedUsersGate({
90
+ hasTelegram: true,
91
+ allowedUsersCount: 0,
92
+ authMode: "allowlist",
93
+ insecureAcknowledged: false,
94
+ });
95
+ expect(result.reason).toMatch(/\.env|alvin-bot/i);
96
+ expect(result.reason).toMatch(/userinfobot|telegram/i);
97
+ });
98
+ });