Skip to content

Public Portal Home Middleware ​

File Information ​

  • Path: app/middleware/public-portal-home.ts
  • Purpose: Public portal auto-login on brand home page
  • Type: Per-Route Middleware (Client-Only)

Overview ​

The public-portal-home.ts middleware handles automatic login for public portals when unauthenticated visitors land on the brand home page (/{brand_name}). It checks if the workspace is configured as a public portal and automatically logs in the user if it is.

Features ​

  • Client-Only Execution: Runs only on client-side (not SSR)
  • Public Portal Detection: Checks if workspace is a public portal
  • Automatic Login: Auto-logs in public portal users
  • Session Validation: Validates existing sessions before checking portal
  • Home Page Specific: Only runs on exact brand home route

Key Characteristics ​

Client-Only Middleware ​

This middleware is intentionally client-only because:

  • Session is stored in HTTP-only cookies
  • Cookies must be set via server API response
  • Browser context is required for cookie handling
typescript
if (import.meta.server) return // Skip on server

Route Specificity ​

Only runs on the exact brand home route:

typescript
// Only run on brand home route
if (to.path !== `/${brandUrlSlug}`) return

Implementation Details ​

Session Validation ​

Before checking for public portal, validates existing session:

typescript
if (authStore.user && import.meta.client) {
  try {
    const sessionCheck = await $fetch<{ authenticated: boolean }>('/api/auth/session')
    if (sessionCheck?.authenticated) {
      // Session is valid, allow access
      return
    }
  } catch (error) {
    // Continue to public portal check
  }
}

Public Portal Check ​

Checks if workspace is a public portal and auto-logs in:

typescript
const { checkAndLoginPublicPortal } = usePublicPortal()
const result = await checkAndLoginPublicPortal(brandUrlSlug)

if (!result.isPublicPortal) {
  // Not a public portal, redirect to login
  return navigateTo(`/${brandUrlSlug}/login`, { replace: true })
}

if (!result.loggedIn) {
  // Public portal but login failed, redirect to login
  return navigateTo(`/${brandUrlSlug}/login`, { replace: true })
}

// Public portal and logged in successfully, allow access

Usage ​

In Brand Home Page ​

vue
<!-- app/pages/[brand_name]/index.vue -->
<script setup lang="ts">
definePageMeta({
  middleware: 'public-portal-home'
})
</script>

<template>
  <div>
    <!-- Dashboard content -->
  </div>
</template>

Execution Flow ​

1. Check if client-side → Skip if server
2. Check if brand home route → Skip if not
3. Check if authenticated → Skip if authenticated
4. Validate existing session → Skip if valid session
5. Check if public portal → Redirect to login if not
6. Auto-login public portal → Redirect to login if fails
7. Allow access if logged in

Error Handling ​

The middleware handles errors gracefully:

typescript
try {
  const result = await checkAndLoginPublicPortal(brandUrlSlug)
  // Handle result
} catch (error) {
  console.error('[public-portal-home] failed:', error)
  return navigateTo(`/${brandUrlSlug}/login`, { replace: true })
}

Dependencies ​

  • usePublicPortal() - Public portal composable
  • useAuthStore() - Authentication store
  • $fetch() - API client for session check
  • navigateTo() - Nuxt navigation helper