Migration 035 adds door_connections (per-space controller integration: secret_ref -> AES-256-GCM secrets vault, never a plaintext password; pinned_host SSRF pin; native_heatsync|generic_http adapter; allow_member_self_entry opt-in for phase 3) and door_access_log (append-only, secrets redacted, service-client-only writes; immutable). RLS additive/default-deny: connections CRUD = door.manage; log SELECT = door.manage/operate. Safety core is pure and heavily unit-tested (door-logic, suite 409): validateDoorTarget (request host must equal the pinned host; metadata/link-local always blocked; http(s) only), the firmware-verified HeatSync encoders with fixed-width zero-padding (slot 3 / perm 3 / tag 8 / 4-char password), generic template substitution, and redactDoorSecrets. lib/door/executor.ts is the single hardened egress: re-validates the pin, refuses redirects, caps time and body, redacts before any audit write. The door password is read from the secrets vault and decrypted server-side only, never returned or logged. /door/manage (door.manage) configures connections, picks a vault secret, and runs a safe status-only test. Sidebar Admin link added; "Learn" moved before "People" per request. Docs updated.
24 lines
720 B
TypeScript
24 lines
720 B
TypeScript
import { requireDoorManagerPage } from '@/lib/door-guard'
|
|
import { listDoorConnections, listSecretTitles, listDoorAccessLog } from '@/lib/actions'
|
|
import { DoorManageClient } from './door-manage-client'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
export default async function DoorManagePage() {
|
|
await requireDoorManagerPage()
|
|
|
|
const [conns, secrets, log] = await Promise.all([
|
|
listDoorConnections(),
|
|
listSecretTitles(),
|
|
listDoorAccessLog(),
|
|
])
|
|
|
|
return (
|
|
<DoorManageClient
|
|
initial={'data' in conns ? (conns.data as unknown[]) : []}
|
|
secrets={'data' in secrets ? (secrets.data as { id: string; title: string }[]) : []}
|
|
log={'data' in log ? (log.data as unknown[]) : []}
|
|
/>
|
|
)
|
|
}
|