Last1 Auth Integration - Prompt¶
Copy this prompt to implement the branded auth page and user sync webhook on Last1.app.
Task: Implement RadioCheck Branded Auth and User Sync¶
Last1 is the central authentication provider for both last1.app and RadioCheck. We need to implement:
- A branded auth page that can display RadioCheck branding when accessed with
?brand=radiocheck - A webhook sender that notifies RadioCheck when users are created/updated
1. Branded Auth Page¶
Create a new route at GET /auth that supports multiple brands.
Query Parameters:
- brand - "radiocheck" or "last1" (default: "last1")
- redirect - URL to redirect after successful auth (required)
- mode - "login" or "signup" (optional, default: "login")
Branding Configuration:
const BRAND_CONFIG = {
last1: {
name: 'Last1',
logo: '/images/last1-logo.png',
primaryColor: '#4F46E5',
tagline: 'Supporting those who served',
},
radiocheck: {
name: 'Radio Check',
logo: 'https://radiocheck.app/logo.png', // Or host locally
primaryColor: '#D4AF37', // Gold
tagline: 'Never leave a veteran behind',
},
};
Auth Page Behavior:
1. Display logo and colors based on brand parameter
2. Show login or signup form based on mode parameter
3. Authenticate user with Supabase Auth
4. On success, redirect to: {redirect}?token={access_token}&refresh_token={refresh_token}&user_id={user_id}
5. On failure, show error message with brand styling
Example URLs:
- https://last1.app/auth?brand=radiocheck&redirect=https://radiocheck.app/checkout&mode=signup
- https://last1.app/auth?brand=last1&redirect=https://last1.app/dashboard
Implementation Notes: - The access token should be a short-lived JWT (5 minutes) - Include user metadata in the redirect (user_id, email) - Support "Remember me" functionality for persistent sessions
2. User Sync Webhook Sender¶
When a user is created or updated on Last1, send a webhook to RadioCheck to sync the user.
Webhook Endpoint: POST https://<radiocheck-supabase-project>.supabase.co/functions/v1/sync-user-from-last1
Events to Send:
- user.created - When a new user signs up
- user.updated - When user profile is updated
- user.deleted - When user account is deleted
- user.email_verified - When email is verified
Webhook Payload:
interface UserWebhookPayload {
event: 'user.created' | 'user.updated' | 'user.deleted' | 'user.email_verified';
timestamp: string; // ISO 8601
user_id: string; // UUID
email: string;
display_name?: string;
phone?: string;
metadata?: {
source?: string; // 'last1' or 'radiocheck'
email_verified?: boolean;
created_at?: string;
// Any other relevant user metadata
};
}
Security - HMAC Signature: Sign the payload with HMAC-SHA256 using a shared secret.
import crypto from 'crypto';
function signWebhook(payload: object, secret: string): string {
const payloadString = JSON.stringify(payload);
return crypto
.createHmac('sha256', secret)
.update(payloadString)
.digest('hex');
}
// When sending the webhook:
const payload = { event: 'user.created', ... };
const signature = signWebhook(payload, process.env.RADIOCHECK_WEBHOOK_SECRET);
await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Last1-Signature': signature,
'X-Last1-Timestamp': new Date().toISOString(),
},
body: JSON.stringify(payload),
});
Implementation Options:
Option A: Supabase Database Webhook (Recommended)
Use Supabase's built-in database webhooks to trigger on auth.users changes:
- Go to Last1 Supabase Dashboard > Database > Webhooks
- Create webhook for
auth.userstable on INSERT, UPDATE, DELETE - Point to an Edge Function that formats and sends to RadioCheck
Option B: Application-Level Hook Add hooks in your auth routes:
// After successful signup
async function onUserCreated(user: User) {
await sendWebhookToRadioCheck('user.created', user);
}
// After profile update
async function onUserUpdated(user: User) {
await sendWebhookToRadioCheck('user.updated', user);
}
3. Environment Variables¶
Add to your Last1 environment:
# RadioCheck Webhook Integration
RADIOCHECK_WEBHOOK_URL=https://<radiocheck-project>.supabase.co/functions/v1/sync-user-from-last1
RADIOCHECK_WEBHOOK_SECRET=<shared-secret-from-radiocheck>
4. CORS Configuration¶
Ensure Last1's Supabase allows requests from radiocheck.app:
-- In Supabase SQL Editor (if needed)
-- Usually handled by Supabase automatically for auth endpoints
5. Email Templates¶
Update email templates to support branding:
- Go to Last1 Supabase Dashboard > Authentication > Email Templates
- Update templates to include dynamic branding based on user metadata
- Example: If
user.user_metadata.source === 'radiocheck', use RadioCheck branding
Confirmation Email Template (example):
<h2>Welcome to {{ if .UserMetaData.source == "radiocheck" }}Radio Check{{ else }}Last1{{ end }}!</h2>
<p>Click the link below to confirm your email:</p>
<a href="{{ .ConfirmationURL }}">Confirm Email</a>
Testing¶
- Test branded auth page:
- Visit
https://last1.app/auth?brand=radiocheck&redirect=http://localhost:3000/test - Verify RadioCheck branding appears
- Complete signup/login flow
-
Verify redirect with token
-
Test webhook sync:
- Create a new user on Last1
- Check RadioCheck Supabase
userstable for new record - Update user profile on Last1
- Verify changes sync to RadioCheck
Summary¶
After implementing this: - Users can sign up for RadioCheck via last1.app/auth with RadioCheck branding - All user accounts are stored in Last1's Supabase (single source of truth) - User data syncs to RadioCheck's Supabase via webhook - RadioCheck mobile app and radiocheck.app both authenticate against Last1