diff --git a/ka-note/scripts/get-token.ps1 b/ka-note/scripts/get-token.ps1 index da6ce66..691afb5 100644 --- a/ka-note/scripts/get-token.ps1 +++ b/ka-note/scripts/get-token.ps1 @@ -1,56 +1,70 @@ <# .SYNOPSIS - Gets a Bearer token for the Ka-Note production API via MSAL.PS. - Installs MSAL.PS automatically if missing. - Uses cached tokens / refresh tokens — browser login only needed on first run - or after token cache is cleared. + Gets a valid Bearer token for the Ka-Note production API. + + PREFERRED (fully automatic): Add the redirect URI once in Azure Portal: + App registrations → Ka-Note (1aba7af7-...) → Authentication + → Add platform "Mobile and desktop" → URI: https://login.microsoftonline.com/common/oauth2/nativeclient + Then uncomment the MSAL section below. + + CURRENT FALLBACK: reads cached token from %USERPROFILE%\.ka-note\token.txt + Store a fresh token there with: .\set-token.ps1 "eyJ..." .OUTPUTS - Writes the access token string to stdout. - -.EXAMPLE - $token = & "$PSScriptRoot\get-token.ps1" + Writes the access token string to stdout (no trailing newline). #> param() $ErrorActionPreference = 'Stop' -$ClientId = '1aba7af7-eec1-4e49-b87e-9f941c0e8630' -$TenantId = '94cf90d7-e9ff-49a1-bc3b-a5b94d3cc8ca' -$Scopes = "api://$ClientId/access" +$tokenFile = Join-Path $env:USERPROFILE '.ka-note\token.txt' -# --- Ensure MSAL.PS is available --------------------------------------------- -if (-not (Get-Module -ListAvailable -Name 'MSAL.PS')) { - Write-Host " [INFO] Installing MSAL.PS module..." -ForegroundColor DarkGray - Install-Module -Name 'MSAL.PS' -Scope CurrentUser -Force -AllowClobber -} -Import-Module MSAL.PS -ErrorAction Stop +# ── Option A: MSAL.PS (uncomment after adding redirect URI in Azure Portal) ─── +# Requires one-time Azure Portal step: +# App registrations → 1aba7af7-eec1-4e49-b87e-9f941c0e8630 → Authentication +# → Add platform "Mobile and desktop applications" +# → Redirect URI: https://login.microsoftonline.com/common/oauth2/nativeclient +# → Save +# +# if (-not (Get-Module -ListAvailable MSAL.PS)) { +# Install-Module -Name MSAL.PS -Scope CurrentUser -Force -AllowClobber +# } +# Import-Module MSAL.PS +# $p = @{ +# ClientId = '1aba7af7-eec1-4e49-b87e-9f941c0e8630' +# TenantId = '94cf90d7-e9ff-49a1-bc3b-a5b94d3cc8ca' +# Scopes = 'api://1aba7af7-eec1-4e49-b87e-9f941c0e8630/access' +# } +# try { $r = Get-MsalToken @p -Silent 2>$null } +# catch { $r = Get-MsalToken @p -Interactive } +# Write-Output $r.AccessToken +# return -# --- Acquire token ----------------------------------------------------------- -$params = @{ - ClientId = $ClientId - TenantId = $TenantId - Scopes = $Scopes -} - -$result = $null - -# 1. Try silent first (uses cached access token or refresh token) -try { - $result = Get-MsalToken @params -Silent 2>$null -} catch { - # No cached token or refresh failed — fall back to interactive -} - -# 2. Interactive browser login -if (-not $result) { - Write-Host " [AUTH] Opening browser for login..." -ForegroundColor Yellow - $result = Get-MsalToken @params -Interactive -} - -if (-not $result -or -not $result.AccessToken) { - Write-Error "Failed to acquire token." +# ── Option B: cached token file (current default) ──────────────────────────── +if (-not (Test-Path $tokenFile)) { + Write-Error "No cached token found. Run: .\set-token.ps1 `"eyJ...`"" exit 1 } -# Output only the token (callers capture via $token = & .\get-token.ps1) -Write-Output $result.AccessToken +$token = (Get-Content $tokenFile -Raw -Encoding UTF8).Trim() + +# Check JWT expiry (payload is base64url, second segment) +try { + $parts = $token.Split('.') + $payload = $parts[1] + # Pad base64url to multiple of 4 + $pad = 4 - ($payload.Length % 4); if ($pad -ne 4) { $payload += '=' * $pad } + $payload = $payload.Replace('-', '+').Replace('_', '/') + $claims = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($payload)) | ConvertFrom-Json + $expUtc = [System.DateTimeOffset]::FromUnixTimeSeconds($claims.exp).UtcDateTime + $remaining = ($expUtc - [System.DateTime]::UtcNow).TotalMinutes + + if ($remaining -lt 2) { + Write-Warning "Token expired $(if ($remaining -lt 0) { [math]::Round(-$remaining) + ' min ago' } else { 'in < 2 min' }). Run: .\set-token.ps1 `"eyJ...`"" + exit 1 + } + Write-Host " Token valid for $([math]::Round($remaining)) min." -ForegroundColor DarkGray +} catch { + Write-Warning "Could not parse token expiry - using as-is." +} + +Write-Output $token diff --git a/ka-note/scripts/import-jf-landata.ps1 b/ka-note/scripts/import-jf-landata.ps1 new file mode 100644 index 0000000..d6179d2 --- /dev/null +++ b/ka-note/scripts/import-jf-landata.ps1 @@ -0,0 +1,99 @@ +<# +.SYNOPSIS + Imports / re-imports "JF: LANdata" into Ka-Note. Idempotent. + +.EXAMPLE + .\import-jf-landata.ps1 -Prod +#> +param([switch]$Prod, [switch]$Force) +$ErrorActionPreference = 'Stop' + +. "$PSScriptRoot\import-helpers.ps1" + +$scripts = $PSScriptRoot +$RepoRoot = Resolve-Path "$PSScriptRoot\..\.." +$workDir = Join-Path $RepoRoot "work" + +# ── 1. Download ─────────────────────────────────────────────────────────────── +Write-Host "`n[1] Downloading bundle..." -ForegroundColor Cyan +$dlArgs = @('-File', "$scripts\download.ps1", '-Force') +if ($Prod) { $dlArgs += '-Prod' } +& powershell @dlArgs +if ($LASTEXITCODE -ne 0) { throw "Download failed" } + +Initialize-BundleSession -WorkDir $workDir +$ctxPath = "$workDir\contexts.json" +$topsPath = "$workDir\topics.json" +$ctxId = 'jf-landata' + +# ── 2. Context ──────────────────────────────────────────────────────────────── +Write-Host "`n[2] Context..." -ForegroundColor Cyan +Upsert-Context -CtxPath $ctxPath -Id $ctxId -Name 'JF: LANdata' -SortOrder 30 + +# ── 3. Cleanup + Topics ─────────────────────────────────────────────────────── +Write-Host "`n[3] Cleanup + Topics..." -ForegroundColor Cyan +Remove-ContextTopics -TopicsPath $topsPath -ContextId $ctxId + +$journalId = Add-Topic $topsPath $ctxId 'Sitzungsprotokoll' ` + 'Meeting-Notizen chronologisch.' 5 $true + +Add-Topic $topsPath $ctxId 'Access-Manager' ` + "- VM vorbereitet, warten auf Stefan`n- SQL-Server benoetigt`n- Banf kann freigegeben werden`n- Angebot mit AM (nur Drolshagen)`n- Jo triggert Thema an" 10 | Out-Null + +Add-Topic $topsPath $ctxId 'Teams-Probleme HKR / BZ-WLAN' ` + "- LANdata startet Aufzeichnung, Log-Probleme`n- Ball bei Steffen (Kabel neu ziehen, Kabel Telekom-Sophos tauschen)`n- Zaehler resettet, Fehler weniger geworden`n- Steffen: zweiten Rechner mit PfSense Gateway`n- PRTG Leitung HKR ueberwachen`n- Ticket BZ-WLAN: #481057 DNS Verschluesselung" 20 | Out-Null + +Add-Topic $topsPath $ctxId 'PRTG und Sophos / STAS' ` + "- Fromm / Abdul an PRTG-Sophos Protokollierung WAN-Port`n- Jo braucht PRTG-Daten fuer Analyse`n- STAS-Problem: Sophos Heartbeat`n- Sophos Ticket bei Marvin, Citrix-Endpoint-Problem`n- Auth-Service geaendert (geloest)" 30 | Out-Null + +Add-Topic $topsPath $ctxId '5G Router / Netzwerk HKR' ` + "- Problem Standard-Gateway → asynchrone Routen`n- Reverse-Problem: Default-GW ist Switch → Routing-Problem`n- Test Fr./Sa. Abend: max. 2h Internet-Downtime`n- Philip: Test nach Karneval`n- diverse Netzwerkfehler HKR, hohe Verluste am Switch (Zaehler)" 40 | Out-Null + +Add-Topic $topsPath $ctxId 'Citrix / NetScaler / MFA' ` + "- Passwortproblem: Zeichensatz auf NS anders als MPS`n- Stefan: Termin SVA-Citrix + LANdata-MPS`n- MFA fuer Citrix: Gruppen mit IP-Adressen kombinieren (erledigt)`n- Citrix Bleed Sicherheitsluecke`n- Sophos Endpoint auf Citrix Terminalserver (Marvin)" 50 | Out-Null + +Add-Topic $topsPath $ctxId 'Microsoft Lizenzen' ` + "- Open Value Verlaengerung: 60:40 Jahres-/Monatslizenzen`n- E3 ohne Teams (EU-Gesetz): 2 EUR guenstiger, mit Teams 6 EUR teurer`n- Win11 OEM: open key ca. 69 EUR Upgrade`n- KYC fuer Teams Phone Porting (Jo)`n- Lizenzen WITEC: MS Server, Sophos FW, Hornet offboarding automatisch" 60 | Out-Null + +Add-Topic $topsPath $ctxId 'Azure Berechtigungskonzept' ` + "- Matrix: Welche Rollen fuer welche Aufgaben`n- Azubi war Voll-Admin der Azure-Cloud (Ticket #13969)`n- Mitglieder durch Gruppen (Willy liefert noch)`n- Zuordnung Org-Einheiten in Azure`n- Rollenbeschreibungen`n- unzulaessige Azure-Lizenzierung wg. MFA-Pflicht: P1 erforderlich" 70 | Out-Null + +Add-Topic $topsPath $ctxId 'SAN / Backup / File-Server' ` + "- SAN Latenzen (nicht freier Speicher, Willy sucht Support)`n- Diskrepanz: SAN 7 TB frei, VM 2 TB frei`n- Notfallhandbuch SAN erweitern`n- SAP-Ausfall: HA-Cluster hat nicht funktioniert (WAN-Port kein Trigger)`n- File-Server Ausfall: Ticket #257534" 80 | Out-Null + +Add-Topic $topsPath $ctxId 'Firewall / Heartbeat / Luedensch.' ` + "- Heartbeat Authentifizierung (CSOC Thema)`n- Slave als neuen Master neu konfigurieren`n- Luedenscheid: Betriebsmodus RED, Routen passen nicht zur Sophos-Konfig`n- HKR-Regel MS wegen Updates: Natting-Problem? NAT-Regeln fehlen?`n- Backup-FW update PhiLos" 90 | Out-Null + +Add-Topic $topsPath $ctxId 'China / Internationale Vernetzung' ` + "- AFT/staatliche Regulierungen`n- SD-WAN Empfehlung: lokale Anbieter, keinen Europaeischen`n- Artikel 9 Data Security Policy China`n- Logfiles 6 Monate vorhalten`n- MS 365: Popup-Funktion nicht verfuegbar (chinesische Regulierung)`n- FW China: Jo hat noch keine Antwort" 100 | Out-Null + +Add-Topic $topsPath $ctxId 'DNS Verschluesselung' ` + "- DNS Traffic aktuell nicht verschluesselt`n- DNS Protection Sophos verschluesselt auch nicht`n- Ticket #481057`n- nicht kritisch aber auf der Liste" 110 | Out-Null + +# ── 4. History entries ──────────────────────────────────────────────────────── +Write-Host "`n[4] History entries..." -ForegroundColor Cyan + +Add-HistoryEntry $journalId '2026-02-18' "## Next`n`n- Access Manager`n- Sophos Ticket zum Thema STAS: bitte neues Ticket bei Sophos" | Out-Null +Add-HistoryEntry $journalId '2026-02-18' "## 2026-02-18`n`n- 5G Router: erst WLAN-Test`n- diverse Replikationsfehler DC bei RES geloest`n- PRTG und Sophos: Jo macht Wissensuebergabe (Problem geloest)`n- HKR-Regel MS wegen Updates: LANdata im Austausch mit Anbieter, Kuriosite festgestellt, hakt nach`n- Idee Philip/ChrKl: Jo prueft Natting-Problem (NAT-Regeln ev. fehlend)" | Out-Null +Add-HistoryEntry $journalId '2026-02-11' "## 2026-02-11`n`n- Backup und Firewall: Stefan beschreibt Grund fuer neuen ESX-Server`n- Termin Willi + Christopher wg. Domaenen-Anmeldung: Fehler behoben (falsch konfig. DCs), weitere Tests`n- Angebot DL fuer AM: ChrKl banft`n- TISAX: Status Sophos Heartbeat`n- Teams HKR: Zaehler resettet, Fehler weniger, auch mit neuen Kabeln. Steffen: zweiten Rechner mit PfSense. Warten auf Steffen`n- PRTG und Sophos: Jo braucht PRTG-Daten, dann tiefere Analyse`n- HKR-Regel MS: LANdata hakt nach" | Out-Null +Add-HistoryEntry $journalId '2026-02-03' "## 2026-02-03`n`n- Neues Format LANdata: kostenloser IT-Strategie-Termin 2h, Ziel Roadmap`n- Info Server VLAN verteilt`n- PRTG und Sophos: Abdul/Fromm in Arbeit, finale Rueckmeldung ausstehend`n- Teams HKR: Ball bei Steffen (Kabel, PfSense)`n- 5G Router: Standard-Gateway Problem → asynchrone Routen, Philip verschiebt Test nach Karneval" | Out-Null +Add-HistoryEntry $journalId '2026-01-28' "## 2026-01-28`n`n- PRTG und Sophos: Protokollierung WAN-Port, Philip prueft nochmal`n- Citrix NetScaler Passwortproblem: Zeichensatz NS != MPS, Stefan organisiert Termin`n- Austausch NHV KW23: Koordination (wer faehrt, wer schaltet, was wird getestet)`n- Teams HKR: LANdata startet Aufzeichnung" | Out-Null +Add-HistoryEntry $journalId '2026-01-21' "## 2026-01-21`n`n- Windows Hello tut nicht → Eray uebernimmt`n- File-Server Problem: klingt nach DC-Problem`n- China: staatliche Regulierungen, SD-WAN Empfehlung lokale Anbieter, Artikel 9 Data Security Policy, Logfiles 6 Monate, MS 365 einschraenkungen`n- Empfehlung: Vernetzung China aus China beauftragen" | Out-Null +Add-HistoryEntry $journalId '2026-01-14' "## 2026-01-14`n`n- HKR: Jo mit Telekom gesprochen (Leitung nicht stark ausgelastet), hohe Verluste am Switch (Zaehler), Termin Fr. 8:15`n- MacMon Angebot: genauer Plan Switche benoetigt, Philip legt Projekt in Plane an`n- FW HKR-Regel MS: Christian F. auf TODO`n- 5G Router: Problem Standard-Gateway, Test nach Karneval`n- PRTG und Sophos: Fromm in Arbeit`n- Edge-Problem: seit Sa. behoben" | Out-Null +Add-HistoryEntry $journalId '2026-01-07' "## 2026-01-07`n`n- 5G Router: Standard-Gateway Problem (asynchrone Routen), reverse-Problem (Default-GW ist Switch), Sa./Fr. Test, max. 2h Downtime`n- PRTG mit Jo: Fromm bei Sophos dran, Ziel Internetbandbreite HKR ueberwachen`n- Citrix NetScaler: Zeichensatz-Problem, Stefan organisiert Termin`n- FW HKR-Regel MS: Teams bricht ab wenn Regel aktiv" | Out-Null +Add-HistoryEntry $journalId '2025-12-10' "## 2025-12-10`n`n- SAN Probleme: nicht freier Speicher, Latenz unterirdisch, Willy sucht Unterstuetzung" | Out-Null +Add-HistoryEntry $journalId '2025-12-03' "## 2025-12-03`n`n- KYC fuer Teams Phone Porting: Jo klaert`n- Teilen mit Malaysia: LANdata prueft, ob zusaetzliche Richtlinie gebaut werden kann`n- 5G Router: grundsaetzlich funktioniert er" | Out-Null +Add-HistoryEntry $journalId '2025-11-26' "## 2025-11-26`n`n- Status Access-Manager: Jo triggert an`n- BitSight HKR untergliedern?`n- Citrix: Sonderzeichen-Problem in komplexen Passwoertern → NetScaler (nicht Radius)`n- Sophos AP Support kuendigen?`n- HKR sperren Sky: Auffaelligkeiten zusammenstellen, Steffen: XP + lokale Admin-Rechte entziehen" | Out-Null +Add-HistoryEntry $journalId '2025-11-19' "## 2025-11-19`n`n- AM Termin passt`n- Sophos und Citrix: Marvin war krank, Ticket wieder eroeffnet`n- FW China: Jo hat noch keine Antwort`n- Teilen mit Malaysia: LANdata prueft`n- Makros Hornet durch SMTP-Regel durchlassen`n- Jo: Telekom HKR: 100% ausgelastet 6-18 Uhr, Downloads koennen Teams-Problem verursachen, Jo + Philip schauen sich das an" | Out-Null +Add-HistoryEntry $journalId '2025-11-12' "## 2025-11-12`n`n- Entscheidung Lizenz Visio fuer viflow: open vs. e3`n- FW WITEC nach China: internationale Leitung auf China-Seite benoetigt`n- AM: Feedback von Willi benoetigt`n- Bestellung MS Open erledigt`n- SAN: Diskrepanz 7TB / 2TB, hohe Latenzen, Jo meldet sich" | Out-Null +Add-HistoryEntry $journalId '2025-11-05' "## 2025-11-05`n`n- Lizenz AM: Jo schickt Lizenz`n- Sophos auf Citrix: Marvin krank, Ticket bei Sophos aufgemacht, laesst sich nicht installieren" | Out-Null + +# ── 5. Upload ───────────────────────────────────────────────────────────────── +Write-Host "`n[5] Uploading..." -ForegroundColor Cyan +$ulArgs = @('-File', "$scripts\upload.ps1") +if ($Prod) { $ulArgs += '-Prod' } +if ($Force) { $ulArgs += '-Force' } +& powershell @ulArgs +if ($LASTEXITCODE -ne 0) { throw "Upload failed" } + +Write-Host "`n[DONE] JF LANdata import complete." -ForegroundColor Green diff --git a/ka-note/scripts/set-token.ps1 b/ka-note/scripts/set-token.ps1 new file mode 100644 index 0000000..dd6f020 --- /dev/null +++ b/ka-note/scripts/set-token.ps1 @@ -0,0 +1,48 @@ +<# +.SYNOPSIS + Stores a Bearer token for Ka-Note prod in %USERPROFILE%\.ka-note\token.txt. + Run this after copying a fresh token from the Ka-Note browser app. + +.PARAMETER Token + The JWT token string. If omitted, reads from clipboard. + +.EXAMPLE + .\set-token.ps1 "eyJ..." + .\set-token.ps1 # reads from clipboard +#> +param([string]$Token) +$ErrorActionPreference = 'Stop' + +if (-not $Token) { + $Token = Get-Clipboard + if (-not $Token) { Write-Error "No token provided and clipboard is empty."; exit 1 } + Write-Host " Read token from clipboard." -ForegroundColor DarkGray +} + +$Token = $Token.Trim() +if (-not $Token.StartsWith('eyJ')) { + Write-Error "Does not look like a JWT token (expected 'eyJ...')." + exit 1 +} + +# Parse expiry +try { + $parts = $Token.Split('.') + $payload = $parts[1] + $pad = 4 - ($payload.Length % 4); if ($pad -ne 4) { $payload += '=' * $pad } + $payload = $payload.Replace('-', '+').Replace('_', '/') + $claims = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($payload)) | ConvertFrom-Json + $expUtc = [System.DateTimeOffset]::FromUnixTimeSeconds($claims.exp).UtcDateTime + $local = $expUtc.ToLocalTime() + $remaining = [math]::Round(($expUtc - [System.DateTime]::UtcNow).TotalMinutes) + Write-Host " Token expires: $($local.ToString('HH:mm')) ($remaining min remaining)" -ForegroundColor $(if ($remaining -lt 10) { 'Yellow' } else { 'Green' }) +} catch { + Write-Host " Token stored (could not parse expiry)." -ForegroundColor DarkGray +} + +# Save +$dir = Join-Path $env:USERPROFILE '.ka-note' +if (-not (Test-Path $dir)) { New-Item -ItemType Directory $dir | Out-Null } +$file = Join-Path $dir 'token.txt' +$Token | Set-Content $file -Encoding UTF8 -NoNewline +Write-Host " Saved to: $file" -ForegroundColor Green