feat: add Keycloak auth adapter for Google SSO - #3
Open
ChakshuGautam wants to merge 440 commits into
Open
Conversation
Pgr data loader
Pgr data loader
Removed the unnecessary tenant config copy from statea
Pgr data loader
…nce employee onboarding template generation - Changed phase 2 description from "Common Master Data Upload" to "BOUNDARY MANAGEMENT WORKFLOW" in DataLoader.ipynb. - Updated phase completion messages to reflect correct phase numbers in DataLoader.ipynb. - Removed redundant validation layers section in 3_EmployeeOnboarding.ipynb. - Enhanced dynamic employee template generation process in 3_EmployeeOnboarding.ipynb with clearer output and error handling. - Improved UI layout and visibility toggles for tenant selection in 1_TenantAndCommonMaster.ipynb.
…to streamline content
Adds 12 E2E tests across 5 spec files with page objects: - employee-login: form render, login+redirect, session storage, bad creds, API auth - pgr-inbox: render, data/empty state, no raw SERVICEDEFS keys - employee-logout: clears session, redirects - citizen-flow: language page, continue navigation - console-errors: no uncaught JS errors across employee flow Also updates: - nginx config: KC reverse proxy + inbox API route - globalConfigs.js: KC auth provider settings - CI workflow: Playwright install + run steps - docker-compose: updated digit-ui image tag Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These source files are required for the webpack build which resolves @egovernments/digit-ui-libraries and @egovernments/digit-ui-react-components via resolve.alias to local source paths. Without them, Docker builds from a fresh clone fail with Module not found errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two-part document covering the complete KC integration: - Part 1: Technical spec (architecture, auth flows, components, multi-tenancy) - Part 2: Gap analysis with 20 findings across security, scalability, reliability, operability, and correctness (3 critical, 7 high, 9 medium, 1 low) All claims validated against source code (28 checks, 3 corrections applied). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NestJS + Fastify + Bun rewrite resolving all 20 gaps: - Module structure, gap-to-module mapping, bootstrap config - 54 unit tests + 11 E2E tests covering every gap - Dragonfly replaces Redis, docker-compose v2 with replicas - KC realm config changes (audience mapper, disable ROPC for browser) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 tasks covering NestJS + Fastify + Bun rewrite: - Project scaffolding + Zod config validation - Cache module (Dragonfly + LRU fallback) - Circuit breaker, Auth (JWT + audience), Metrics, Health modules - DIGIT client (random passwords, mobile retry, user type) - User resolver (realm-namespaced userName, staleness, role sync) - Proxy + Login BFF controller - KC admin with retry-backoff - Docker + realm config + frontend adapter update - Full test suite (54 unit + 12 E2E) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add esbuild.dev.js (live-reload dev server on port 18080) - Switch esbuild to IIFE format (fixes ESM module ordering crash) - Add process shim to index.html (fixes "process is not defined") - Fix globalConfigs.js path in dev server - Fix missing exports: ArrowRight, MdmsService - Remove unused imports: start (date-fns), APPLY_FILTER - Add react-responsive + esbuild deps to package.json - Fix E2E logout test (sidebar navigation) - Fix E2E inbox test (lenient assertions for async content) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace direct Keycloak ROPC token call with a JSON POST to the token-exchange-svc BFF, which handles KC authentication and DIGIT user enrichment server-side. The BFF does not return a refresh_token so null is passed to _setTokens. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…in endpoint" This reverts commit 3c9a5b3.
…gin endpoint" This reverts commit 2fb150d.
Non-critical 400 errors from DIGIT API (role sync, boundary lookups) are expected and don't indicate JS bugs. Filter them like other known benign errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 tests validating every frontend API route works through v2 proxy: 1. All employee flow APIs return valid responses (11 unique endpoints captured) 2. All API calls carry JWT — no 401s after login 3. Each critical API individually tested with JWT (MDMS, localization, access control, PGR, boundary, HRMS, workflow) 4. KC OIDC endpoints accessible (not blocked by proxy) 5. Citizen flow APIs work without authentication Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Catches all 4 SSO misconfigurations we hit in production: - redirect_uri not in KC client - deployment domain not in web origins - KC frontendUrl pointing to wrong domain - Google client secret mismatch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Frontend calls /egov-user-event/v1/events/notifications/_count for notification badges. This service was missing from Kong's route map, causing 404. Added as user-event-service route. Also added citizen-proxy test and Google SSO config tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The KC silent-check-sso iframe can hang indefinitely when: - Third-party cookies are blocked (Safari, Firefox strict mode) - KC session iframe CORS fails - Network issues with the KC OIDC endpoints Without a timeout, await initAuthAdapter() blocks forever and ReactDOM.render() never runs — resulting in a blank white page. Added 15-second Promise.race timeout. If SSO check doesn't complete in time, the app renders without SSO state (user sees login page). Also added debug logs throughout the citizen flow: - bootstrap, initAuthAdapter, DigitAppWrapper, DigitApp routing, CitizenApp, EmployeeApp setType guard Also fixed: - DigitApp default redirect respects userType (citizen → /citizen) - EmployeeApp skips setType for CITIZEN users - DigitAppWrapper uses grounded-container for authenticated citizens Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tizenHomeCard Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix UserService.logout not a function: explicit import from User/index.js instead of ambiguous User (esbuild picked User.js which has no logout method) - Default citizen tenant to pg.citya (state-level pg has no boundaries) - Add key props to LogoutDialog children/footer arrays Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Store id_token in localStorage during SSO login. On logout, pass it as id_token_hint to KC's logout endpoint. KC skips the 'Do you want to log out?' confirmation when the hint is present. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
KC adapter stores citizen info as Citizen.user-info (not user-info). PGRInitialization couldn't find the citizen tenant, defaulted to state-level pg (no boundaries), causing empty location dropdown. Now checks both localStorage keys and falls back to Citizen.tenant-id. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PGRInitialization was only running for employee users (line 50: userType === 'employee'). Citizens need boundaryHierarchyOrder in SessionStorage for the complaint location dropdown. Without it, the dropdown renders empty because boundaryHierarchy=[] in the BoundaryComponent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Run usePGRInitialization for citizen users (was employee-only) - Fallback state-level tenant (pg) to city-level (pg.citya) since boundaries are seeded at city level - Read Citizen.user-info and Citizen.tenant-id for KC SSO users Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When keycloak-js init({onLoad:"check-sso"}) fails or times out (e.g.,
third-party cookies blocked, network issues), the app had no fallback
and showed the login page even though valid tokens were in localStorage.
Now the bootstrap reads Citizen.token/Citizen.user-info from localStorage
and populates SessionStorage, allowing the citizen PGR flow to work
without an active KC SSO session.
Also fixed BoundaryService.js to read Citizen.user-info and fallback
to city-level tenant (same fix as PGRInitialization).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Walks through the full complaint creation flow (type → map → landmark → location) and validates that boundary APIs return data through the proxy. Catches regressions in tenant ID rewriting for boundary-relationships and hierarchy-definition endpoints. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…root dropdown - Cloned @egovernments/digit-ui-components v0.2.3 source from DIGIT-UI-LIBRARIES repo (commit aa8b1b442b) into micro-ui-internals/packages/digit-ui-components/ - Fixed BoundaryFilter.js: root-level City dropdown used variant="nesteddropdown" which filters out flat options (no nested `options` arrays). Changed to variant="dropdown" for the root boundary type. - Updated esbuild.dev.js to resolve digit-ui-components from local source for HMR - Added stub exports for icons/hooks referenced by other packages but not in v0.2.3 - Updated ComplaintsLocation.js levelConfig defaults to match actual hierarchy (City/Locality instead of region/zone) - Updated citizen-pgr-complaint E2E test to verify City dropdown has options - Minor fixes: PGRInbox structuredClone, persister geoLocation defaults Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove digit-ui-components, react-components, and libraries source from git tracking. These are upstream packages from egovernments/ DIGIT-UI-LIBRARIES and should be contributed back via separate PRs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8 tasks
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 free
to 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.
Summary
AUTH_PROVIDER=keycloakinglobalConfigs.js— when not set, the existing DIGIT auth flow is used unchangedArchitecture
Files Changed
auth/AuthAdapter.jsauth/DigitAuthAdapter.jsauth/KeycloakAuthAdapter.jsauth/index.jsRequest.jsUser/index.jsPrivateRoute.jscore/App.jsLogin/index.jspublic/index.htmlsrc/App.jssrc/index.jswebpack.config.jsdocker/DockerfileKey Design Decisions
<script>tag rather than npm import to avoid bundling issues with the monorepo's complex dependency tree<Switch>only matches direct<Route>children; using<>...</>breaks route matchingConfiguration Required
In
globalConfigs.js:Test plan
AUTH_PROVIDERset: verify existing DIGIT OTP login works unchangedAUTH_PROVIDER=keycloak: verify Google SSO login redirects correctly🤖 Generated with Claude Code