Skip to content

feat: Implement Crime IDAM Integration (#357)#435

Open
alexbottenberg wants to merge 15 commits intomasterfrom
feature/357-crime-idam-integration
Open

feat: Implement Crime IDAM Integration (#357)#435
alexbottenberg wants to merge 15 commits intomasterfrom
feature/357-crime-idam-integration

Conversation

@alexbottenberg
Copy link
Copy Markdown
Contributor

@alexbottenberg alexbottenberg commented Mar 10, 2026

Summary

Implements Crime IDAM as a third OAuth2 authentication provider alongside Azure AD SSO and CFT IDAM, enabling crime service users to authenticate using their Crime IDAM credentials.

Closes #357

Features Implemented

OAuth2 Authentication Flow

  • ✅ Authorization code flow with Crime IDAM OAuth2 endpoints
  • ✅ JWT token parsing and user info extraction
  • ✅ Session management with Passport.js
  • ✅ Secure token exchange and validation

New Routes

  • /crime-login - Initiates Crime IDAM OAuth2 flow
  • /crime-login/return - Handles OAuth2 callback
  • /crime-rejected - Displays rejection page for unauthorized roles

User Experience

  • ✅ "Sign in with Crime IDAM" option added to sign-in page
  • ✅ Full Welsh language support throughout authentication flow
  • ✅ Language preference preserved through OAuth redirect
  • ✅ Role-based access control with clear rejection messaging

Error Handling

  • ✅ Configuration validation (503 when not configured)
  • ✅ Missing authorization code handling
  • ✅ Token exchange failure handling
  • ✅ Database error handling
  • ✅ Session management error handling
  • ✅ Application Insights tracking for failures

Security

  • ✅ CSP configuration updated for Crime IDAM redirects
  • ✅ Environment variable-based configuration
  • ✅ JWT validation
  • ✅ Role validation with citizen/letter-holder rejection
  • ✅ Session regeneration before login

Technical Implementation

New Modules

  • libs/auth/src/config/crime-idam-config.ts - Configuration management
  • libs/auth/src/crime-idam/token-client.ts - OAuth2 token client
  • libs/auth/src/pages/crime-login/ - Login initiation controller
  • libs/auth/src/pages/crime-callback/ - OAuth2 callback handler
  • libs/auth/src/pages/crime-rejected/ - Rejection page (EN + CY)

Modified Components

  • Sign-in page - Added Crime IDAM radio option
  • Role service - Added isRejectedCrimeRole() function
  • Helmet middleware - Added Crime IDAM URL to CSP
  • App registration - Registered callback route

Testing

Unit Tests

  • ✅ 224 tests in auth module (all passing)
  • ✅ Configuration module: 11 tests
  • ✅ Token client: 19 tests
  • ✅ Role service: 18 tests
  • ✅ Page controllers: Full coverage with error scenarios
  • ✅ Welsh language selection: 5 tests

Test Coverage

  • ✅ >80% coverage on business logic
  • ✅ All error paths tested
  • ✅ Language switching verified
  • ✅ AAA pattern followed consistently

Manual Testing

  • ✅ App boots successfully with Crime IDAM enabled
  • ✅ Redirects to Crime IDAM authorization endpoint with correct parameters
  • ✅ Handles configuration absence gracefully (shows "not available" message)

Documentation

Updated Documentation

  • apps/web/.env.example - Added Crime IDAM environment variables
  • docs/GITHUB_SECRETS_SETUP.md - Added Crime IDAM secrets documentation
  • docs/tickets/357/ - Technical plan, tasks, and code review

Environment Variables Required

ENABLE_CRIME_IDAM=true
CRIME_IDAM_BASE_URL=<crime-idam-url>
CRIME_IDAM_CLIENT_ID=<client-id>
CRIME_IDAM_CLIENT_SECRET=<client-secret>
CRIME_IDAM_SCOPE=openid profile roles  # Optional, has default

Code Quality

  • ✅ TypeScript strict mode compliance
  • ✅ ES modules with .js extensions
  • ✅ WCAG 2.2 AA accessible templates
  • ✅ GOV.UK Design System components
  • ✅ Follows established CFT IDAM pattern
  • ✅ No circular dependencies
  • ✅ Biome linting passed

Accessibility

  • ✅ WCAG 2.2 AA compliant
  • ✅ GOV.UK components used correctly
  • ✅ Keyboard navigation supported
  • ✅ Screen reader compatible
  • ✅ Progressive enhancement (works without JavaScript)

Screenshots

Sign-In Page (English)

Crime IDAM option added as third authentication method

Crime Rejected Page (Welsh)

Full bilingual support for rejection flow

Deployment Notes

Prerequisites

  1. Crime IDAM OAuth2 application registered
  2. Redirect URI configured: {BASE_URL}/crime-login/return
  3. Environment variables set in Key Vault
  4. Crime IDAM base URL accessible from environment

Rollout Plan

  1. Configure environment variables in staging
  2. Test with real Crime IDAM credentials
  3. Verify OAuth2 flow end-to-end
  4. Deploy to production
  5. Monitor authentication success/failure rates

Follow-Up Tasks

  • E2E tests for complete Crime IDAM flow (requires test credentials)
  • Professional Welsh translation review
  • Monitoring/alerting for Crime IDAM authentication failures
  • Document Crime IDAM role requirements

Review Checklist

  • Code follows project standards
  • Tests passing (224 unit tests)
  • Documentation updated
  • Welsh translations provided
  • Accessibility verified
  • Security reviewed
  • Error handling comprehensive
  • No secrets in code

Review Report: Full code review available in docs/tickets/357/review.md

Technical Plan: Detailed implementation plan in docs/tickets/357/plan.md

Summary by CodeRabbit

  • New Features

    • Adds Crime IDAM as a third authentication provider: new sign‑in option, login initiation, OAuth callback flow, role‑rejection handling and user create/update on successful auth.
    • Adds a crime‑rejected page with English and Welsh content.
  • Documentation

    • Updates env example and GitHub secrets docs; adds integration plan and ticket documentation for Crime IDAM.
  • Tests

    • Expanded unit and flow tests for token handling, login/callback flows, role checks and security middleware.

Add Crime IDAM as third OAuth2 authentication provider alongside Azure AD SSO and CFT IDAM.

Features:
- OAuth2 authorization code flow with Crime IDAM
- New routes: /crime-login, /crime-login/return, /crime-rejected
- Role-based access control with rejection page
- Full Welsh language support
- Comprehensive error handling for all failure scenarios
- CSP configuration for Crime IDAM redirects
- Environment variable configuration

Implementation:
- Config module for Crime IDAM settings
- Token client for OAuth2 code exchange and JWT parsing
- Page controllers for login, callback, and rejection flows
- Updated sign-in page with Crime IDAM option
- 224 unit tests with full coverage

Documentation:
- Updated .env.example with Crime IDAM variables
- Added Crime IDAM secrets to GITHUB_SECRETS_SETUP.md
- Technical plan and review in docs/tickets/357/

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Crime IDAM as a third OAuth2 provider: new env/docs entries, config and token client, login/callback/rejected handlers with i18n and role validation, sign‑in option, helmet CSP update, auth exports and app wiring, and comprehensive tests for the new flows.

Changes

Cohort / File(s) Summary
Environment & Docs
apps/web/.env.example, docs/GITHUB_SECRETS_SETUP.md
Added example env vars and GitHub secrets/test credentials for Crime IDAM.
Auth: Configuration
libs/auth/src/config/crime-idam-config.ts, libs/auth/src/config/crime-idam-config.test.ts
New CrimeIdamConfig type, getCrimeIdamConfig() and isCrimeIdamConfigured() with defaults and unit tests.
Auth: Token Client
libs/auth/src/crime-idam/token-client.ts, libs/auth/src/crime-idam/token-client.test.ts
OAuth token exchange, JWT parsing, extractUserInfoFromToken, exported CrimeIdamUserInfo, and extensive tests.
Auth: Login & Callback
libs/auth/src/pages/crime-login/index.ts, libs/auth/src/pages/crime-login/index.test.ts, libs/auth/src/pages/crime-callback/index.ts, libs/auth/src/pages/crime-callback/index.test.ts
Login handler builds auth URL and stores locale/state; callback exchanges code, validates state/roles, upserts user, manages session and redirects; tests cover success and error paths.
Auth: Rejection Page & i18n
libs/auth/src/pages/crime-rejected/index.ts, .../index.test.ts, .../en.ts, .../cy.ts, .../index.njk
Added crime‑rejected page template with English/Welsh translations and tests.
Role Validation
libs/auth/src/role-service/index.ts, libs/auth/src/role-service/index.test.ts
Added isRejectedCrimeRole() with REJECTED_CRIME_ROLE_PATTERN and unit tests; exported from role service.
Auth Exports & App Wiring
libs/auth/src/index.ts, apps/web/src/app.ts, apps/web/src/app.test.ts
Re‑exports Crime IDAM config and callback handler; registered /crime-login/return route; passed crimeIdamUrl into helmet; app test mocks updated.
Public Pages: Sign‑in
libs/public-pages/src/pages/sign-in/en.ts, .../cy.ts, .../index.njk, .../index.ts, .../index.test.ts
Added "Crime IDAM" radio option and labels, POST handling to redirect to /crime-login preserving locale, and tests.
Security: Helmet CSP
libs/web-core/src/middleware/helmet/helmet-middleware.ts, .../helmet-middleware.test.ts
SecurityOptions gains optional crimeIdamUrl; formAction CSP includes Crime IDAM when provided; tests updated.
Planning & Tickets
docs/tickets/357/*
Added ticket, plan, review and tasks documenting design, acceptance criteria, tests and implementation notes for Crime IDAM integration.

Sequence Diagram(s)

sequenceDiagram
    participant User as User / Browser
    participant App as Application
    participant CrimeIDAM as Crime IDAM
    participant DB as Database

    User->>App: Click "Crime IDAM" login option
    App->>App: getCrimeIdamConfig()
    App-->>User: Redirect to Crime IDAM /oauth2/authorise (client_id, redirect_uri, scope, ui_locales)

    User->>CrimeIDAM: Authenticate
    CrimeIDAM-->>User: Redirect back with code to /crime-login/return

    User->>App: GET /crime-login/return?code=...
    App->>CrimeIDAM: POST /oauth2/token (code, client_id, client_secret, redirect_uri)
    CrimeIDAM-->>App: Returns access_token (+ id_token)

    App->>App: extractUserInfoFromToken()
    App->>App: isRejectedCrimeRole(roles)?
    alt rejected
        App-->>User: Redirect to /crime-rejected
    else accepted
        App->>DB: createOrUpdateUser(provenance: CRIME_IDAM)
        DB-->>App: confirm
        App->>App: regenerate session, login user
        App-->>User: Redirect to account-home (preserve lng)
    end
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: implementing Crime IDAM integration as a new OAuth2 authentication provider alongside existing providers.
Linked Issues check ✅ Passed All key requirements from issue #357 are met: OAuth2 flow implementation, endpoint configuration, token handling, user session management, role-based access control, error handling, and environment variable setup.
Out of Scope Changes check ✅ Passed All changes are directly aligned with Crime IDAM integration objectives. No unrelated modifications to existing authentication flows, database schemas, or unrelated features detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/357-crime-idam-integration
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 10, 2026

🎭 Playwright E2E Test Results

243 tests   243 ✅  24m 37s ⏱️
 34 suites    0 💤
  1 files      0 ❌

Results for commit 5b22a0e.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (6)
libs/auth/src/role-service/index.ts (1)

64-77: Keep a single rejected-role matcher.

This duplicates the CFT regex and matching logic already defined above. Reusing one helper keeps Crime and CFT rejection rules from drifting apart on the next policy change.

♻️ Suggested consolidation
 const REJECTED_ROLE_PATTERN = /^citizen(-.*)?$|^letter-holder$/;
+
+function hasRejectedRole(roles: string[]): boolean {
+  return roles.length > 0 && roles.some((role) => REJECTED_ROLE_PATTERN.test(role));
+}
 
 export function isRejectedCFTRole(roles: string[]): boolean {
-  if (!roles || roles.length === 0) {
-    return false;
-  }
-
-  return roles.some((role) => REJECTED_ROLE_PATTERN.test(role));
+  return hasRejectedRole(roles);
 }
-
-const REJECTED_CRIME_ROLE_PATTERN = /^citizen(-.*)?$|^letter-holder$/;
 
 /**
  * Checks if any of the provided Crime IDAM roles match the rejected role pattern
  * Rejected roles include: citizen, citizen-*, letter-holder
  * `@param` roles - Array of role strings to check
  * `@returns` true if any role matches the rejected pattern, false otherwise
  */
 export function isRejectedCrimeRole(roles: string[]): boolean {
-  if (!roles || roles.length === 0) {
-    return false;
-  }
-
-  return roles.some((role) => REJECTED_CRIME_ROLE_PATTERN.test(role));
+  return hasRejectedRole(roles);
 }

As per coding guidelines, "Follow YAGNI principle: Don't add speculative functionality. Take the simplest approach."

libs/auth/src/crime-idam/token-client.ts (2)

29-35: Consider adding a timeout to the fetch request.

The token exchange request has no timeout, which could cause the request to hang indefinitely if Crime IDAM is unresponsive. This could degrade user experience or exhaust connection resources.

Proposed fix using AbortController
 export async function exchangeCodeForToken(code: string, config: CrimeIdamConfig): Promise<TokenResponse> {
   const params = new URLSearchParams({
     client_id: config.clientId,
     client_secret: config.clientSecret,
     grant_type: "authorization_code",
     redirect_uri: config.redirectUri,
     code
   });

+  const controller = new AbortController();
+  const timeoutId = setTimeout(() => controller.abort(), 30000);
+
-  const response = await fetch(config.tokenEndpoint, {
+  const response = await fetch(config.tokenEndpoint, {
     method: "POST",
     headers: {
       "Content-Type": "application/x-www-form-urlencoded"
     },
-    body: params.toString()
+    body: params.toString(),
+    signal: controller.signal
   });
+
+  clearTimeout(timeoutId);

3-9: Consider exporting TokenResponse interface.

The TokenResponse interface is not exported but CrimeIdamUserInfo is. If consumers need to type token responses (e.g., for mocking in tests), they'd benefit from having this exported.

Proposed fix
-interface TokenResponse {
+export interface TokenResponse {
   access_token: string;
libs/auth/src/config/crime-idam-config.ts (1)

13-24: Consider extracting shared getConfigValue helper.

The getConfigValue function is duplicated across sso-config.ts, cft-idam-config.ts, and now crime-idam-config.ts. Consider extracting to a shared utility module to reduce duplication.

libs/auth/src/pages/crime-rejected/index.njk (1)

15-17: Sign-in link loses language selection.

The link to /sign-in doesn't preserve the user's language preference. Welsh users redirected here will lose their language selection when returning to sign in.

Proposed fix

Consider passing the locale to the template and appending it:

     <p class="govuk-body">
-      <a href="/sign-in" class="govuk-link">{{ t.returnToSignIn }}</a>
+      <a href="/sign-in?lng={{ locale }}" class="govuk-link">{{ t.returnToSignIn }}</a>
     </p>

This requires the controller to pass locale to the template context.

libs/auth/src/pages/crime-rejected/index.ts (1)

5-9: Consider passing locale to template and removing unnecessary async.

The handler doesn't await anything, so async is redundant. Additionally, the computed locale isn't passed to the template, which would be needed if the template wants to preserve language selection in links.

Proposed changes
-export const GET = async (req: Request, res: Response) => {
+export const GET = (req: Request, res: Response) => {
   const locale = (req.query.lng as string) || res.locals.locale || "en";
   const t = locale === "cy" ? cy : en;
-  res.render("crime-rejected/index", { en, cy, t });
+  res.render("crime-rejected/index", { en, cy, t, locale });
 };

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ef3476df-0f75-402b-9c10-b7fb07cb1a08

📥 Commits

Reviewing files that changed from the base of the PR and between d4377e3 and 7dfc896.

📒 Files selected for processing (30)
  • apps/web/.env.example
  • apps/web/src/app.ts
  • docs/GITHUB_SECRETS_SETUP.md
  • docs/tickets/357/plan.md
  • docs/tickets/357/review.md
  • docs/tickets/357/tasks.md
  • docs/tickets/357/ticket.md
  • libs/auth/src/config/crime-idam-config.test.ts
  • libs/auth/src/config/crime-idam-config.ts
  • libs/auth/src/crime-idam/token-client.test.ts
  • libs/auth/src/crime-idam/token-client.ts
  • libs/auth/src/index.ts
  • libs/auth/src/pages/crime-callback/index.test.ts
  • libs/auth/src/pages/crime-callback/index.ts
  • libs/auth/src/pages/crime-login/index.test.ts
  • libs/auth/src/pages/crime-login/index.ts
  • libs/auth/src/pages/crime-rejected/cy.ts
  • libs/auth/src/pages/crime-rejected/en.ts
  • libs/auth/src/pages/crime-rejected/index.njk
  • libs/auth/src/pages/crime-rejected/index.test.ts
  • libs/auth/src/pages/crime-rejected/index.ts
  • libs/auth/src/role-service/index.test.ts
  • libs/auth/src/role-service/index.ts
  • libs/public-pages/src/pages/sign-in/cy.ts
  • libs/public-pages/src/pages/sign-in/en.ts
  • libs/public-pages/src/pages/sign-in/index.njk
  • libs/public-pages/src/pages/sign-in/index.test.ts
  • libs/public-pages/src/pages/sign-in/index.ts
  • libs/web-core/src/middleware/helmet/helmet-middleware.test.ts
  • libs/web-core/src/middleware/helmet/helmet-middleware.ts

alexbottenberg and others added 4 commits March 11, 2026 09:33
- Fixed 17 failing tests in apps/web/src/app.test.ts
- Added missing crimeCallbackHandler export to auth mock
- All 61 web app tests now passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Changed email extraction to use claims.email first, then fall back to claims.sub
- The sub claim in OIDC is typically a UUID/GUID per spec, not an email address
- Storing sub as email would result in non-email values in the email field
- Added 3 tests to verify correct email claim priority:
  - Prioritizes email over sub when both present
  - Falls back to sub when email not present
  - Uses empty string when neither present

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Email address was being logged as a trackException property, which
would store it in Application Insights. Use only the opaque IDAM
sub-claim (userId) for error correlation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generate a random state on login, store it in session, and verify it
on callback to prevent CSRF attacks where a forged callback could sign
a victim into an attacker's account.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
libs/auth/src/pages/crime-callback/index.test.ts (1)

14-14: Consider typing mockSession more explicitly.

Using any bypasses TypeScript's type checking. A minimal type alias or Partial<Session> intersection would catch mismatches between the mock and actual Express session shape.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a4400384-9ae0-4fed-82de-0615073590b5

📥 Commits

Reviewing files that changed from the base of the PR and between 916bf23 and 078aca0.

📒 Files selected for processing (2)
  • libs/auth/src/pages/crime-callback/index.test.ts
  • libs/auth/src/pages/crime-callback/index.ts

alexbottenberg and others added 2 commits March 11, 2026 11:41
…etry

Strip email addresses, user IDs, display names, rejected roles, session IDs,
req.user, session internals, and raw errors from console output and
trackException properties.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lisions

userProvenanceId has a global unique constraint and is looked up without
a userProvenance filter. Prefixing with 'CRIME_IDAM:' ensures subject
IDs are unique per provider, preventing a collision from silently
updating the wrong user record.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
libs/auth/src/pages/crime-callback/index.ts (1)

105-108: ⚠️ Potential issue | 🟡 Minor

Avoid logging raw error objects.

The caught error may contain sensitive request or token data. Log a sanitised message instead.

Proposed fix
   } catch (error) {
-    console.error("Crime IDAM callback error:", error);
+    console.error("Crime IDAM callback error");
     const lng = req.session.lng || "en";
     return res.redirect(`/sign-in?error=auth_failed&lng=${lng}`);
   }
libs/auth/src/pages/crime-callback/index.test.ts (1)

234-237: ⚠️ Potential issue | 🟡 Minor

Test asserts PII in telemetry payload.

The assertion expects userId in trackException properties. If the implementation is corrected to remove PII, this test will fail. Update to match the sanitised payload.

Proposed fix
       expect(trackException).toHaveBeenCalledWith(dbError, {
-        area: "Crime IDAM callback",
-        userId: "user-123"
+        area: "Crime IDAM callback"
       });

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0ee177f8-dcd1-4b71-964e-f11f38bd83e3

📥 Commits

Reviewing files that changed from the base of the PR and between 078aca0 and 08852ed.

📒 Files selected for processing (4)
  • libs/auth/src/pages/crime-callback/index.test.ts
  • libs/auth/src/pages/crime-callback/index.ts
  • libs/auth/src/pages/crime-login/index.test.ts
  • libs/auth/src/pages/crime-login/index.ts

alexbottenberg and others added 8 commits March 11, 2026 11:57
Normalise roles to lowercase before regex matching so that variants
like 'Citizen' or 'CITIZEN' are correctly rejected regardless of how
Crime IDAM returns the role casing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix token endpoint path: Crime IDAM uses /idp/oauth2/access_token, not /oauth2/token
- Fix Prisma pg.Pool being created before dotenv loads DATABASE_URL by
  changing createApp to a dynamic import in server.ts so env vars are
  set before any module initialises its database connection
- Update all test fixtures to use the correct token endpoint path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers:
- Valid user sign-in journey (nightly - requires CRIME_IDAM credentials)
- crime-rejected page content, Welsh translation, and accessibility
- Callback error handling for missing code and invalid state
- Language parameter preserved through Crime IDAM redirect

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds ENABLE_CRIME_IDAM=true and required config env vars to the
playwright webServer command so the /crime-login route redirects
to Crime IDAM rather than returning 503, allowing the language
preservation test to verify ui_locales is passed correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Common Platform radio on the sign-in page now triggers Crime IDAM
authentication. The separate Crime IDAM radio option has been removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nt-home spec

- Fix sign-in.spec.ts: Common Platform test was asserting redirect to "/" (home
  page) instead of the Crime IDAM OAuth URL — copy-paste error from the CaTH
  account test
- Rewrite account-home.spec.ts: replace 20+ fragmented tests (many checking CSS
  properties) with a single @nightly journey test covering auth, content,
  accessibility, Welsh translation, and navigation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without scope=openid profile roles, CFT IDAM returns a JWT without the
uid claim. This causes claims.uid to be undefined, which propagates as
userProvenanceId: undefined to createOrUpdateUser. Prisma then attempts
to INSERT NULL into the non-nullable user_provenance_id column, throwing
a constraint violation and triggering the db_error redirect.

Mirrors the equivalent fix already applied to Crime IDAM (b8cddba).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

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.

Implement Crime IDAM Integration

1 participant