Skip to content

🚀 release(auth-microservice) [OTP]: promote the Center email-code login (CUSTOM_AUTH routes, passwordless provisioning, log redaction) + cognito-triggers package to PROD - #43

Closed
JuankCadavid wants to merge 15 commits into
main-authfrom
dev-auth
Closed

JuankCadavid wants to merge 15 commits into
main-authfrom
dev-auth

Conversation

@JuankCadavid

Copy link
Copy Markdown
Contributor

What goes to PROD

dev-auth = main-auth + 10 OTP commits (no other changes; 0 conflicts):

  • POST /auth/login/otp/start / POST /auth/login/otp/verify — Cognito CUSTOM_AUTH / CUSTOM_CHALLENGE, stable error codes on the wire (OtpHttpExceptionFilter), rotated session on CODE_MISMATCH, destination mask derived from the request (no enumeration tell).
  • PASSWORDLESS_DOMAINS provisioning: /auth/register creates users on listed domains without a temporary password (CONFIRMED) and skips the welcome email. Unset → behaviour identical to today.
  • LoggingInterceptor now redacts session / tokens / password-like keys in the response log line (also closes the pre-existing login/custom token exposure).
  • cognito-triggers/ package (source only — the Lambdas are deployed separately with SAM; see docs/auth/center-email-code-login/devops-lambdas.md in the PRMS repo).

Safety in PROD before the rest of the rollout

The OTP routes are additive and inert until (a) the PROD pool has the three triggers wired and (b) PRMS PROD sets OTP_ALLOWED_EMAIL_DOMAINS. Calling them earlier fails closed (CHALLENGE_NOT_SUPPORTED / UPSTREAM_ERROR), nothing else changes. Existing routes and tests untouched (17 suites / 380).

Env for PROD (DevOps)

  • Optional now, required before center users are registered: PASSWORDLESS_DOMAINS=cifor-icraf.org,icrisat.org.
  • Nothing else new; COGNITO_*, MS_NOTIFICATION_* unchanged.

Full PROD sequence: PRMS repo docs/auth/center-email-code-login/prod-rollout-runbook.md (this PR = its step 5, done early on purpose).

🤖 Generated with Claude Code

JuankCadavid and others added 15 commits September 11, 2026 14:35
… to CognitoService with stable error mapping

[SPEC:changes/cognito-email-otp-login] Cognito USER_AUTH + EMAIL_OTP: InitiateAuth (PREFERRED_CHALLENGE), gated SELECT_CHALLENGE round-trip, RespondToAuthChallenge EMAIL_OTP → tokens; pure mapCognitoError (CODE_MISMATCH, CODE_EXPIRED, ATTEMPTS_EXCEEDED, NOT_AUTHORIZED, CHALLENGE_NOT_SUPPORTED, UPSTREAM_ERROR); outcome-only logs. 22 tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…users without a temporary password so they land CONFIRMED

[SPEC:changes/cognito-email-otp-login] createUser omits TemporaryPassword (SUPPRESS, email_verified) for allow-listed domains and skips the welcome-password email; all other domains byte-identical. README env row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d auth/login/otp/verify routes with stable error codes on the wire

- EmailOtpStartDto / EmailOtpVerifyDto, thin AuthService delegates to CognitoService
- route-local OtpHttpExceptionFilter keeps { code, message } in error bodies
- LoggingInterceptor redacts session/tokens/code keys before the response log line (OTP-R-11)
- request-level supertest suite through the real global filter, pipe and interceptor
- README: endpoints, actual error body, 201, telemetry vocabulary

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
✨ feat(auth-microservice) [OTP]: email one-time-code login routes + passwordless provisioning for CGIAR center domains
…0 spec blocks into shared builders and it.each tables (Sonar new-code duplication 5.9% → ≤3%)

Tests only: 365 → 365 tests, runtime-counted assertions unchanged (cognito.service.spec 121 → 121, auth.service.spec 74 → 74); no production change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
♻️ refactor(auth-microservice) [OTP]: dedupe OTP spec blocks for the Sonar quality gate (tests only)
…gh Cognito CUSTOM_AUTH / CUSTOM_CHALLENGE

- start: InitiateAuth CUSTOM_AUTH (no PREFERRED_CHALLENGE, no SELECT_CHALLENGE round-trip), expects CUSTOM_CHALLENGE
- verify: RespondToAuthChallenge CUSTOM_CHALLENGE with ANSWER; a wrong code returns 401 CODE_MISMATCH carrying the rotated session; NotAuthorized mapping → ATTEMPTS_EXCEEDED / CODE_EXPIRED / NOT_AUTHORIZED; missing Session → CHALLENGE_NOT_SUPPORTED; empty AuthenticationResult → UPSTREAM_ERROR
- Swagger and README contract updated; request-level hygiene test on the 401-with-session path

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…gers package (Define / Create / Verify) with the PRMS-branded code email

- DefineAuthChallenge: one CUSTOM_CHALLENGE per session, tokens on a correct answer, failAuthentication after 3 misses, fake challenge for unknown users
- CreateAuthChallenge: crypto.randomInt 6-digit code, reuse across retries via challengeMetadata, masked destination, email emitted to the notification queue with the auth envelope (from PRMS-No-reply, name "PRMS Reporting Tool"), queue failure → email_failed but the challenge still returns
- VerifyAuthChallengeResponse: timingSafeEqual, always false for unknown users
- amqplib-only runtime dep; confirm channel + waitForConfirms; NestJS event envelope { pattern, data }; logs = allow-listed keys only
- SAM template (Node 22, Timeout 5 s, pool-scoped cognito-idp invoke permission) + README (deploy, pool wiring via before-export, troubleshooting)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
✨ feat(auth-microservice, cognito-triggers) [OTP rev 3]: CUSTOM_AUTH sign-in code sent by PRMS (do not merge before the pool triggers are wired)
… logo to 220 px (width attribute + inline style)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… ChallengeParameters.destination (CUSTOM_AUTH), keeping CODE_DELIVERY_DESTINATION as fallback

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
🔧 fix(auth-microservice, cognito-triggers) [OTP-T-14]: masked destination on CUSTOM_AUTH start + 220 px email logo
…nation mask from the submitted userName (design §13 m)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…on from the request username, never from Cognito's reply (design §13 m)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
🔧 fix(auth-microservice, cognito-triggers) [OTP pre-PROD]: destination mask derived from the request username (no unknown-user tell)
@sonarqubecloud

Copy link
Copy Markdown

@JuankCadavid

Copy link
Copy Markdown
Contributor Author

Superseded: PRMS owns the sign-in code lifecycle (spec cognito-email-otp-login rev 4, Option D) — the microservice OTP routes and passwordless provisioning are no longer needed in PROD. Keeping dev-auth as is; nothing to promote for this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant