Files
wekan/server/lib/argumentChecks.js
Lauri Ojansivu 508484ef1e Sign-up, and every method and publication, pass audit-argument-checks again.
Registering answered "Internal server error" - and created the account
anyway, so the next try said it already existed - and the
starredPublicBoards and translation publications failed for everybody:
"Did not check() all arguments". audit-argument-checks asks,
synchronously, the moment a handler returns, whether check() saw every
argument. The REQUIRE_2FA wrapper of every method and publication, and
the Audit log's wrapper of the administrators' methods, were async and
awaited before they called the handler - even with REQUIRE_2FA off - so
the handler's own check() came after the audit had already failed the
call, and the handler went on running.

A wrapper now calls the handler at once when it needs no lookup
(REQUIRE_2FA off, nobody signed in, a cached answer). When it must await
first, it hands the audit over (server/lib/argumentChecks.js): the
arguments count as seen for the outer audit, and the handler runs under
an audit of its own that it must satisfy exactly as unwrapped.

tests/wrappedHandlerArgumentChecks.test.cjs runs both wrappers under a
model of the check package's audit: a checking handler passes, off and
on, a refusal stays a refusal, a handler that does not check still fails
on every path, and no wrapper in server/ awaits before it has checked.

Thanks to xet7 !
2026-10-31 14:13:40 +02:00

29 lines
1.4 KiB
JavaScript

import { check, Match } from 'meteor/check';
// For a wrapper of Meteor's method and publication handlers that has to AWAIT
// before it calls the handler (server/requireTwoFactor.js, server/adminAudit.js).
//
// audit-argument-checks (.meteor/packages) asks, synchronously, the moment a
// handler returns, whether check() has seen every argument. An async wrapper
// returns its promise at its first await, before the handler it wraps has run,
// so the handler's own check() came too late: every call failed "Did not
// check() all arguments" - while the handler went on running, so sign-up
// created the account and still answered "Internal server error".
//
// So such a wrapper hands the audit over: deferArgumentAudit() before its
// first await counts the arguments as seen by the outer audit, and
// applyAudited() runs the handler under an audit of its own, which the handler
// has to satisfy exactly as it would unwrapped. A wrapper that does not await
// first needs neither: it calls the handler at once and the audit sees it.
export function deferArgumentAudit(args) {
for (const arg of args) check(arg, Match.Any);
}
export function applyAudited(handler, context, args, description) {
if (typeof Package !== 'undefined' && Package['audit-argument-checks']) {
return Match._failIfArgumentsAreNotAllChecked(handler, context, args, description);
}
return handler.apply(context, args);
}