Skip to content

Mindful Auth - Astro configuration

The following routes are publicly accessible without authentication:

  • / - Root (redirects to login page)
  • /login - Password login
  • /register - Password registration
  • /magic-login - Magic link login
  • /magic-register - Magic link registration
  • /forgot-password - Password reset request
  • /resend-verification - Resend email verification
  • /reset-password/* - Password reset with token
  • /verify-email/* - Email verification with token
  • /email-verified/* - Email verified confirmation
  • /verify-magic-link/* - Magic link verification
  • /auth/* - All API proxy endpoints to Mindful Auth (login, register, 2FA, etc.)
  • /favicon.ico
  • /robots.txt
  • /.well-known/security.txt

All protected routes require a valid session and must include the memberid in the URL path:

  • /{memberid}/ - User profile and security settings
  • /{memberid}/dashboard - User dashboard
  • /{memberid}/* - Any dynamic protected pages

Every page and component in protected routes has access to Astro.locals which contains the authenticated user’s data:

---
// In any .astro component, page, or layout
const { recordId } = Astro.locals;
---
<div>
<p>User ID: {recordId}</p>
</div>

Available in Astro.locals:

  • recordId: string | null - The authenticated user’s unique ID

Important: Astro.locals is automatically populated by the middleware for all protected routes. You don’t need to pass props or import anything — just use Astro.locals.recordId directly in any component.

To extend Astro.locals: Add custom properties to the Locals interface in src/env.d.ts:

import type { MindfulAuthLocals } from '@mindfulauth/astro';
declare namespace App {
interface Locals extends MindfulAuthLocals {
// ADD YOUR CUSTOM LOCALS HERE
customUserId?: string;
customData?: Record<string, unknown>;
}
}

The base types (recordId, runtime) are provided by @mindfulauth/astro and don’t need to be manually defined.

All protected routes enforce memberid validation in the URL path:

/{memberid}/
/{memberid}/dashboard
/{memberid}/*

Routes under /{memberid}/ require the memberid in the URL to match the authenticated user’s session. Users cannot access another user’s pages by changing the memberid in the URL.

Security Benefits:

  • ✅ Memberid validated at middleware level (early rejection before page render)
  • ✅ URL structure makes it obvious which user’s data is being accessed
  • Prevents accidental access - users can’t type /wrong-memberid/dashboard and get their own data
  • Better for multi-tenant scenarios - clear resource ownership in the URL
  • Audit-friendly - logs clearly show which memberid was accessed

Implementation:

  • The src/pages/[memberid]/ folder structure handles dynamic memberid routing
  • Middleware validates memberid at every request
  • Users cannot access other users’ pages by changing the URL
  • src/pages/login.astro
  • src/pages/register.astro
  • src/pages/magic-login.astro
  • src/pages/magic-register.astro
  • src/pages/forgot-password.astro
  • src/pages/resend-verification.astro
  • src/pages/reset-password/[...token].astro
  • src/pages/verify-magic-link/[...params].astro
  • src/pages/email-verified/[...params].astro
  • src/pages/auth/[...slug].ts

These files are critical for Mindful Auth to function. They contain:

  • Form structures built with Mindful Auth NPM components from @mindfulauth/astro
  • Dynamic token/parameter handling for password reset and email verification
  • 2FA setup and verification flows

You can add additional pages to the protected routes by creating new .astro files directly in the src/pages/[memberid]/ directory or in subdirectories for organizing your pages.

Supported file types:

  • .astro - Astro components
  • .mdx / .md - Markdown/MDX content
  • .tsx / .jsx - React components
  • .vue - Vue components
  • .svelte - Svelte components
  • .ts / .js - TypeScript/JavaScript

Examples:

Add a new page:

src/pages/[memberid]/billing.astro
---
import { MAuthProtected } from '@mindfulauth/astro/components';
import MyLayout from '../../layouts/MyLayout.astro';
const recordId = Astro.locals.recordId;
---
<MyLayout title="Billing">
<MAuthProtected>
<h1>Billing Information</h1>
<p>User {recordId}'s billing details</p>
</MAuthProtected>
</MyLayout>

Automatically accessible at: /{memberid}/billing

Nested static folder:

src/pages/[memberid]/folder-1/sample.astro
---
import { MAuthProtected } from '@mindfulauth/astro/components';
import MyLayout from '../../../layouts/MyLayout.astro';
const recordId = Astro.locals.recordId;
---
<MyLayout title="Sample">
<MAuthProtected>
<h1>Sample Page</h1>
<p>Static route for {recordId}</p>
</MAuthProtected>
</MyLayout>

Automatically accessible at: /{memberid}/folder-1/sample

Using dynamic routes:

src/pages/[memberid]/[page]/sample.astro
---
import { MAuthProtected } from '@mindfulauth/astro/components';
import MyLayout from '../../../layouts/MyLayout.astro';
const { page } = Astro.params;
const recordId = Astro.locals.recordId;
---
<MyLayout title={page}>
<MAuthProtected>
<h1>{page}</h1>
<p>Dynamic page for {recordId}</p>
</MAuthProtected>
</MyLayout>

Automatically accessible at: /{memberid}/[dynamic-page-value]/sample

Folder structure example:

[memberid]/
├── index.astro → /{memberid}/
├── dashboard.astro → /{memberid}/dashboard
├── billing.astro → /{memberid}/billing
├── [page]/
│ └── sample.astro → /{memberid}/[dynamic-page-value]/sample
└── static-folder/
└── static-page.astro → /{memberid}/static-folder/static-page

The template uses two layers of layouts:

Mindful Auth Layouts (DO NOT DELETE or remove from pages)

Section titled “Mindful Auth Layouts (DO NOT DELETE or remove from pages)”
  • MAuthPublic — imported from @mindfulauth/astro/components. Wraps public auth pages. Injects MAuthMainScript and required auth scripts. Pass scripts via the scripts prop.
  • MAuthProtected — imported from @mindfulauth/astro/components. Wraps all protected pages. Injects MAuthMainScript.

These layouts handle all required authentication scripts. Removing them from your pages will break authentication entirely.

Your own layout (e.g. src/layouts/MyLayout.astro) wraps MAuthPublic or MAuthProtected — not the other way around. Your layout handles the page <title>, navigation, and styling. No authentication scripts need to be added to it.

Route configuration (public routes, protected routes, and security headers) is managed by the @mindfulauth/astro library and configured in src/middleware.ts.

If you need to add public pages to your portal (marketing pages, documentation, etc.), keep the portal strictly for authenticated users. Instead:

  • Host public content on your main website (e.g., mysite.com)
  • Keep the portal (e.g., portal.mysite.com) exclusively for authenticated users

This approach:

  • Keeps authentication logic simple and secure
  • Provides a clear separation between public and authenticated content
  • Prevents accidental security vulnerabilities from misconfiguration
  • Server-side session validation: All protected routes validated before rendering
  • Path sanitization: Prevents directory traversal attacks
  • Request timeouts: Prevents hanging connections
  • Secure headers: CSP, HSTS, X-Frame-Options, etc.
  • HttpOnly cookies: Session cookies not accessible via JavaScript
  • CSRF protection: Via Mindful Auth’s Turnstile integration