Uh oh!
There was an error while loading. Please reload this page.
test(dogfood): converge two-factor-lockout on the shared TOTP helper - #11323
Merged
Conversation
`two-factor-lockout.dogfood.test.ts` carried a private `base32Decode` / `totp` pair, byte-for-byte identical to the ones in `test/totp.ts` — the shared module was extracted FROM this file (#10681) without rewriting its internals, so the package held two spellings of RFC 6238. Point the file at `./totp.js`, delete both local functions, and collapse the inline otpauth:// parsing into `secretFromTotpUri`. Mechanical: no assertion, timeout or fixture-semantics changes. The hand-rolled rationale (`@better-auth/utils/otp` is a transitive dependency; taking a direct one to make six digits would tie these fixtures to an internal package's resolution) already lives in the shared module's header, so it survives. That header's stale "the lockout file still carries its own copy" warning is replaced by the fact that this is now the package's single copy. Verified the file really drives the shared helper rather than merely importing it: mutating the shared `totp()` to return a fixed wrong code turns the suite red in `beforeAll` (enrolment confirmation, 401 INVALID_CODE vs the expected 200); restoring it byte-identically returns it to 5 passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01APWX2AwT3a4xDcjPCe8bk4
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 2 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-sam
marked this pull request as ready for review
August 23, 2026 11:38
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#11111
two-factor-lockout.dogfood.test.tscarried a privatebase32Decode/totppair. The sharedpackages/qa/dogfood/test/totp.tswas extracted from that file while adding a second caller (#10681) and deliberately did not rewrite its internals, so the package held two spellings of RFC 6238. This converges them. Mechanical: no assertion, timeout or fixture-semantics changes.What changed
secretFromTotpUri, totpfrom./totp.js— the same import its siblingtwo-factor-backup-code-reveal.dogfood.test.tsalready uses.base32Decodeandtotpare deleted, along with thecreateHmacimport that only they used.secretFromTotpUri.Net: 48 lines deleted, 7 added.
Divergence check — the thing that could have made this unsafe
Both implementations were compared before anything was touched. Extracting the function bodies and diffing them yields exactly one difference each, the
exportkeyword:No divergence. Nothing behavioural is being smuggled in under a dedupe.
The one semantic nuance, stated rather than hidden
The collapsed block previously guarded the URI with
expect(uriSecret, 'no secret in the otpauth URI').toBeTruthy().secretFromTotpUriinstead throwsError('no secret in the otpauth URI')— same message, same red/green outcome, a thrown error rather than an assertion. The card sanctions this collapse explicitly ("plus thesecretparam lookup and itstoBeTruthyguard, so that block can collapse too").Why the green suite here is not a tautology
A dedupe PR's real risk is not that the suite goes red — it is that the suite never exercised the helper, so repointing it at a different implementation proves nothing. Predicted in writing before running: mutating the SHARED
totp()must fail insidebeforeAll, at the enrolment confirmation, because that is the first consumer of a TOTP in the file.Measured, with the shared
totp()mutated to return a fixed wrong code:Restored byte-identically —
git hash-objectequal on both sides (f5b906f55752e74ae4ba5c4be2d67891b621cbc9), injected marker absent, original line back — and re-run to a real green:Test Files 1 passed (1) / Tests 5 passed (5). The mutation ran under atrap ... EXIT INT TERMrestore, so a cap kill mid-mutation could not have left the tree mutated.Two honest deviations from the prediction: the rejection status is 401 INVALID_CODE, not the 400 I guessed, and vitest accounts a
beforeAllfailure as 1 file failed / 5 skipped rather than 5 failed. Location and cause matched the prediction.Pre-change the same mutation could not have moved this file at all — it referenced
./totp.jsnowhere, which is the contrast that makes the ablation a statement about the new wiring.No dist preflight applies:
test/totp.tsis a relative sibling module compiled from source by vitest, and@objectstack/dogfooddeclares nobuildscript.Verification
Baseline on the same ref, before the change:
Test Files 1 passed (1) / Tests 5 passed (5). After the change: identical.Gate union derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no hand-supplied paths) and run at commit3c6028f1b2. 11 matched + 7 convention-triggered families, every one exit 0:check:empty-state·check:liveness·check:published-files·check:slot-lookup·check:strictness-ledger·check:test-source-alias·check:type-source-resolution·check:variant-docs·check-ci-filter-parity·check-plugin-teardown-shape·check-affected-docs·check:query-options-erasure·check:type-check-coverage·check:type-check-debt·check:engine-double-contract·check:cross-package-test-inputs·check:where-matcher·check:nul-bytes·@objectstack/dogfood typecheckcheck:type-check-debtfirst refused withPREREQUISITE NOT MET—@objectstack/service-knowledgehad no built type entry point, and the gate is explicit that measuring from there measures a different world. That is NOT MEASURED, not a pass, so the closure was built and the gate re-run to its own verdict line:Changeset
skip-changeset.@objectstack/dogfoodis"private": trueand this PR touches only two of its test files, so it publishes nothing — the textbook case the changeset workflow's own comments name.Generated by Claude Code
Generated by Claude Code