Skip to Content

JavaScript SDK (@auris/js)

@auris/js v0.1.0

@auris/js ist das Basis-SDK für Auris. Es ist eine abhängigkeitsfreie Bibliothek, die in Browsern, Node.js 18+ und Edge Runtimes (Cloudflare Workers, Vercel Edge, Deno) funktioniert. Sowohl ESM- (import) als auch CJS- (require) Builds sind enthalten, zusammen mit vollständigen TypeScript-Deklarationen.

Die React- und Next.js-SDKs sind dünne Wrapper um @auris/js. Wenn du eine framework-unabhängige Anwendung entwickelst oder die Low-Level-API benötigst, verwende dieses Paket direkt.


Installation

npm install @auris/js
pnpm add @auris/js
yarn add @auris/js

AurisClient

AurisClient ist der Haupt-Einstiegspunkt. Pro Anwendung eine Instanz erstellen.

Konstruktor

import { AurisClient } from '@auris/js' const auris = new AurisClient({ domain: 'auth.yourdomain.com', // Dein Auris-Tenant-Domain (erforderlich) clientId: 'app_xxxxx', // Anwendungs-Client-ID aus der Console (erforderlich) redirectUri: 'http://localhost:3000/callback', // Muss einer registrierten Callback-URL entsprechen (für PKCE erforderlich) tenant: 'my-tenant', // Tenant-Bezeichner als x-tenant-Header (optional, Standard: 'default') storage: 'localStorage', // Token-Speicher: 'localStorage' | 'sessionStorage' | 'memory' | TokenStore-Instanz autoRefresh: true, // Access-Tokens vor Ablauf automatisch erneuern (Standard: true) scope: 'openid profile email', // Anzufordernde OAuth2-Scopes (Standard: 'openid profile email') })

Konfigurationsoptionen:

OptionTypErforderlichStandardBeschreibung
domainstringJa—Dein Auris-Tenant-Domain, ohne https://
clientIdstringJa—Anwendungs-Client-ID aus der Console
redirectUristringBedingt—Callback-URL für PKCE-Flows. Muss in der Console registriert sein.
tenantstringNein'default'Tenant-Bezeichner als x-tenant-HTTP-Header
storagestring | TokenStoreNein'localStorage'Wo Tokens gespeichert werden
autoRefreshbooleanNeintrueAccess-Tokens automatisch erneuern, bevor sie ablaufen
scopestringNein'openid profile email'Leerzeichen-getrennte OAuth2-Scopes

In Edge Runtimes und Node.js-Umgebungen ohne localStorage fällt das SDK automatisch auf In-Memory-Speicher zurück. storage: 'memory' explizit übergeben, um dieses Verhalten in Browser-Umgebungen zu erzwingen.


Authentifizierungs-Methoden

loginWithRedirect(options?)

Initiiert den OAuth2 Authorization Code Flow mit PKCE. Generiert einen Code Verifier und Challenge, speichert den Verifier und leitet den Browser zur Auris-gehosteten Login-Seite weiter.

Signatur:

loginWithRedirect(options?: LoginWithRedirectOptions): Promise<void>

Parameter:

OptionTypBeschreibung
login_hintstringE-Mail-Feld vorausfüllen
prompt'login' | 'none'login erzwingt Re-Auth. none gibt einen Fehler zurück, wenn keine aktive Sitzung vorhanden ist.
screen_hint'signup'Öffnet den Registrierungsbildschirm statt des Login-Bildschirms
connectionstringErzwingt eine bestimmte SSO-Verbindung
localestringÜberschreibt die Sprache der gehosteten Seite (en, it, de, fr, es)
statestringBenutzerdefinierter State-Wert. Das SDK generiert einen sicheren Zufallswert, wenn dieser fehlt.
// Einfache Login-Weiterleitung await auris.loginWithRedirect() // Registrierungsbildschirm öffnen await auris.loginWithRedirect({ screen_hint: 'signup' }) // E-Mail vorausfüllen und Re-Authentifizierung erzwingen await auris.loginWithRedirect({ login_hint: '[email protected]', prompt: 'login' })

handleRedirectCallback()

Schließt den OAuth2-PKCE-Flow ab, nachdem der Benutzer zur Anwendung zurückgekehrt ist. Liest code und state aus der aktuellen URL, validiert den State, tauscht den Code gegen Tokens und speichert das Ergebnis.

Diese Methode genau einmal auf der Callback-Seite aufrufen, wenn diese zum ersten Mal lädt.

Signatur:

handleRedirectCallback(): Promise<AuthResult>
const result = await auris.handleRedirectCallback() if (result.user) { console.log('Angemeldet als', result.user.email) window.location.href = '/dashboard' }

login(email, password)

Direkte E-Mail/Passwort-Authentifizierung ohne Weiterleitung. Gibt Tokens sofort zurück.

Signatur:

login(email: string, password: string): Promise<AuthResult>

Bei der direkten Anmeldung werden Zugangsdaten an deinen Anwendungsserver gesendet. Es wird nicht für Browser-Anwendungen empfohlen, da die Sicherheitsvorteile der gehosteten Login-Seite (CAPTCHA, Rate Limiting, Suspicious Login Detection, MFA) umgangen werden. loginWithRedirect() für Endbenutzer-Authentifizierung in Browser-Apps verwenden.

const result = await auris.login('[email protected]', 'hunter2') console.log(result.user.id)

signup(email, password, options?)

Registriert einen neuen Benutzer und gibt sofort Tokens zurück.

Signatur:

signup(email: string, password: string, options?: SignupOptions): Promise<AuthResult>

Optionen:

OptionTypBeschreibung
firstNamestringVorname des Benutzers
lastNamestringNachname des Benutzers
usernamestringBenutzername (muss im Tenant eindeutig sein)
metadataRecord<string, unknown>Benutzerdefinierte Metadaten, die am Konto gespeichert werden
const result = await auris.signup('[email protected]', 'securepassword', { firstName: 'Bob', lastName: 'Smith', })

logout(options?)

Widerruft das Refresh-Token, löscht gespeicherte Tokens und leitet optional den Browser weiter.

Signatur:

logout(options?: LogoutOptions): Promise<void>

Optionen:

OptionTypBeschreibung
returnTostringURL, zu der nach dem Abmelden weitergeleitet wird. Muss den gleichen Origin wie deine redirectUri haben.
// Tokens löschen und zur Startseite weiterleiten await auris.logout({ returnTo: 'http://localhost:3000' }) // Tokens löschen ohne Weiterleitung (z.B. in einem Node.js-Kontext) await auris.logout()

getUser()

Gibt den aktuell authentifizierten Benutzer aus dem gespeicherten ID-Token zurück. Gibt null zurück, wenn der Benutzer nicht authentifiziert ist.

Signatur:

getUser(): Promise<UserInfo | null>
const user = await auris.getUser() if (user) { console.log(user.id) // Auris-Benutzer-ID console.log(user.email) console.log(user.roles) // string[] — zugewiesene Rollen console.log(user.metadata) // Record<string, unknown> }

isAuthenticated()

Gibt true zurück, wenn der Benutzer ein gültiges (nicht abgelaufenes) Access-Token hat.

Signatur:

isAuthenticated(): Promise<boolean>
if (await auris.isAuthenticated()) { // Authentifizierte Operationen durchführen }

getAccessToken()

Gibt das aktuelle Access-Token zurück. Wenn autoRefresh aktiviert ist und das Token abgelaufen ist, wird automatisch das Refresh-Token gegen ein neues Access-Token getauscht, bevor es zurückgegeben wird.

Signatur:

getAccessToken(): Promise<string | null>
const token = await auris.getAccessToken() // Token in API-Anfragen verwenden const response = await fetch('/api/data', { headers: { Authorization: `Bearer ${token}` }, })

refreshToken()

Tauscht das gespeicherte Refresh-Token manuell gegen ein neues Access-Token- und Refresh-Token-Paar.

Signatur:

refreshToken(): Promise<AuthResult>
const result = await auris.refreshToken() console.log(result.accessToken)

loginWithMagicLink(email)

Sendet eine Magic-Link-E-Mail an die angegebene Adresse. Der Benutzer klickt auf den Link in der E-Mail, um die Authentifizierung über verifyMagicLink() abzuschließen.

Signatur:

loginWithMagicLink(email: string): Promise<void>
await auris.loginWithMagicLink('[email protected]') // Weiterleiten oder "Überprüfe deine E-Mails"-Nachricht anzeigen

verifyMagicLink(token)

Verifiziert ein Magic-Link-Token (aus der URL extrahiert, auf die der Benutzer geklickt hat). Gibt Tokens und Benutzerinformationen bei Erfolg zurück.

Signatur:

verifyMagicLink(token: string): Promise<AuthResult>
const urlParams = new URLSearchParams(window.location.search) const token = urlParams.get('token') if (token) { const result = await auris.verifyMagicLink(token) console.log('Authentifiziert:', result.user) }

forgotPassword(email)

Sendet eine Passwortzurücksetzungs-E-Mail an die angegebene Adresse.

Signatur:

forgotPassword(email: string): Promise<void>
await auris.forgotPassword('[email protected]')

loginWithSocial(provider)

Leitet den Benutzer zum angegebenen sozialen Identity Provider weiter. Auris verwaltet den Provider-OAuth-Flow und gibt den Benutzer mit einem Authorization Code zu deiner redirectUri zurück.

Signatur:

loginWithSocial(provider: SocialProvider): Promise<void>

Unterstützte Provider:

type SocialProvider = | 'google' | 'github' | 'microsoft' | 'apple' | 'facebook' | 'discord' | 'linkedin' | 'twitter' | 'slack'
await auris.loginWithSocial('google') await auris.loginWithSocial('github')

getM2MToken(clientSecret, scopes?)

Erhält ein Machine-to-Machine-Access-Token mit dem OAuth2-Grant client_credentials. Für Server-zu-Server-API-Aufrufe ohne Benutzerbeteiligung verwenden.

Signatur:

getM2MToken(clientSecret: string, scopes?: string[]): Promise<M2MTokenResult>
const result = await auris.getM2MToken('cs_live_xxxxx', ['read:users', 'manage:roles']) console.log(result.accessToken) console.log(result.expiresIn) // Sekunden bis zum Ablauf

getM2MToken() niemals in Browser-Code verwenden. Das clientSecret muss ausschließlich serverseitig verbleiben.


onAuthStateChange(callback)

Abonniert Änderungen des Authentifizierungsstatus. Der Callback wird ausgelöst, wenn sich der Benutzer anmeldet, abmeldet oder sein Token erneuert wird.

Signatur:

onAuthStateChange(callback: (user: UserInfo | null) => void): Unsubscribe

Gibt zurück: Unsubscribe — aufrufen, um den Listener zu entfernen.

const unsubscribe = auris.onAuthStateChange((user) => { if (user) { console.log('Angemeldet:', user.email) } else { console.log('Abgemeldet') } }) // Wenn der Listener nicht mehr benötigt wird: unsubscribe()

Berechtigungs-Modul

Zugriff über auris.permissions. Alle Methoden rufen die Auris-API auf und erfordern eine Benutzerauthentifizierung.

check(permissions)

Überprüft, ob der aktuelle Benutzer eine oder alle angegebenen Berechtigungen hat.

Signatur:

check(permissions: string[]): Promise<PermissionCheckResult>
const result = await auris.permissions.check(['manage:users', 'view:reports']) if (result.has('manage:users')) { // Admin-UI anzeigen } if (result.hasAll) { // Benutzer hat beide Berechtigungen }

checkOne(permission)

Überprüft eine einzelne Berechtigung. Gibt true zurück, wenn erlaubt, sonst false.

Signatur:

checkOne(permission: string): Promise<boolean>
const canDelete = await auris.permissions.checkOne('delete:documents') if (canDelete) { showDeleteButton() }

listUserPermissions()

Gibt die vollständige Liste der Berechtigungsstrings zurück, die dem aktuellen Benutzer über alle seine Rollen zugewiesen sind.

Signatur:

listUserPermissions(): Promise<string[]>
const permissions = await auris.permissions.listUserPermissions() console.log(permissions) // ['view:documents', 'create:documents', 'manage:users', ...]

FGA-Modul

Zugriff über auris.fga. Implementiert Zanzibar-style Fine-Grained Authorization. Erfordert, dass das FGA-Feature auf deinem Tenant aktiviert ist.

check(input)

Überprüft, ob ein Subjekt eine Beziehung zu einem Objekt hat.

Signatur:

check(input: FgaCheckInput): Promise<FgaCheckResult>
const result = await auris.fga.check({ objectType: 'document', objectId: 'doc_abc123', relation: 'editor', subjectType: 'user', subjectId: user.id, }) if (result.allowed) { enableEditMode() }

expand(input)

Erweitert eine Beziehung, um alle Subjekte (Benutzer oder Gruppen) aufzulisten, die sie für ein bestimmtes Objekt haben.

const tree = await auris.fga.expand({ objectType: 'project', objectId: 'proj_xyz', relation: 'member', })

listObjects(input)

Listet alle Objekt-IDs eines bestimmten Typs auf, für die das Subjekt die angegebene Beziehung hat.

// Alle Dokumente auflisten, die der aktuelle Benutzer anzeigen kann const documentIds = await auris.fga.listObjects({ objectType: 'document', relation: 'viewer', subjectType: 'user', subjectId: user.id, })

writeTuples(tuples)

Schreibt ein oder mehrere Beziehungs-Tuples in den FGA-Store.

await auris.fga.writeTuples([ { objectType: 'document', objectId: 'doc_abc123', relation: 'editor', subjectType: 'user', subjectId: 'usr_456', }, ])

deleteTuples(tuples)

Löscht ein oder mehrere Beziehungs-Tuples aus dem FGA-Store.

await auris.fga.deleteTuples([ { objectType: 'document', objectId: 'doc_abc123', relation: 'editor', subjectType: 'user', subjectId: 'usr_456', }, ])

Management Client

createManagementClient(config) erstellt einen Management-API-Client, der sich mit M2M-client_credentials authentifiziert. In Backend-Code (Node.js-Skripte, API-Routen, CLI-Tools) verwenden, um den Tenant programmatisch zu verwalten.

Signatur:

import { createManagementClient } from '@auris/js' const mgmt = await createManagementClient({ domain: 'auth.yourdomain.com', clientId: 'app_xxxxx', clientSecret: 'cs_live_xxxxx', tenant: 'my-tenant', })

Benutzer

// Benutzer mit Paginierung auflisten const { users, total } = await mgmt.users.list({ page: 1, limit: 50 }) // Einzelnen Benutzer nach ID abrufen const user = await mgmt.users.get('usr_abc123') // Benutzer erstellen const newUser = await mgmt.users.create({ email: '[email protected]', password: 'temporary-password', firstName: 'Alice', roles: ['editor'], }) // Benutzer aktualisieren await mgmt.users.update('usr_abc123', { firstName: 'Alicia' }) // Benutzer deaktivieren await mgmt.users.update('usr_abc123', { enabled: false }) // Benutzer löschen await mgmt.users.delete('usr_abc123')

Organisationen

const orgs = await mgmt.organizations.list() const org = await mgmt.organizations.get('org_xyz') const newOrg = await mgmt.organizations.create({ name: 'Acme GmbH', slug: 'acme' }) await mgmt.organizations.update('org_xyz', { name: 'Acme Corporation' }) await mgmt.organizations.delete('org_xyz')

Rollen

const roles = await mgmt.roles.list() const role = await mgmt.roles.get('role_abc') const newRole = await mgmt.roles.create({ name: 'Editor', description: 'Kann Inhalte bearbeiten' }) await mgmt.roles.update('role_abc', { description: 'Kann Inhalte anzeigen und bearbeiten' }) await mgmt.roles.delete('role_abc')

Webhook-Verifizierung

verifyWebhookSignature(options) verifiziert, dass ein eingehender Webhook von Auris gesendet wurde und nicht manipuliert wurde. Verwendet HMAC-SHA256.

import express from 'express' import { verifyWebhookSignature } from '@auris/js' const app = express() app.post('/webhooks/auris', express.raw({ type: 'application/json' }), async (req, res) => { const isValid = await verifyWebhookSignature({ payload: req.body.toString('utf-8'), signature: req.headers['x-webhook-signature'], secret: process.env.AURIS_WEBHOOK_SECRET, timestamp: req.headers['x-webhook-timestamp'], }) if (!isValid) { return res.status(401).json({ error: 'Ungültige Signatur' }) } const event = JSON.parse(req.body) console.log('Event empfangen:', event.type) res.json({ received: true }) })

JWT-Verifizierung

verifyJwt(token, jwksUrl) verifiziert ein von Auris ausgestelltes Access-Token anhand der öffentlichen Schlüssel von deinem JWKS-Endpunkt. Abhängigkeitsfrei — verwendet die Web Crypto API in Browsern und Node.js 18+.

import { verifyJwt } from '@auris/js' try { const payload = await verifyJwt( accessToken, `https://${process.env.AURIS_DOMAIN}/.well-known/jwks.json` ) console.log('Benutzer-ID:', payload.sub) console.log('Rollen:', payload.roles) } catch (err) { console.error('Token ungültig:', err.message) }

TypeScript-Typen

Wichtige aus @auris/js exportierte Typen:

interface AuthResult { user: UserInfo accessToken: string refreshToken?: string expiresIn: number tokenType: 'Bearer' } interface UserInfo { id: string sub: string email: string emailVerified: boolean name: string firstName: string lastName: string username: string picture?: string roles: string[] metadata: Record<string, unknown> tenant: string createdAt: string } interface TokenStore { get(key: string): string | null | Promise<string | null> set(key: string, value: string): void | Promise<void> remove(key: string): void | Promise<void> } type Unsubscribe = () => void

Benutzerdefinierter Speicher-Adapter

Das TokenStore-Interface implementieren, um Tokens in beliebigen Speicher-Backends zu speichern.

import { AurisClient, TokenStore } from '@auris/js' class RedisTokenStore implements TokenStore { constructor(private redis: RedisClient, private prefix = 'auris:') {} async get(key: string) { return this.redis.get(this.prefix + key) } async set(key: string, value: string) { await this.redis.set(this.prefix + key, value, { EX: 60 * 60 * 24 }) } async remove(key: string) { await this.redis.del(this.prefix + key) } } const auris = new AurisClient({ domain: 'auth.yourdomain.com', clientId: 'app_xxxxx', storage: new RedisTokenStore(redisClient), })

Fehlerbehandlung

Alle Async-Methoden werfen bei einem Fehler einen AurisError.

import { AurisClient, AurisError } from '@auris/js' try { await auris.login('[email protected]', 'wrongpassword') } catch (err) { if (err instanceof AurisError) { console.error(err.code) // z.B. 'invalid_credentials', 'account_locked', 'mfa_required' console.error(err.message) // Lesbare Fehlermeldung console.error(err.status) // HTTP-Statuscode (z.B. 401, 403, 429) } }

Häufige Fehlercodes:

CodeStatusBeschreibung
invalid_credentials401Falsches E-Mail oder Passwort
account_locked403Konto nach Fehlversuchen temporär gesperrt
mfa_required403MFA-Challenge erforderlich — stattdessen gehosteten Login verwenden
invalid_token401Token ist abgelaufen oder ungültig
permission_denied403Benutzer hat nicht die erforderliche Berechtigung
rate_limited429Zu viele Anfragen — Retry-After-Header beachten
not_found404Ressource existiert nicht
validation_error422Request-Body hat Validierung nicht bestanden

Verwandte Seiten