security: remove VITE_TLSYNC_SECRET from frontend bundle
- Remove import.meta.env.VITE_TLSYNC_SECRET from syncService.ts - Add optional token parameter to SyncConnectionOptions interface (caller passes token fetched from API, not a baked-in secret) - Add clientEnvBlocklist in vite.config.ts to prevent sensitive VITE_ env vars (TLSYNC_SECRET, MICROSOFT_CLIENT_SECRET*) from reaching bundle - Remove VITE_TLSYNC_SECRET from .env.example - Token auth for TLSync now handled server-side or via API endpoint Ref: t_99d166c6
This commit is contained in:
parent
0db53bfd9c
commit
0d76868a42
@ -27,7 +27,6 @@ VITE_SUPABASE_ANON_KEY=your-supabase-anon-key
|
||||
# TLSync (TLDraw Sync) Configuration
|
||||
# =============================================================================
|
||||
VITE_TLSYNC_URL=https://app.classroomcopilot.ai/tldraw
|
||||
VITE_TLSYNC_SECRET=your-tlsync-secret
|
||||
|
||||
# =============================================================================
|
||||
# WhisperLive (Transcription) Configuration
|
||||
|
||||
@ -15,6 +15,8 @@ export interface SyncConnectionOptions {
|
||||
color: string;
|
||||
roomId?: string;
|
||||
baseUrl: string;
|
||||
/** Optional TLSync auth token (fetched from API server-side, never baked into bundle) */
|
||||
token?: string;
|
||||
}
|
||||
|
||||
export function createSyncConnectionOptions(options: SyncConnectionOptions) {
|
||||
@ -22,8 +24,8 @@ export function createSyncConnectionOptions(options: SyncConnectionOptions) {
|
||||
userId,
|
||||
displayName,
|
||||
roomId = 'multiplayer',
|
||||
baseUrl
|
||||
|
||||
baseUrl,
|
||||
token = ''
|
||||
} = options;
|
||||
|
||||
// Ensure we have valid user info
|
||||
@ -72,7 +74,8 @@ export function createSyncConnectionOptions(options: SyncConnectionOptions) {
|
||||
roomId: effectiveRoomId
|
||||
});
|
||||
|
||||
const token = import.meta.env.VITE_TLSYNC_SECRET ?? ''
|
||||
// Token is provided by the caller (e.g. fetched from API server-side).
|
||||
// Never embed a shared secret in the frontend bundle.
|
||||
const tokenParam = token ? `?token=${encodeURIComponent(token)}` : ''
|
||||
|
||||
return {
|
||||
|
||||
@ -14,9 +14,16 @@ export default defineConfig(({ mode }) => {
|
||||
|
||||
// Determine client-side env vars to expose
|
||||
const envPrefix = 'VITE_'
|
||||
// Blocklist: sensitive env vars that must NEVER reach the client bundle.
|
||||
const clientEnvBlocklist = new Set([
|
||||
'VITE_TLSYNC_SECRET',
|
||||
'VITE_MICROSOFT_CLIENT_SECRET',
|
||||
'VITE_MICROSOFT_CLIENT_SECRET_ID',
|
||||
])
|
||||
|
||||
const clientEnv = Object.fromEntries(
|
||||
Object.entries(env)
|
||||
.filter(([key]) => key.startsWith(envPrefix))
|
||||
.filter(([key]) => key.startsWith(envPrefix) && !clientEnvBlocklist.has(key))
|
||||
.map(([key, value]) => [`import.meta.env.${key}`, JSON.stringify(value)])
|
||||
)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user