Skip to content
Aabha AI Academy

Stage 6 · L26

Design local users, registration and credential verification

Core · original Session 6

Registration creates a new inactive customer identity with a server-owned UUID, hashed password and customer role. The caller cannot request admin role through extra JSON. Existing stage-02 customer profiles acquire inactive status and a nullable password hash in migration0003; the migration does not invent passwords or activate old profiles.

The service creates a verification action token with its own token_use, expiry and credential version. The private CaptureMailbox records a fixture message after commit. It performs no network request and has no public mailbox endpoint. Tests read those in-process synthetic messages to exercise verification; this is not proof of mailbox ownership, deliverability or a Resend integration.

Verification checks signature, issuer/audience/purpose/expiry and the current stored version, locks the user row, then changes active and verified_at once. The version increment makes the same action token unusable again. A valid access token is not accepted as a verification token. The tests prove the inactive account cannot log in, successful verification permits it, and replay is400.

Reset request returns the same accepted202 shape for known and unknown email. A known active account gets a reset-purpose fixture token. The independent task changes the password inside one locked transaction and increments credential_version. Old access tokens and reset replays must then fail; the new password must log in and the old password must fail.

Sending mail after committing creates a delivery gap if a real adapter fails. A durable outbox can coordinate committed state and later delivery, but it is not implemented here. Production delivery, anti-abuse limits, retry policy and retention/deletion decisions require their own approved design. The site's existing Resend configuration is preserved and is not read or altered by these course checks.

Register synthetic inactive identity; Capture opaque verification value; Submit value in the same process; One verification activates identity
Register synthetic inactive identity; Capture opaque verification value; Submit value in the same process; One verification activates identity

Follow the running code

Focused lesson example; see the end-of-stage capstone for the cumulative app · stage 06

with TestClient(app) as client:
    created = client.post('/auth/register', json={'email': email, 'password': password})
    assert created.status_code == 201 and not created.json()['active']
    action = app.state.mailbox.messages[-1]['token']
    assert client.post('/auth/verify', json={'token': action}).status_code == 200

Predict and observe this focused example using the concepts explained above. Its boundary is stated in the focused answer.

Guided lab

  1. Read the explanation and predict the focused example’s outcome.
  2. Run the documented same-process walkthrough through --until verify. Explain why another Uvicorn process cannot retrieve this private capture list.
  3. Compare the observed outcome with the focused answer and state its boundary.

From the extracted stage starter root, after completing its README setup:

python run_checks.py --stage 06 --role starter --walkthrough verify

Expected: The TestClient and app mailbox share one owned process, so the synthetic captured token can be submitted to verify without an inbox endpoint. Registration is inactive until that succeeds. Another process owns a different memory list. Treat the action value as opaque here; its signature/claims are taught in L27. URL-encoded username=email/password is the login input contract.

  • A captured message is not real delivery; a post-commit adapter failure needs a delivery design; role is never caller-controlled.

Focused exercise and answer

Complete this focused exercise before reading its answer. The full native transfer is introduced only at the end of the stage.

Your transfer task: Run the documented same-process walkthrough through --until verify. Explain why another Uvicorn process cannot retrieve this private capture list.

  1. Run the documented same-process walkthrough through --until verify. Explain why another Uvicorn process cannot retrieve this private capture list.
Inspect the matching answer

This answer addresses the focused exercise above; the cumulative implementation is shown only after the stage prerequisites.

The TestClient and app mailbox share one owned process, so the synthetic captured token can be submitted to verify without an inbox endpoint. Registration is inactive until that succeeds. Another process owns a different memory list. Treat the action value as opaque here; its signature/claims are taught in L27. URL-encoded username=email/password is the login input contract.

Check your reasoning

What does the captured-mail test actually prove?

Show the explanation

Application token/state integration using a private fixture. It does not prove an email was delivered or a person controls an inbox.

Reading progress

54 lessons remain open to guests. Marking a lesson read records reading only; it does not award assessment credit or a certificate.

Device reading marks require browser storage. Reading is always available.

Sign in or create an account to save separate account progress. Your current page is kept.