PrimeBrickPrimeBrick
  • Docs
  • Contact
  • MIT License
  • Documentation
  • MCP Server
  • API Catalog
  • Services
  • Libraries
PrimeBrickPrimeBrick

© 2026 PrimeBrick. MIT License. v3.8.0

github
Backend
Frontend
    OverviewGetting startedUI stackApp shell & sidebarAuthentication & sessionsSystem settingsUI componentsUI patterns
    Components
    API Reference
Microservices
powered by Zudoku
Frontend

Authentication & sessions

Login

src/routes/login/+page.svelte renders <LoginForm> from src/lib/components/auth/LoginForm.svelte. The form uses sveltekit-superforms with a Zod schema (username, password both required) and POSTs to /api/v1/auth/login.

On success it stores the user in userProfileStore and invokes the onsuccess callback, which the login page uses to redirect to the saved redirect URL (or /). On failure it maps RFC7807 error responses to i18n-localized messages, with special handling for rate-limited attempts (showing minutes remaining).

Code
<LoginForm onsuccess={() => { const redirectUrl = getAndClearRedirectUrl(); window.location.href = redirectUrl || '/'; }} />

Session expiration

When an API call returns 401, the request is enqueued in the session-expired store and the SessionExpiredDialog opens so the user can re-authenticate without losing context.

src/lib/auth/session-expired-store.svelte.ts exposes:

MemberPurpose
enqueue(input, init)Enqueues a failed request and opens the dialog; returns a Promise<Response> that resolves after re-login
drainPending()Returns and clears the queued requests (called after successful re-login)
setFailed()Marks the last login attempt as failed (shows the error alert + "Go to login" button)
close()Closes the dialog and resets state

State is exposed read-only via state (isOpen, pendingRequests, hasFailedAttempt). After a successful re-login in the dialog, handleLoginSuccess() calls close() and drainPending(), and the enqueued requests are retried with a _sessionRetry flag to avoid re-triggering the dialog.

Password policy

The backend exposes the active password policy at GET /api/v1/system/password-policy. The usePasswordPolicy() composable fetches it and exposes both the rules and a derived validation regex.

Policies

PolicyRules enforced
alpha_numericLength 8–64, alphanumeric only
letter_and_numberLength, ≥1 letter, ≥1 number
letter_number_specialLength, letter, number, special char
mixed_case_specialLength, lowercase, uppercase, number, special char

Allowed special characters: *-_.#@!|?^:

The regex patterns are kept in sync with the backend exactly:

Code
ALPHA_NUMERIC: /^[A-Za-z0-9]{8,64}$/ LETTER_AND_NUMBER: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9]{8,64}$/ LETTER_NUMBER_SPECIAL:/^(?=.*[A-Za-z])(?=.*\d)(?=.*[*\-_.#@!|?^:])[A-Za-z0-9*\-_.#@!|?^:]{8,64}$/ MIXED_CASE_SPECIAL: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[*\-_.#@!|?^:])[A-Za-z0-9*\-_.#@!|?^:]{8,64}$/

Composable API

Code
const policy = usePasswordPolicy(); policy.state.policy // PasswordPolicy enum policy.state.checklistRules // PasswordChecklistRule[] policy.state.specialChars // string policy.state.loading // boolean policy.state.loaded // boolean policy.regex // RegExp matching the active policy policy.load() // fetch from backend

Password checklist

PasswordChecklist.svelte renders a live checklist of the active rules (length, letter, lowercase, uppercase, number, special) with check/circle icons, updating as the user types. It takes password, rules: PasswordChecklistRule[], and optional specialChars.

Change password dialog

ChangePasswordDialog.svelte (in the entity-list-table dialogs) loads the policy on open, validates the new password against policy.regex, requires confirmation match, and POSTs to /api/v1/entities/user_profiles/{uuid}/change-password. It embeds <PasswordChecklist> for inline feedback.

Password UI components

The src/lib/components/ui/password/ family wraps password input with strength checking via @zxcvbn-ts/core:

  • Password.Root — context provider (usePassword({ hidden, minScore }))
  • Password.Input — the input itself (usePasswordInput({ value, ref }))
  • Password.ToggleVisibility — show/hide toggle
  • Password.Copy — copy-to-clipboard
  • Password.Strength — zxcvbn strength meter
  • PasswordInputField — convenience wrapper combining Root + Input + Toggle

zxcvbn is lazy-loaded and strength checking is debounced with request cancellation. When the score is below minScore, the input's custom validity is set.

Active roles

useActiveRoles() fetches roles from /api/v1/system/roles/active and exposes state.roles (ActiveRole[] with idp_role, label_key, permissions, is_admin) plus a derived roleNames getter for use in forms.

MCP OAuth consent

src/lib/mcp-oauth.ts provides OAuth client helpers for the MCP consent screen at /mcp/consent:

FunctionPurpose
parseConsentParams(searchParams)Parses OAuth params from the URL query string
parseScopes(scopeString)Splits the scope string into { name, description } entries
buildApproveUrl(params, beBaseUrl)Builds the backend authorize URL with consent_approved=true
buildDenyUrl(params)Builds the deny redirect URL per RFC 6749 §4.1.2.1

The consent page checks /api/v1/auth/me; if the user is not logged in it shows <LoginForm> and reloads on success. Otherwise it shows the client name and requested scopes, then redirects to the approve or deny URL.

Form guards

Two composables consolidate logic shared across the settings form pages:

useFormGuard

Derives hasChanges and canSave from a SuperForm instance. Because Superform's auto-subscription does not work inside .svelte.ts files, it takes getter functions for $tainted and $errors plus the form's isTainted function:

Code
const guard = useFormGuard(() => $tainted, () => $errors, (p) => isTainted(p)); $derived(guard.hasChanges); // true when form is tainted $derived(guard.canSave); // hasChanges && no errors

useUnsavedChangesGuard

Registers navigation guards for unsaved changes:

Code
const guard = useUnsavedChangesGuard(() => formGuard.hasChanges, 'settings.unsavedChangesConfirm');
  • handleBeforeUnload — for <svelte:window onbeforeunload>, prevents browser close/refresh
  • handleCancel — for the footer Cancel button; confirms then closes the window or navigates back
  • Internally registers a SvelteKit™ beforeNavigate guard that prompts on in-app navigation

Next steps

  • System settings
  • Entity list table
Last modified on July 26, 2026
App shell & sidebarSystem settings
On this page
  • Login
  • Session expiration
  • Password policy
    • Policies
    • Composable API
    • Password checklist
    • Change password dialog
  • Password UI components
  • Active roles
  • MCP OAuth consent
  • Form guards
    • useFormGuard
    • useUnsavedChangesGuard
  • Next steps
TypeScript
TypeScript
TypeScript
TypeScript