auth/role_grant_offer_action_specs.ts

Role grant offer RPC action specs — declarative contract for the consentful-role-grants surface (offer lifecycle + admin revoke + the immediate admin-only role_grant_assign).

Import this module for the specs, Input/Output schemas, ERROR_ROLE_GRANT_OFFER_* reason constants, and the all_role_grant_offer_action_specs registry. Handlers live in auth/role_grant_offer_actions.ts.

Authorization enforcement: offer-lifecycle specs declare account+actor required (no roles) and rely on query_* IDOR guards or in-handler policy checks (e.g. role_grant_offer_list/_history elevate to admin only when inspecting another account — an input-dependent check that can't be expressed at the spec level). role_grant_revoke adds roles: ['admin'] — the RPC dispatcher's per-spec post-authorization auth gate (check_action_auth_post_authorization) rejects non-admin callers before the handler runs even though the endpoint hosts non-admin methods alongside.

view source

Declarations
#

32 declarations

all_role_grant_offer_action_specs
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; initiator: "frontend" | "backend" | "both"; side_effects: boolean; input: ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>; output: ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>; ... 6 more ...; rate_limit?: "both" | ... 2 more ... | undefined; }[] import {all_role_grant_offer_action_specs} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

All role-grant-offer action specs — a codegen-ready registry. Consumers spread this into their own action-spec array to include offer lifecycle + revoke + assign methods in a typed client surface.

ERROR_ROLE_GRANT_OFFER_ACTOR_ACCOUNT_MISMATCH
#

auth/role_grant_offer_action_specs.ts view source

"role_grant_offer_actor_account_mismatch" import {ERROR_ROLE_GRANT_OFFER_ACTOR_ACCOUNT_MISMATCH} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Error reason — role_grant_offer_create was called with a to_actor_id that does not belong to to_account_id.

ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH
#

auth/role_grant_offer_action_specs.ts view source

