Temporary Email Access with NocoDB Session Capture

Simplified email capture flow that grants immediate access to confidential content while logging sessions to NocoDB.

Claude
Claude Claude

Changelog - 2025-12-25 (#3)

Dark Matter Site: Temporary Email Access with NocoDB Session Capture

Overview

Implemented a streamlined "side door" for temporary access to confidential content. Users click a subtle link, enter their email in a modal, and are immediately granted access. No email verification required - the email and session start time are captured to NocoDB for tracking.

Key deliverables:

  • Temporary Access Modal: Clean popup triggered by subtle link
  • Instant Access: No verification - submit email, get access
  • NocoDB Session Logging: Email + timestamp saved to database
  • Mode-Responsive Design: Modal adapts to light/dark/vibrant themes

User Flow

┌─────────────────────────────────────────────────────────────────────────────┐
│                        Temporary Access Flow                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   /portfolio-gate                                                            │
│         │                                                                    │
│         ▼                                                                    │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │  ┌─────────────┐ ┌─────────────┐                                    │   │
│   │  │  Passcode   │ │    Email    │  ← Main auth tabs                  │   │
│   │  └─────────────┘ └─────────────┘                                    │   │
│   │                                                                      │   │
│   │       "Get temporary access here"  ← Subtle link                    │   │
│   │                    │                                                 │   │
│   └────────────────────┼─────────────────────────────────────────────────┘   │
│                        │                                                     │
│                        ▼                                                     │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │                     Modal Popup                                      │   │
│   │  ┌───────────────────────────────────────────────────────────────┐  │   │
│   │  │                                                               │  │   │
│   │  │   Temporary Access                                     [X]   │  │   │
│   │  │                                                               │  │   │
│   │  │   Enter your email to request temporary access                │  │   │
│   │  │   to confidential content.                                    │  │   │
│   │  │                                                               │  │   │
│   │  │   ┌─────────────────────────────────────────────────────┐    │  │   │
│   │  │   │  you@company.com                                    │    │  │   │
│   │  │   └─────────────────────────────────────────────────────┘    │  │   │
│   │  │                                                               │  │   │
│   │  │   [ Get Temporary Access in a brief moment ]                 │  │   │
│   │  │                                                               │  │   │
│   │  └───────────────────────────────────────────────────────────────┘  │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                        │                                                     │
│                        ▼                                                     │
│              POST /api/verify-temp-access                                    │
│                        │                                                     │
│         ┌──────────────┴──────────────┐                                     │
│         │                             │                                      │
│         ▼                             ▼                                      │
│   Save to NocoDB               Set auth cookie                              │
│   emailAccess table            (24 hours)                                   │
│         │                             │                                      │
│         └──────────────┬──────────────┘                                     │
│                        │                                                     │
│                        ▼                                                     │
│              /portfolio/confidential                                         │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Changes by Area

1. Temporary Access Trigger

Added a subtle link below the auth tabs:

<!-- Temporary Access Link -->
<p class="text-center">
  <button
    type="button"
    id="temp-access-trigger"
    class="text-xs text-foreground/40 hover:text-primary transition-colors underline underline-offset-2"
  >
    Get temporary access here
  </button>
</p>

2. Modal Component

Full modal with backdrop blur, close button, and email form:

<div id="temp-access-modal" class="modal-overlay hidden">
  <div class="modal-backdrop"></div>
  <div class="modal-container">
    <div class="modal-content">
      <button id="modal-close" class="modal-close">×</button>

      <h2>Temporary Access</h2>
      <p>Enter your email to request temporary access...</p>

      <form method="POST" action="/api/verify-temp-access">
        <input type="hidden" name="redirect" value="/portfolio/confidential" />
        <input type="email" name="email" placeholder="you@company.com" required />
        <button type="submit">Get Temporary Access in a brief moment</button>
      </form>
    </div>
  </div>
</div>

Modal Features:

  • Backdrop click to close
  • Escape key to close
  • Auto-focus on email input
  • Form submits on Enter
  • Body scroll lock when open

3. Simplified API Endpoint

Created /api/verify-temp-access.ts - much simpler than the full email verification:

export const POST: APIRoute = async ({ request, cookies, redirect }) => {
  const formData = await request.formData();
  const email = formData.get('email');

  // Log to NocoDB (fire and forget)
  createEmailAccessSession(email);

  // Set auth cookie
  cookies.set('universal_portfolio_access', sessionToken, {
    httpOnly: true,
    secure: import.meta.env.PROD,
    maxAge: 60 * 60 * 24, // 24 hours
  });

  // Redirect to confidential content
  return redirect('/portfolio/confidential');
};

Key Differences from verify-email.ts:

verify-email.ts verify-temp-access.ts
Checks domain allowlist No domain checking
Checks previous sessions No session lookup
May show "pending" message Always grants access
Complex access logic Simple capture + grant

4. NocoDB v3 API Fix

Fixed the POST body format for creating records:

Before (broken):

body: JSON.stringify({
  emailOfAccessor: email,
  sessionStartTime: timestamp,
})

After (working):

body: JSON.stringify([
  {
    fields: {
      emailOfAccessor: email,
      sessionStartTime: timestamp,
    },
  },
])

The v3 API requires:

  • Array of records (even for single record)
  • Each record wrapped in { fields: {...} }

5. Mode-Responsive Modal Styling

/* Light mode */
:global([data-mode="light"]) .modal-content {
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}

/* Dark mode */
:global([data-mode="dark"]) .modal-backdrop {
  background: rgba(0, 0, 0, 0.7);
}

:global([data-mode="dark"]) .modal-content {
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.5);
}

/* Vibrant mode - signature purple glow */
:global([data-mode="vibrant"]) .modal-content {
  background: rgba(15, 9, 35, 0.95);
  border-color: rgba(102, 67, 226, 0.4);
  box-shadow:
    0 0 40px rgba(102, 67, 226, 0.2),
    0 0 80px rgba(102, 67, 226, 0.1);
}

Files Changed Summary

New

File Purpose
src/pages/api/verify-temp-access.ts Simple email capture + instant access endpoint

Modified

File Changes
src/pages/portfolio-gate.astro Added trigger link, modal HTML, modal JS, modal CSS
src/lib/nocodb.ts Fixed v3 API POST body format for createEmailAccessSession

NocoDB Record Format

Each temporary access creates a record:

{
  "id": 1,
  "fields": {
    "emailOfAccessor": "investor@example.com",
    "sessionStartTime": "2025-12-25T18:30:00.000Z",
    "sessionEndTime": null
  }
}

Design Decisions

Why a "Side Door"?

The main auth flow (tabs with Passcode/Email) is for users who have credentials or are from known domains. The temporary access link is for:

  • Quick demos to potential investors
  • Users who just want to peek at confidential content
  • Situations where sharing a passcode is inconvenient

Why No Verification?

For this phase, we prioritized:

  1. Low friction - Don't scare away interested users
  2. Data capture - We still get their email for follow-up
  3. Simplicity - Can add verification later if needed

Future iterations could add:

  • Email verification (magic link)
  • Time-limited access tokens
  • Rate limiting on submissions

Notes / Follow-Ups

  1. Session End Tracking: Could add beforeunload event to call endEmailAccessSession() and populate sessionEndTime.

  2. Duplicate Handling: Currently creates new record for each submission. Could check for existing email first.

  3. Rate Limiting: No protection against spam submissions yet.

  4. Analytics Dashboard: Could build admin view to see who's accessing content.

  5. Access at: /portfolio-gate → click "Get temporary access here"