moderator-toolbox-nxg-for-reddit / util/infra/captureGuard

util/infra/captureGuard

Functions

assertActionAllowed()

assertActionAllowed(action, opts?): void

Defined in: extension/data/util/infra/captureGuard.ts:227

Throws CaptureSuppressedError if performing a real moderation action now would violate the training/second-opinion sandbox. Called at the top of every mutating moderation primitive.

Allowed (no throw) when: inside an authorized replay; or the resolved subreddit is not capture-active (the common case - non-trainees); or the subreddit cannot be resolved AND the user is sandboxed nowhere (a non-trainee is never blocked).

When the subreddit cannot be resolved (a multi-sub page) but the user is sandboxed somewhere, we cannot prove the action is outside their sandbox, so we fail closed - blocking it rather than leaking a real moderation action. The block carries no captured intent (the primitive lacks one); the gateway remains the path that captures properly. A non-trainee is sandboxed nowhere, so this never blocks legitimate mod work.

Parameters

action

string

Name of the primitive, for the error message.

opts?

AssertOptions

How to resolve the action’s subreddit.

Returns

void


isCaptureActiveFor()

isCaptureActiveFor(subreddit): boolean

Defined in: extension/data/util/infra/captureGuard.ts:63

Returns whether the current user is sandboxed for subreddit. Synchronous - backed by warm config via the installed predicate.

Parameters

subreddit

string

The subreddit to check.

Returns

boolean


isInReplay()

isInReplay(): boolean

Defined in: extension/data/util/infra/captureGuard.ts:152

Returns whether execution is currently inside an authorized proposal replay.

Returns

boolean


registerItemSubreddit()

registerItemSubreddit(subreddit, fullname): void

Defined in: extension/data/util/infra/captureGuard.ts:115

Registers the subreddit a thing belongs to, so a primitive that only receives a fullname can still resolve its subreddit for the guard. Populated by the button-attach code, which already knows each item’s subreddit.

Parameters

subreddit

string

The subreddit it belongs to.

fullname

string

The thing’s fullname (e.g. t3_abc).

Returns

void


runInReplay()

runInReplay<T>(fn): Promise<T>

Defined in: extension/data/util/infra/captureGuard.ts:170

Runs fn as an authorized proposal replay, during which mutating primitives are permitted (the gateway uses this when Accepting a proposal). Uses a depth counter so nested replays are handled; restores on both success and failure.

LIMITATION: the counter is process-global, not async-context-local (the browser has no AsyncLocalStorage), so any guarded action that starts while a replay is awaiting also sees isInReplay() true and is permitted. In practice this is safe because a replay only runs for a reviewer accepting a proposal, who is not sandboxed for that subreddit - the per-subreddit predicate, not this window, is the real gate. A precise fix would thread a per-call authorization token through every primitive; deferred as disproportionate to the (cross-sub, concurrent) race it would close.

Type Parameters

T

T

Parameters

fn

() => Promise<T>

The replay work to run.

Returns

Promise<T>


setCaptureActivePredicate()

setCaptureActivePredicate(predicate): () => void

Defined in: extension/data/util/infra/captureGuard.ts:51

Installs the predicate that decides whether the current user is in training/second-opinion capture mode for a given subreddit. Called by the proposals module from warm config. Returns a disposer that restores the default.

Parameters

predicate

CaptureActivePredicate

Synchronous per-subreddit capture-active check.

Returns

() => void


setCaptureAnywherePredicate()

setCaptureAnywherePredicate(predicate): () => void

Defined in: extension/data/util/infra/captureGuard.ts:88

Installs the predicate that decides whether the current user is sandboxed in any subreddit at all. Used to fail closed when an action’s subreddit cannot be resolved (a multi-sub page): a sandboxed user is blocked rather than leaking a real action, while a non-trainee - who is sandboxed nowhere - is still never blocked. Returns a disposer that restores the default.

Parameters

predicate

CaptureAnywherePredicate

Synchronous “sandboxed anywhere” check (warm state only).

Returns

() => void


setCaptureExpected()

setCaptureExpected(expected): () => void

Defined in: extension/data/util/infra/captureGuard.ts:192

Test/dev only: assert that no real moderation action should fire right now, so a capture-path test can prove “zero primitives executed.” Has no role in production (the per-subreddit predicate is the real gate). Returns a disposer that restores the prior value - like the predicate setters - so a leaked true can’t trip unrelated guarded calls in a later test.

Parameters

expected

boolean

Whether to expect capture (suppress all non-replay actions).

Returns

() => void


setPageSubreddit()

setPageSubreddit(subreddit): void

Defined in: extension/data/util/infra/captureGuard.ts:132

Sets the current page’s subreddit, used as the fallback when an action’s subreddit isn’t otherwise known (single-sub pages: a sub’s modqueue, a post).

Parameters

subreddit

string | undefined

The page subreddit, or undefined to clear.

Returns

void


unregisterItemSubreddit()

unregisterItemSubreddit(fullname): void

Defined in: extension/data/util/infra/captureGuard.ts:120

Forgets a registered item->subreddit mapping (e.g. when an item leaves the page).

Parameters

fullname

string

Returns

void

Classes

CaptureSuppressedError

Defined in: extension/data/util/infra/captureGuard.ts:29

Thrown by assertActionAllowed when a real action is suppressed.

Extends

  • Error

Constructors

Constructor

new CaptureSuppressedError(action, subreddit): CaptureSuppressedError

Defined in: extension/data/util/infra/captureGuard.ts:30

Parameters
action

string

subreddit

string | undefined

Returns

CaptureSuppressedError

Overrides

Error.constructor

Methods

isError()

static isError(error): error is Error

Defined in: node_modules/typescript/lib/lib.esnext.error.d.ts:21

Indicates whether the argument provided is a built-in Error instance or not.

Parameters
error

unknown

Returns

error is Error

Inherited from

Error.isError

Properties

action

action: string

Defined in: extension/data/util/infra/captureGuard.ts:30

cause?

optional cause?: unknown

Defined in: node_modules/typescript/lib/lib.es2022.error.d.ts:24

Inherited from

Error.cause

message

message: string

Defined in: node_modules/typescript/lib/lib.es5.d.ts:1075

Inherited from

Error.message

name

name: string

Defined in: node_modules/typescript/lib/lib.es5.d.ts:1074

Inherited from

Error.name

stack?

optional stack?: string

Defined in: node_modules/typescript/lib/lib.es5.d.ts:1076

Inherited from

Error.stack

subreddit

subreddit: string | undefined

Defined in: extension/data/util/infra/captureGuard.ts:30

Interfaces

AssertOptions

Defined in: extension/data/util/infra/captureGuard.ts:203

Options identifying which subreddit a guarded action targets.

Properties

fullname?

optional fullname?: string

Defined in: extension/data/util/infra/captureGuard.ts:205

Fullname of the targeted thing (resolved to a subreddit via the item map).

subreddit?

optional subreddit?: string

Defined in: extension/data/util/infra/captureGuard.ts:207

Explicit subreddit, when the primitive knows it (e.g. ban/mute).