fix(store): scope SetDomainStatus by project (IDOR); scheduler reuses DeriveStatus
handleCheck's error branch wrote last_check_status via an id-only UPDATE, so an authenticated caller's own valid project id paired with a foreign domain id in the URL could flip a stranger's domain to "error" even though Check itself is project-scoped and would 404/error out first. Add project_id to the WHERE clause (queries/domains.sql + generated db/domains.sql.go), thread projectID through Store/TenantStore/SchedStore SetDomainStatus, and pass pid from context at both call sites in handleCheck plus the scheduler. Also collapse checkDomain's inline status derivation in scheduler.go into a call to service.DeriveStatus, the same helper handleCheck already uses, so there's a single source of truth for "drift vs in_sync" instead of two copies that could drift apart. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwxdSt4reTm7Dj1oxRvpP3
This commit is contained in:
@@ -218,16 +218,17 @@ func (q *Queries) LoadDomainFull(ctx context.Context, arg LoadDomainFullParams)
|
||||
}
|
||||
|
||||
const setDomainStatus = `-- name: SetDomainStatus :exec
|
||||
UPDATE domains SET last_check_status = $2 WHERE id = $1
|
||||
UPDATE domains SET last_check_status = $2 WHERE id = $1 AND project_id = $3
|
||||
`
|
||||
|
||||
type SetDomainStatusParams struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
LastCheckStatus string `json:"last_check_status"`
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetDomainStatus(ctx context.Context, arg SetDomainStatusParams) error {
|
||||
_, err := q.db.Exec(ctx, setDomainStatus, arg.ID, arg.LastCheckStatus)
|
||||
_, err := q.db.Exec(ctx, setDomainStatus, arg.ID, arg.LastCheckStatus, arg.ProjectID)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user