Hook-Referenz: Sicherheit und Identität
In Hooks sprichst du diese sieben Pakete über context an, zum Beispiel zum Token-Erstellen, Passwort-Hashen oder Cookie-Setzen. Die Signaturen stammen aus den // args:-Kommentaren in internal/hook/context_*.go im tibi-server; wo so ein Kommentar fehlt, ist die Signatur aus dem Funktionsrumpf abgeleitet und entsprechend markiert. Jede Funktion zeigt genau einen Fehlerfall mit dem originalen Error-Text aus Code oder Tests (Hook-Fehler enden im Test mit Status 500).
jwt – Tokens erstellen und prüfen
Abschnitt betitelt „jwt – Tokens erstellen und prüfen“Quelle: context_jwt.go, registriert per RegisterPackageFunctions("jwt", ...) mit create und parse. Ohne secret-Option nutzt der Server ein zufälliges Temporär-Secret (jwtTempSecret, context_jwt.go:21).
jwt.create
Abschnitt betitelt „jwt.create“Signatur: jwt.create(claims: object, options?: { validityDuration?: number, secret?: string }): string — aus // args: claims:map[string]interface{}, options:map[string]interface{} (context_jwt.go:27). validityDuration setzt exp auf jetzt plus Sekunden.
;(function () { const token = context.jwt.create({ sub: "user123", role: "admin" }, { validityDuration: 3600 }) throw { status: 200, json: { token: token } }})()Fehlerfall (Error): Ohne Claims brichst du mit missing claims in jwt.create function ab, Status 500 (error - missing claims, context_jwt_test.go:109); Claims als String statt Objekt: claims must be object in jwt.create function (context_jwt.go:42).
jwt.parse
Abschnitt betitelt „jwt.parse“Signatur: jwt.parse(token: string, options?: { secret?: string }): object — aus // args: token:string, options:map[string]interface{} (context_jwt.go:84). Antwortet mit { valid, claims, header, method, error? } und wirft bei ungültigen Tokens keinen Error: falsches Secret oder abgelaufenes Token liefern valid: false plus error-Text bei Status 200.
;(function () { const token = context.jwt.create({ sub: "user123" }, { secret: "s3cr3t" }) const res = context.jwt.parse(token, { secret: "s3cr3t" }) throw { status: 200, json: { valid: res.valid } }})()Fehlerfall (Error): Ohne Token: missing token in jwt.parse function, Status 500 (error - missing token, context_jwt_test.go:120); Token als Nicht-String: token must be string in jwt.parse function (context_jwt.go:96).
user – Aktuellen Login lesen
Abschnitt betitelt „user – Aktuellen Login lesen“Quelle: context_user.go, registriert per RegisterPackageFunctions("user", ...) mit auth. Liefert { id, username, role, permissions } oder null ohne Login.
user.auth
Abschnitt betitelt „user.auth“Signatur (abgeleitet): user.auth(): object | null — kein args:-Kommentar, abgeleitet aus dem Rumpf FuncUserAuth (context_user.go:16): nimmt keine Argumente und liest den API-Kontext.
;(function () { const me = context.user.auth() throw { status: 200, json: { login: me !== null, name: me && me.username } }})()Fehlerfall (Error): Außerhalb von Hooks (ohne API-Kontext) scheitert der Aufruf mit user.auth is only valid in hooks (context_user.go:19); ohne Login bekommst du null zurück, keinen Error (auth not logged in, context_user_test.go:44).
bcrypt – Passwörter hashen und prüfen
Abschnitt betitelt „bcrypt – Passwörter hashen und prüfen“Quelle: context_bcrypt.go, registriert per RegisterPackageFunctions("bcrypt", ...) mit hash und check.
bcrypt.hash
Abschnitt betitelt „bcrypt.hash“Signatur: bcrypt.hash(password: string, options?: { cost?: number }): string — aus // args: password:string, options:map[string]interface{} (context_bcrypt.go:18); Standard-cost ist 14.
;(function () { const hash = context.bcrypt.hash("s3cr3t-pw") throw { status: 200, json: { hash: hash } }})()Fehlerfall (Error): Ohne Passwort: missing password in bcrypt.hash function, Status 500 (error - missing password, context_bcrypt_test.go:91); falscher cost-Typ: invalid type for costs in bcrypt.hash function — so wörtlich im Code, mit Plural-s (context_bcrypt.go:42).
bcrypt.check
Abschnitt betitelt „bcrypt.check“Signatur: bcrypt.check(password: string, hash: string): boolean — aus // args: password:string, hash:string (context_bcrypt.go:56). Ein falsches Passwort liefert false, keinen Error.
;(function () { const hash = context.bcrypt.hash("s3cr3t-pw") const ok = context.bcrypt.check("s3cr3t-pw", hash) throw { status: 200, json: { match: ok } }})()Fehlerfall (Error): Weniger als zwei Argumente: missing password and/or hash in bcrypt.check function, Status 500 (error - missing args in check, context_bcrypt_test.go:102).
crypto – Hashes bilden
Abschnitt betitelt „crypto – Hashes bilden“Quelle: context_crypto.go, registriert per RegisterPackageFunctions("crypto", ...) mit sha256 und md5. Das sind Einweg-Hashes für Prüfsummen, kein Passwort-Hashing — dafür nimmst du das bcrypt-Paket.
crypto.sha256
Abschnitt betitelt „crypto.sha256“Signatur: crypto.sha256(text: string): string — aus // args: string:string (context_crypto.go:19). Liefert Hex, belegt mit "hello" → 2cf24dba…9824 in context_crypto_test.go:22.
;(function () { const sum = context.crypto.sha256("hello") throw { status: 200, json: { sha256: sum } }})()Fehlerfall (Error): Ohne Argument: missing string in crypto.sha256 function, Status 500 (error - sha256 missing argument, context_crypto_test.go:77).
crypto.md5
Abschnitt betitelt „crypto.md5“Signatur: crypto.md5(text: string): string — aus // args: string:string (context_crypto.go:33). Liefert Hex, belegt mit "hello" → 5d41402a…c592 in context_crypto_test.go:44.
;(function () { const sum = context.crypto.md5("hello") throw { status: 200, json: { md5: sum } }})()Fehlerfall (Error): Ohne Argument: missing string in crypto.md5 function, Status 500 (error - md5 missing argument, context_crypto_test.go:88).
cookie – Cookies lesen und setzen
Abschnitt betitelt „cookie – Cookies lesen und setzen“Quelle: context_cookie.go, registriert per RegisterPackageFunctions("cookie", ...) mit get und set. Beide brauchen einen Hook-HTTP-Kontext.
cookie.get
Abschnitt betitelt „cookie.get“Signatur: cookie.get(name: string): string — aus // args: name:string (context_cookie.go:17). Unbekannte Cookies liefern "", keinen Error.
;(function () { const session = context.cookie.get("session") throw { status: 200, json: { hasSession: session !== "" } }})()Fehlerfall (Error): Ohne Namen: missing cookie name in cookie.get, Status 500 (error - missing cookie name, context_cookie_test.go:55); außerhalb von Hooks: cookie functions only valid in hooks (context_cookie.go:20).
cookie.set
Abschnitt betitelt „cookie.set“Signatur: cookie.set(name: string, data: string, options?: object): void — aus // args: name:string options:map[string]interface{} (context_cookie.go:40). options kennt maxAge, path, domain, httpOnly, secure und sameSite (strict, lax oder none).
;(function () { context.cookie.set("session", "abc123", { maxAge: 3600, path: "/", httpOnly: true, sameSite: "lax" }) throw { status: 200, json: { set: true } }})()Fehlerfall (Error): Weniger als zwei Argumente: missing cookie name and/or data in cookie.set, Status 500 (error - missing cookie data, context_cookie_test.go:66); unbekanntes sameSite: invalid value for sameSite in cookie.set function (context_cookie.go:136).
exec – Kommandos ausführen
Abschnitt betitelt „exec – Kommandos ausführen“Quelle: context_exec.go, registriert per RegisterPackageFunctions("exec", ...) mit command. Läuft mit Timeout (Standard 10000 ms) im Projektverzeichnis und unter der Config-UID.
exec.command
Abschnitt betitelt „exec.command“Signatur: exec.command(command: string, options?: { args?: Array, stdin?: string, dir?: string, env?: Array, timeout?: number, returnObject?: boolean, combineOutput?: boolean }): string | object — aus // args: command:string, options:map[string]interface{} (context_exec.go:22). Ohne returnObject kommt stdout als String; mit returnObject: true antwortet { stdout, stderr, exitCode } (bzw. { output, exitCode } mit combineOutput).
;(function () { const out = context.exec.command("echo", { args: ["Hallo Hook"] }) throw { status: 200, json: { result: out } }})()Fehlerfall (Error): Ohne Kommando: missing command in exec.command function (context_exec.go:38); Exit-Code ungleich 0 ohne returnObject: exec.command failed with exit code 1, Status 500 (test exec command error case, context_exec_test.go:65); bei Timeout: exec.command timed out after ... ms (context_exec.go:183).
config – Server- und Projekt-Config lesen
Abschnitt betitelt „config – Server- und Projekt-Config lesen“Quelle: context_config.go, registriert per RegisterPackageFunctions("config", ...) mit namespace, project und server. Alle drei ohne args:-Kommentar — Signaturen aus den Rümpfen abgeleitet (context_config.go:19, :23, :27).
config.namespace
Abschnitt betitelt „config.namespace“Signatur (abgeleitet): config.namespace(): string — liefert den Namespace, nimmt keine Argumente.
;(function () { const ns = context.config.namespace() throw { status: 200, json: { namespace: ns } }})()Fehlerfall: Kein Fehlerfall — namespace liest nur ein Feld und kennt keinen Error-Pfad (dokumentierte Abwesenheit, kein Versäumnis).
config.project
Abschnitt betitelt „config.project“Signatur (abgeleitet): config.project(): object — liefert die Projekt-Config als Map, nimmt keine Argumente.
;(function () { const project = context.config.project() throw { status: 200, json: { name: project.name } }})()Fehlerfall: Kein Fehlerfall — project mappt nur die Config und kennt keinen Error-Pfad (dokumentierte Abwesenheit, kein Versäumnis).
config.server
Abschnitt betitelt „config.server“Signatur (abgeleitet): config.server(): object — liefert die Server-Config als Map, nimmt keine Argumente.
;(function () { const server = context.config.server() throw { status: 200, json: { port: server.api && server.api.port } }})()Fehlerfall (Error): Kein fixer Error-String im Code — nur interne JSON-Marshal-Fehler werden durchgereicht (context_config.go:30); im Test läuft der Aufruf fehlerfrei mit Status 200 (context_config_test.go:19).
Weiter: Hook-Kontexte als Paket-Index, Hooks schreiben für Lifecycle und Starter-Muster.
Verifiziert am 68b4278 2026-10-16 (tibi-server)