Nobody has started this yet — be first.
Business impact
Right now, a user's only way to get a fresh set of backup codes is to fully disable and re-enable 2FA -- a clunky, alarming flow. Support gets tickets from users who have used most of their codes, or suspect one leaked, and want to rotate them without touching whether 2FA is on at all. This is a standard capability in any product with recovery codes (GitHub, Google, etc. all offer "regenerate codes" as a first-class action).
Problem
The route POST /auth/2fa/backup-codes/regenerate is registered and reachable, but is a placeholder that always returns {"error": "not implemented"}, 501 regardless of the caller.
Current behavior
regenerate_backup_codes()'s handler body is just return jsonify(error="not implemented"), 501 -- it never touches the database or totp_lib at all.
Expected behavior
An authenticated user with 2FA already enabled can call this endpoint to invalidate every existing backup code and receive a brand new set, shown once in the response body -- without touching totp_enabled or totp_secret at all.
Steps to reproduce
Why this matters
This is a good exercise in reusing an existing building block (generate_backup_codes) correctly, and in getting the ordering right: the old codes must be gone from the database before (or atomically with) the new ones being issued, not just "new ones added alongside the old."
Suggested approach
Look at how confirm_2fa() calls totp_lib.generate_backup_codes() after 2FA is proven. This route needs the same call, but preceded by deleting the user's existing BackupCode rows (the same query shape disable_2fa() used to use -- see the disable-2fa ticket, a related but distinct gap in the same area of the code).
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_05.py -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
Sign in to create it automatically, or do it yourself:
$git checkout -b feat/regenerate-backup-codesFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/regenerate-backup-codesSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign inhttp://localhost:5000make seedpyotpmake docker-prod-upYou do not need Docker running at all to work the tickets -- the test suite uses an in-memory SQLite database (via StaticPool, an isolated DB per test function) and fakeredis (TestingConfig.USE_FAKE_REDIS), so everything runs against a plain virtualenv:
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pytest practice_tickets/tests/test_ticket_01.py -v # a single ticket
./practice_tickets/run_tickets.sh # all 15, clean pass/fail summary
All 15 tests fail at the start; as you fix each ticket in app/, its test (and only its test) should flip to passing. make test (pytest -q) runs the project's own main suite -- as of writing it shows 9 pre-existing failures caused by ticket bugs 02, 03, 07, 11, and 15; fixing those tickets fixes those failures too, not a separate task. Do not look at git diff / version control history to find the bugs if this repo is ever put under source control -- the point is to find them the way you would find a real bug: from a failing test and a description of broken behavior, not a diff.
Level 2
Implement a feature
Extend the system within its own patterns.