"role_grant_offer_actor_mismatch" import {ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Error reason — actor-targeted offer was accepted by an actor other than to_actor_id.

ERROR_ROLE_GRANT_OFFER_EXPIRED
#

ERROR_ROLE_GRANT_OFFER_NOT_AUTHORIZED
#

auth/role_grant_offer_action_specs.ts view source

"role_grant_offer_not_authorized" import {ERROR_ROLE_GRANT_OFFER_NOT_AUTHORIZED} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Error reason — caller is not authorized to offer this role (default policy: caller lacks the role; consumer authorize callback may add further policy).

ERROR_ROLE_GRANT_OFFER_NOT_FOUND
#

auth/role_grant_offer_action_specs.ts view source

"role_grant_offer_not_found" import {ERROR_ROLE_GRANT_OFFER_NOT_FOUND} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Error reason — offer does not exist or belongs to a different recipient (404-over-403 IDOR mask).

ERROR_ROLE_GRANT_OFFER_ROLE_NOT_GRANTABLE
#

auth/role_grant_offer_action_specs.ts view source

"role_grant_offer_role_not_grantable" import {ERROR_ROLE_GRANT_OFFER_ROLE_NOT_GRANTABLE} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Error reason — the offered role does not include 'admin' in its RoleSpec.grant_paths (nobody may offer it via this surface).

ERROR_ROLE_GRANT_OFFER_SELF_TARGET
#

auth/role_grant_offer_action_specs.ts view source

"role_grant_offer_self_target" import {ERROR_ROLE_GRANT_OFFER_SELF_TARGET} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Error reason — caller tried to offer themselves a role_grant.

ERROR_ROLE_GRANT_OFFER_TERMINAL
#

auth/role_grant_offer_action_specs.ts view source

"role_grant_offer_terminal" import {ERROR_ROLE_GRANT_OFFER_TERMINAL} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Error reason — offer is declined, retracted, or superseded.

role_grant_assign_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; roles: string[]; }; side_effects: true; input: ZodObject<{ to_account_id: $ZodBranded<ZodUUID, "Uuid", "out">; to_actor_id: ZodOptional<...>; role: ZodString; scope_id: ZodOptional<...>; acting: ZodOpti... import {role_grant_assign_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

rate_limit: 'account' bounds admin-side burn of role_grant_assign — the action is admin-gated and audit-trailed, but the per-account cap matches role_grant_revoke so a single admin script can't churn grants in a loop.

role_grant_offer_accept_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; }; side_effects: true; input: ZodObject<{ offer_id: $ZodBranded<ZodUUID, "Uuid", "out">; acting: ZodOptional<...>; }, $strict>; output: ZodObject<...>; async: true; description: string; error_reasons: (... import {role_grant_offer_accept_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

role_grant_offer_create_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; }; side_effects: true; input: ZodObject<{ to_account_id: $ZodBranded<ZodUUID, "Uuid", "out">; ... 5 more ...; acting: ZodOptional<...>; }, $strict>; ... 4 more ...; rate_limit: "account"; } import {role_grant_offer_create_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

rate_limit: 'account' throttles offer-spam at the authenticated grantor and bounds the account-existence oracle on to_account_id — the same shape as invite_create_action_spec upstream addresses, where a hostile authed caller iterates recipients to probe ERROR_ACCOUNT_NOT_FOUND (and the actor-binding via ERROR_ROLE_GRANT_OFFER_ACTOR_ACCOUNT_MISMATCH) as an enumeration vector. Failure-outcome audit rows preserve the forensic trail; the rate cap closes the budget.

role_grant_offer_decline_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; }; side_effects: true; input: ZodObject<{ offer_id: $ZodBranded<ZodUUID, "Uuid", "out">; reason: ZodOptional<...>; acting: ZodOptional<...>; }, $strict>; output: ZodObject<...>; async: true; description... import {role_grant_offer_decline_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

role_grant_offer_history_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; }; side_effects: false; input: ZodDefault<ZodObject<{ account_id: ZodOptional<ZodNullable<$ZodBranded<ZodUUID, "Uuid", "out">>>; limit: ZodOptional<...>; offset: ZodOptional<...>; acting: ZodOptional<..... import {role_grant_offer_history_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

role_grant_offer_list_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; }; side_effects: false; input: ZodDefault<ZodObject<{ account_id: ZodOptional<ZodNullable<$ZodBranded<ZodUUID, "Uuid", "out">>>; acting: ZodOptional<...>; }, $strict>>; output: ZodObject<...>; async: tr... import {role_grant_offer_list_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

role_grant_offer_retract_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; }; side_effects: true; input: ZodObject<{ offer_id: $ZodBranded<ZodUUID, "Uuid", "out">; acting: ZodOptional<...>; }, $strict>; output: ZodObject<...>; async: true; description: string; error_reasons: (... import {role_grant_offer_retract_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

role_grant_revoke_action_spec
#

auth/role_grant_offer_action_specs.ts view source

{ method: string; kind: "request_response"; initiator: "frontend"; auth: { account: "required"; actor: "required"; roles: string[]; }; side_effects: true; input: ZodObject<{ actor_id: $ZodBranded<ZodUUID, "Uuid", "out">; role_grant_id: $ZodBranded<...>; reason: ZodOptional<...>; acting: ZodOptional<...>; }, $strict>... import {role_grant_revoke_action_spec} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

rate_limit: 'account' bounds admin-side burn of role_grant_revoke — the action is admin-gated and audit-trailed, but the per-account cap keeps a single admin script from churning role_grants in a loop and obscuring audit context for unrelated activity.

RoleGrantAssignInput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ to_account_id: $ZodBranded<ZodUUID, "Uuid", "out">; to_actor_id: ZodOptional<ZodNullable<$ZodBranded<ZodUUID, "Uuid", "out">>>; role: ZodString; scope_id: ZodOptional<...>; acting: ZodOptional<...>; }, $strict> import type {RoleGrantAssignInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_assign — the immediate admin-only conferral path, the consent-free sibling of role_grant_offer_create. An admin assigns a role_grant straight onto the target actor; there is no offer for a grantee to accept. No message (no offer to carry it on) and no scope_kind (scope_id alone is the v1 scope discriminator — the grant row's scope_kind stays null).

RoleGrantAssignOutput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ ok: ZodLiteral<true>; role_grant_id: $ZodBranded<ZodUUID, "Uuid", "out">; }, $strict> import type {RoleGrantAssignOutput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Output for role_grant_assign.

RoleGrantOfferAcceptInput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ offer_id: $ZodBranded<ZodUUID, "Uuid", "out">; acting: ZodOptional<$ZodBranded<ZodUUID, "Uuid", "out">>; }, $strict> import type {RoleGrantOfferAcceptInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_offer_accept.

RoleGrantOfferAcceptOutput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ role_grant_id: $ZodBranded<ZodUUID, "Uuid", "out">; offer: ZodObject<{ id: $ZodBranded<ZodUUID, "Uuid", "out">; from_actor_id: $ZodBranded<ZodUUID, "Uuid", "out">; ... 13 more ...; resulting_role_grant_id: ZodNullable<...>; }, $strict>; superseded_offer_ids: ZodArray<...>; }, $strict> import type {RoleGrantOfferAcceptOutput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Output for role_grant_offer_accept.

RoleGrantOfferCreateInput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ to_account_id: $ZodBranded<ZodUUID, "Uuid", "out">; to_actor_id: ZodOptional<ZodNullable<$ZodBranded<ZodUUID, "Uuid", "out">>>; ... 4 more ...; acting: ZodOptional<...>; }, $strict> import type {RoleGrantOfferCreateInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_offer_create.

to_actor_id (optional) narrows the offer to a specific actor on the recipient account. When supplied, role_grant_offer_accept will only admit the named actor — wrong-actor accepts reject with role_grant_offer_actor_mismatch. The audit envelope's target_actor_id is stamped from this column on the create / supersede / expire / retract events. Omit (or pass null) for the account-grain default — any actor on to_account_id may accept.

RoleGrantOfferCreateOutput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ offer: ZodObject<{ id: $ZodBranded<ZodUUID, "Uuid", "out">; from_actor_id: $ZodBranded<ZodUUID, "Uuid", "out">; to_account_id: $ZodBranded<ZodUUID, "Uuid", "out">; ... 12 more ...; resulting_role_grant_id: ZodNullable<...>; }, $strict>; }, $strict> import type {RoleGrantOfferCreateOutput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Output for role_grant_offer_create.

RoleGrantOfferDeclineInput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ offer_id: $ZodBranded<ZodUUID, "Uuid", "out">; reason: ZodOptional<ZodNullable<ZodString>>; acting: ZodOptional<$ZodBranded<ZodUUID, "Uuid", "out">>; }, $strict> import type {RoleGrantOfferDeclineInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_offer_decline.

RoleGrantOfferHistoryInput
#

auth/role_grant_offer_action_specs.ts view source

ZodDefault<ZodObject<{ account_id: ZodOptional<ZodNullable<$ZodBranded<ZodUUID, "Uuid", "out">>>; limit: ZodOptional<ZodNullable<ZodNumber>>; offset: ZodOptional<...>; acting: ZodOptional<...>; }, $strict>> import type {RoleGrantOfferHistoryInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_offer_history. Returns every offer involving the account in either direction (recipient or grantor), including terminal rows, newest first. account_id is admin-only.

RoleGrantOfferHistoryOutput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ offers: ZodArray<ZodObject<{ id: $ZodBranded<ZodUUID, "Uuid", "out">; from_actor_id: $ZodBranded<ZodUUID, "Uuid", "out">; to_account_id: $ZodBranded<ZodUUID, "Uuid", "out">; ... 12 more ...; resulting_role_grant_id: ZodNullable<...>; }, $strict>>; }, $strict> import type {RoleGrantOfferHistoryOutput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Output for role_grant_offer_history.

RoleGrantOfferListInput
#

auth/role_grant_offer_action_specs.ts view source

ZodDefault<ZodObject<{ account_id: ZodOptional<ZodNullable<$ZodBranded<ZodUUID, "Uuid", "out">>>; acting: ZodOptional<$ZodBranded<ZodUUID, "Uuid", "out">>; }, $strict>> import type {RoleGrantOfferListInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_offer_list. account_id is admin-only (inspect another account's inbox).

RoleGrantOfferListOutput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ offers: ZodArray<ZodObject<{ id: $ZodBranded<ZodUUID, "Uuid", "out">; from_actor_id: $ZodBranded<ZodUUID, "Uuid", "out">; to_account_id: $ZodBranded<ZodUUID, "Uuid", "out">; ... 12 more ...; resulting_role_grant_id: ZodNullable<...>; }, $strict>>; }, $strict> import type {RoleGrantOfferListOutput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Output for role_grant_offer_list.

RoleGrantOfferOkOutput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ ok: ZodLiteral<true>; }, $strict> import type {RoleGrantOfferOkOutput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Output for role_grant_offer_decline / role_grant_offer_retract.

RoleGrantOfferRetractInput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ offer_id: $ZodBranded<ZodUUID, "Uuid", "out">; acting: ZodOptional<$ZodBranded<ZodUUID, "Uuid", "out">>; }, $strict> import type {RoleGrantOfferRetractInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_offer_retract.

RoleGrantRevokeInput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ actor_id: $ZodBranded<ZodUUID, "Uuid", "out">; role_grant_id: $ZodBranded<ZodUUID, "Uuid", "out">; reason: ZodOptional<ZodNullable<ZodString>>; acting: ZodOptional<...>; }, $strict> import type {RoleGrantRevokeInput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Input for role_grant_revoke. Admin-only mutation that revokes an active role_grant on a target actor. actor_id is the natural key — role_grants are actor-scoped, and the admin UI reads row.actor.id straight from the listing. Deriving actor_id from account_id would collapse under multi-actor accounts.

RoleGrantRevokeOutput
#

auth/role_grant_offer_action_specs.ts view source

ZodObject<{ ok: ZodLiteral<true>; revoked: ZodLiteral<true>; }, $strict> import type {RoleGrantRevokeOutput} from '@fuzdev/fuz_app/auth/role_grant_offer_action_specs.js';

Output for role_grant_revoke.

Depends on
#

Imported by
#