mirror of
https://github.com/wekan/wekan.git
synced 2026-11-12 14:45:00 -05:00
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 !
29 lines
1.4 KiB
JavaScript
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);
|
|
}
|