const express = require('express'); const router = express.Router(); const { v4: uuidv4 } = require('uuid'); const { db } = require('../db/database'); // Phase 2.2f: workspace-scoped branding. POST gated by requireWorkspaceAdmin // per the design doc (branding is a workspace_admin power, not editor). const { requireWorkspaceAdmin } = require('../lib/permissions'); const { resolveBranding, publicBranding } = require('../lib/branding'); // Get the current workspace's effective branding. #15: when the workspace has no // row of its own, fall through to the platform default (workspace_id IS NULL) // instead of the hardcoded ScreenTinker default, so unbranded/new workspaces // inherit the instance brand. router.get('/', (req, res) => { res.json(resolveBranding(db, { workspaceId: req.workspaceId || null })); }); // Get branding by custom domain. #15: domain match -> platform default -> // hardcoded. (Mounted behind requireAuth like the rest of this router; the // public/pre-login path is GET /api/branding, registered before auth.) router.get('/domain/:domain', (req, res) => { res.json(publicBranding(resolveBranding(db, { domain: req.params.domain }))); }); // Create or update the current workspace's white-label config. Restricted to // workspace_admin / org_owner / org_admin / platform_admin. router.post('/', requireWorkspaceAdmin, (req, res) => { if (!req.workspaceId) return res.status(403).json({ error: 'No workspace context. Switch to a workspace before configuring branding.' }); const { brand_name, logo_url, favicon_url, primary_color, secondary_color, bg_color, custom_domain, custom_css, hide_branding } = req.body; // Security (#3): custom_domain drives the PUBLIC, pre-auth branding resolver // (GET /api/branding) and custom_css is injected into the login page's