Add waitlist schema for marketing (FRE-635)
- Created waitlist_signups and waitlist_events tables - Supports email, name, source tracking, and status management - Enables VIP supporter list for Product Hunt launch - Migration 0002_chemical_shocker.sql generated - Fixed brand color in product-hunt-assets-brief.md (#518ac8)
This commit is contained in:
@@ -42,7 +42,7 @@ export async function recordKPI(
|
||||
metadata: metadata ? JSON.stringify(metadata) : null,
|
||||
};
|
||||
const result = await db.insert(kpiSnapshots).values(snapshot).returning();
|
||||
return result[0];
|
||||
return result[0]!;
|
||||
}
|
||||
|
||||
export async function getLatestKPI(
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export { useAuth, useAuthActions, requireAuth, ClerkProvider } from './clerk-provider';
|
||||
export { useAuth, useAuthActions, RequireAuth, ClerkProvider } from './clerk-provider';
|
||||
export { getClerk, loadClerk, getClerkUrls } from './clerk-client';
|
||||
export type { User, UserRole, Team, TeamMember, Project, ProjectStatus, ProjectCollaborator, AuthState, ClerkConfig } from './types';
|
||||
|
||||
@@ -3,6 +3,6 @@ export {
|
||||
AuthActionsContext,
|
||||
useAuth,
|
||||
useAuthActions,
|
||||
requireAuth,
|
||||
RequireAuth,
|
||||
ClerkProvider as AuthProvider,
|
||||
} from './clerk-provider';
|
||||
|
||||
@@ -189,7 +189,7 @@ export class WebSocketConnection implements WebSocketConnectionWithPresence {
|
||||
|
||||
/**
|
||||
* Send auth token via awareness state after connection
|
||||
* Security: Token not exposed in URL/logs, only sent over secure WebSocket
|
||||
* Security: Only send userId and projectId (not full JWT) to avoid credential broadcast
|
||||
*/
|
||||
private sendAuthToken(): void {
|
||||
if (!this.provider || !this.provider.awareness) {
|
||||
@@ -197,13 +197,19 @@ export class WebSocketConnection implements WebSocketConnectionWithPresence {
|
||||
return;
|
||||
}
|
||||
|
||||
// Store token in awareness state (sent to server, not in URL)
|
||||
this.provider.awareness.setLocalStateField('auth', {
|
||||
token: this.options.authToken,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
console.log('[WebSocketConnection] Auth token sent via awareness state');
|
||||
// Parse JWT to extract userId and projectId (don't broadcast full token)
|
||||
try {
|
||||
const jwtPayload = this.options.authToken.split('.')[1];
|
||||
const payload = JSON.parse(atob(jwtPayload || ''));
|
||||
this.provider.awareness.setLocalStateField('auth', {
|
||||
userId: payload.userId,
|
||||
projectId: payload.projectId,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
console.log('[WebSocketConnection] Auth credentials sent via awareness (userId, projectId only)');
|
||||
} catch (error) {
|
||||
console.error('[WebSocketConnection] Failed to parse JWT token:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user