fix(door): thread conn.auth_param into call + audit redaction (E1, completes D10)

D10 closed the client-facing leak; this completes the defense-in-depth
so a generic-adapter connection's custom auth-param value is also
scrubbed from the operator-readable door_access_log / callDoor reason
regardless of param name. auth_param added to ConnRow +
loadEnabledConnection + the test/selfEntry selects; threaded into every
callDoor (which already redacts reason/snippet by it) and auditDoor
gained an optional authParam. Native HeatSync (e=) was already covered;
this hardens custom generic adapters. 532 tests.
This commit is contained in:
Moheeb Zara
2026-05-19 02:10:20 -07:00
parent b90debbd37
commit c2ba9586fa
+14 -9
View File
@@ -239,7 +239,7 @@ export async function testDoorConnection(input: unknown) {
const { data: conn } = await supabase
.from('door_connections')
.select('id, space_id, adapter, base_url, pinned_host, secret_ref, verbs, is_enabled')
.select('id, space_id, adapter, base_url, pinned_host, auth_param, secret_ref, verbs, is_enabled')
.eq('id', v.data.connectionId)
.eq('space_id', member.space_id)
.maybeSingle()
@@ -260,15 +260,17 @@ export async function testDoorConnection(input: unknown) {
query = applyTemplate(tmpl, { pw: password ?? '' })
}
const authParam = (conn.auth_param as string | null) ?? null
const result = await callDoor({
url: (conn.base_url as string) + query,
pinnedHost: conn.pinned_host as string,
password,
authParam,
})
const detail = result.ok
? redactDoorSecrets(`status ${result.status}: ${result.snippet}`.slice(0, 1000), password)
: redactDoorSecrets(`failed: ${result.reason}`.slice(0, 1000), password)
? redactDoorSecrets(`status ${result.status}: ${result.snippet}`.slice(0, 1000), password, authParam)
: redactDoorSecrets(`failed: ${result.reason}`.slice(0, 1000), password, authParam)
await admin.from('door_access_log').insert({
space_id: member.space_id,
@@ -344,6 +346,7 @@ type ConnRow = {
adapter: string
base_url: string
pinned_host: string
auth_param: string | null
secret_ref: string | null
verbs: Record<string, string> | null
is_enabled: boolean
@@ -356,7 +359,7 @@ async function loadEnabledConnection(
): Promise<{ ok: true; conn: ConnRow } | { ok: false; error: string }> {
const { data } = await admin
.from('door_connections')
.select('id, adapter, base_url, pinned_host, secret_ref, verbs, is_enabled')
.select('id, adapter, base_url, pinned_host, auth_param, secret_ref, verbs, is_enabled')
.eq('id', connectionId)
.eq('space_id', spaceId)
.maybeSingle()
@@ -376,6 +379,7 @@ async function auditDoor(
success: boolean
detail: string
password?: string | null
authParam?: string | null
},
) {
await admin.from('door_access_log').insert({
@@ -385,7 +389,7 @@ async function auditDoor(
target_member_id: row.targetMemberId ?? null,
action: row.action,
success: row.success,
detail: redactDoorSecrets(row.detail.slice(0, 1000), row.password),
detail: redactDoorSecrets(row.detail.slice(0, 1000), row.password, row.authParam),
})
}
@@ -499,7 +503,7 @@ export async function grantCard(input: unknown) {
})
}
const result = await callDoor({ url: conn.base_url + query, pinnedHost: conn.pinned_host, password })
const result = await callDoor({ url: conn.base_url + query, pinnedHost: conn.pinned_host, password, authParam: conn.auth_param })
if (!result.ok) {
// Roll back the reservation so slots do not leak on a failed write.
@@ -580,7 +584,7 @@ export async function revokeCard(input: unknown) {
query = applyTemplate(tmpl, { slot, pw: password ?? '' })
}
const result = await callDoor({ url: conn.base_url + query, pinnedHost: conn.pinned_host, password })
const result = await callDoor({ url: conn.base_url + query, pinnedHost: conn.pinned_host, password, authParam: conn.auth_param })
if (!result.ok) {
// Keep the slot row so the app's map stays in sync with the device's
@@ -678,7 +682,7 @@ export async function doorControl(input: unknown) {
query = applyTemplate(tmpl, { pw: password ?? '' })
}
const result = await callDoor({ url: conn.base_url + query, pinnedHost: conn.pinned_host, password })
const result = await callDoor({ url: conn.base_url + query, pinnedHost: conn.pinned_host, password, authParam: conn.auth_param })
await auditDoor(admin, {
spaceId: member.space_id, connectionId, actorMemberId: member.id,
@@ -748,7 +752,7 @@ export async function selfEntry(input: unknown) {
const { data: conn } = await admin
.from('door_connections')
.select('id, adapter, base_url, pinned_host, secret_ref, verbs, is_enabled, allow_member_self_entry')
.select('id, adapter, base_url, pinned_host, auth_param, secret_ref, verbs, is_enabled, allow_member_self_entry')
.eq('id', v.data.connectionId)
.eq('space_id', member.space_id)
.maybeSingle()
@@ -789,6 +793,7 @@ export async function selfEntry(input: unknown) {
url: (conn.base_url as string) + query,
pinnedHost: conn.pinned_host as string,
password,
authParam: (conn.auth_param as string | null) ?? null,
})
await auditDoor(admin, {