auth/cell_action_helpers.ts

The cell verbs' shared gates and audit emit.

Every gate loads the cell, reads its grants where the tier consults them, applies the tier's predicate, and answers a miss and a denial with the same cell_not_found 404. A 403 on denial would confirm the row exists, so a caller with no authority could walk ids and read a private cell's existence off the difference; one wire shape for both is the IDOR mask. Each gate returns the loaded row, so a handler that needs it doesn't re-read it.

Twins of the Rust fuz_cell_actions helpers; require_viewable_cell covers both of Rust's authenticated and _optional_auth read gates.

view source

Declarations
#

5 declarations

cell_not_found_error
#

auth/cell_action_helpers.ts view source

(): ThrownJsonrpcError import {cell_not_found_error} from '@fuzdev/fuz_app/auth/cell_action_helpers.js';

The 404 every cell gate answers for a miss and a denial alike.

returns

ThrownJsonrpcError

the cell_not_found JSON-RPC error

emit_cell_audit
#

auth/cell_action_helpers.ts view source

<T extends string>(ctx: ActionContext | ActionActorContext, audit: AuditEmitter, auth: RequestActorContext, event_type: T, metadata: (T extends "login" | ... 26 more ... | "db_admin_row_delete" ? (AuditMetadataMap[T] & Record<...>) | null : Record<...> | null) | undefined): Promise<...> import {emit_cell_audit} from '@fuzdev/fuz_app/auth/cell_action_helpers.js';

Emit a cell-domain audit event for the caller, with actor_id, account_id, and ip lifted from auth and ctx. metadata is the event's own envelope.

ctx

the action context

audit

the bound audit emitter

auth

the caller

event_type

the cell event

type T

metadata

the event's metadata envelope

type (T extends "login" | "logout" | "bootstrap" | "signup" | "password_change" | "session_revoke" | "session_revoke_all" | "token_create" | "token_revoke" | "token_revoke_all" | "role_grant_create" | "role_grant_revoke" | "role_grant_offer_create" | "role_grant_offer_accept" | "role_grant_offer_decline" | "role_grant_offer_retract" | "role_grant_offer_expire" | "role_grant_offer_supersede" | "invite_create" | "invite_delete" | "account_delete" | "account_purge" | "account_undelete" | "actor_delete" | "actor_purge" | "actor_undelete" | "app_settings_update" | "db_admin_row_delete" ? (AuditMetadataMap[T] & Record<string, unknown>) | null : Record<string, unknown> | null) | undefined

returns

Promise<void>

generics

emit_cell_audit<T extends string>
T
constraint string

throws

  • Error - when the in-transaction INSERT fails, failing the handler

mutates

  • audit_log table — inserts the row through `audit.emit`, in the request transaction

require_editable_cell
#

auth/cell_action_helpers.ts view source

(deps: QueryDeps, auth: RequestActorContext, cell_id: string & $brand<"Uuid">): Promise<CellRow> import {require_editable_cell} from '@fuzdev/fuz_app/auth/cell_action_helpers.js';

Load a cell and gate the caller on can_edit_cell, 404-masking a miss and a denial alike.

The write tier: cell_update / cell_delete, the source a field write writes, and the parent every item mutation writes.

deps

query deps

auth

the caller

cell_id

the cell to load

type Uuid

returns

Promise<CellRow>

the loaded row

throws

  • the - `cell_not_found` 404 on a miss or a denial

require_manageable_cell
#

auth/cell_action_helpers.ts view source

(deps: QueryDeps, auth: RequestActorContext, cell_id: string & $brand<"Uuid">): Promise<CellRow> import {require_manageable_cell} from '@fuzdev/fuz_app/auth/cell_action_helpers.js';

Load a cell and gate the caller on can_manage_cell, 404-masking a miss and a denial alike.

The manage tier: cell_audit_list, cell_grant_create, cell_grant_list. Manage is admin-or-owner and not a grant level, so no grant is read. A viewer or an editor gets the same mask a stranger does: an audit timeline and a share list say who touched the cell, which is more sensitive than the content.

deps

query deps

auth

the caller

cell_id

the cell to load

type Uuid

returns

Promise<CellRow>

the loaded row

throws

  • the - `cell_not_found` 404 on a miss or a denial

require_viewable_cell
#

auth/cell_action_helpers.ts view source

(deps: QueryDeps, auth: RequestContext | null, cell_id: string & $brand<"Uuid">): Promise<CellRow> import {require_viewable_cell} from '@fuzdev/fuz_app/auth/cell_action_helpers.js';

Load a cell and gate the caller on can_view_cell, 404-masking a miss and a denial alike.

The read tier: a create's parent, a clone's source, the far endpoint a write links to (so a link is no existence oracle), and the endpoints of the public relation lists, where auth may be null.

deps

query deps

auth

the caller, or null when unauthenticated

type RequestContext | null

cell_id

the cell to load

type Uuid

returns

Promise<CellRow>

the loaded row

throws

  • the - `cell_not_found` 404 on a miss or a denial

Depends on
#

Imported by
#