'use client'; import * as Icons from '../Icons'; import ToggleCard from '../fields/ToggleCard'; import PasswordField from '../fields/PasswordField'; import EnvLockNote from '../fields/EnvLockNote'; import { resolveWatermarkOpacity } from '@/lib/config/schema'; import type { SectionProps } from './types'; export default function SecuritySection({ settings, update, envLocks }: SectionProps) { const passwordLock = envLocks?.sitePassword; return (

Site Password

Puts the whole public site behind one password — useful while a portfolio is still being built, or for a folio only ever shown to clients.

update('sitePassword', password ?? '')} placeholder="Leave empty for a public site" label="Site password" disabled={!!passwordLock} /> {passwordLock && }

Stored as a scrypt:… hash in settings.yaml, never as typed. {!passwordLock && ( <> {' '} The SITE_PASSWORD environment variable overrides this field. )}{' '} The admin panel keeps its own password and is never behind this gate.

Asset Protection & Watermark

Configure image protection rules, right-click prevention, and watermark overlay.

} title="Disable Right-Click Menu" description="Prevents context menu on portfolio images to hinder unauthorized downloads" checked={settings.protection?.disableRightClick === true} onToggle={() => update('protection.disableRightClick', !settings.protection?.disableRightClick) } /> } title="Disable Image Dragging" description="Prevents visitors from dragging images off the portfolio page" checked={settings.protection?.disableImageDrag === true} onToggle={() => update('protection.disableImageDrag', !settings.protection?.disableImageDrag) } />

Dynamic Watermark Overlay

Overlay copyright branding text on Lightbox images.

} title="Enable Watermark" description="Overlay copyright text on portfolio image views" checked={settings.watermark?.enabled === true} onToggle={() => update('watermark.enabled', !settings.watermark?.enabled)} />
{settings.watermark?.enabled && ( <>
update('watermark.text', e.target.value)} placeholder="© Ralfo Photography" />
{/* Read through the same normaliser the lightbox uses, so a config written as a percentage shows as "90%" here rather than "9000%" — and is written back as a fraction on save. */} update('watermark.opacity', parseFloat(e.target.value))} />
)}
); }