hyperclay
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v59View latest version
This is a Hyperclay-compatible HTML editor application that provides secure email-based authentication for editing HTML documents with version control. The app serves both as a public viewer and an authenticated editor interface.
- Storage: Uses Val Town blob storage for persistence
- Versioning: Automatic version history with incremental numbering
- Default Content: Falls back to a Hyperclay starter template when no content exists
- Reset Capability: Admin can reset to default state (dangerous operation)
- Magic Link Auth: Email-based passwordless authentication
- Admin-Only Access: Only the configured admin email can authenticate
- Session Management: 30-day sessions with automatic extension
- Token Security: 15-minute expiring one-time-use tokens
- Edit Mode Cookies: Sets
currentResource
andisAdminOfCurrentResource
cookies for authenticated admins - Security: Server-side cookie setting with proper security attributes
- View Mode: Cookie clearing for public viewing
Blob Keys:
- `${APP_NAMESPACE}_app` - Current HTML document
- `${APP_NAMESPACE}_app_version_${n}` - Versioned HTML documents
- `${APP_NAMESPACE}_app_version_count` - Version counter
- `${APP_NAMESPACE}_auth_token_${token}` - Magic link tokens (15min TTL)
- `${APP_NAMESPACE}_session_${sessionId}` - User sessions (30day TTL)
ADMIN_EMAIL
- Email address allowed to authenticate (required)APP_NAMESPACE
- Storage namespace prefix (default: 'default')DEBUG
- Enable debug logging (default: false)
- Session Cookie:
session=${sessionId}
- HttpOnly, Secure, 30-day expiry - Hyperclay Cookies (admin only):
currentResource=app
- Identifies the resource being editedisAdminOfCurrentResource=true
- Enables Hyperclay edit mode
-
GET /
- Serve HTML document- Check admin status from session cookie
- Set Hyperclay cookies if admin
- Return HTML content
-
GET /auth/edit
- Show email login form -
POST /auth/edit
- Process email submission- Validate admin email
- Generate magic link token
- Send email with magic link
- Show confirmation page
-
GET /auth/verify?token=xxx
- Verify magic link- Validate and consume token
- Create session
- Set session cookie
- Redirect to main page
-
GET /auth/view
- Logout/view mode- Clear all cookies
- Redirect to main page
-
POST /save/app
- Save HTML document- Verify admin session
- Validate HTML content
- Save with versioning
- Return success response
-
GET /versions
- View version history- Verify admin session
- Display all versions with HTML preview
-
POST /reset-dangerous
- Reset to default- Verify admin session
- Clear all versions and content
- Reset to default HTML
- User enters admin email → Magic link sent
- User clicks magic link → Token verified & consumed
- Session created → 30-day cookie set
- Subsequent requests → Session validated & extended
- Public Access: View HTML document, access auth forms
- Admin Access: Save content, view versions, reset state
- Session Validation: Every admin operation checks session validity
- HttpOnly: Session cookies not accessible to JavaScript
- Secure: Only transmitted over HTTPS
- SameSite=Lax: CSRF protection
- Proper Expiration: Consistent 30-day expiry
- Monolithic Handler: Single 700+ line function handles all routes
- Mixed Concerns: Authentication, routing, HTML generation all intermingled
- Repetitive Patterns: Manual response creation throughout
- Hard to Test: Tightly coupled logic makes unit testing difficult
- Route Parsing: Manual URL path checking with if/else chains
- Cookie Management: Manual parsing and setting throughout
- Error Handling: Inconsistent error response patterns
- Content-Type Setting: Repetitive header management
- Single Point of Failure: All logic in one massive function
- Code Duplication: Similar HTML templates repeated
- Hard to Extend: Adding new routes requires modifying the monolith
- Debug Complexity: Hard to trace issues through nested conditionals
- Route Separation: Each endpoint becomes a focused handler
- Middleware Chain: Authentication, logging, error handling as reusable middleware
- Type Safety: Better TypeScript integration
- Testability: Individual route handlers can be unit tested
- Declarative Routing:
app.get('/path', handler)
instead of manual parsing - Built-in Helpers: Cookie, JSON, redirect helpers
- Error Boundaries: Centralized error handling
- Hot Reloading: Better development experience
- Modular Design: Features can be developed independently
- Consistent Patterns: Framework conventions reduce cognitive load
- Easier Debugging: Clear request/response flow
- Future-Proof: Easier to add features like API endpoints, webhooks, etc.