Neilk1021 opened a new pull request, #7563: URL: https://github.com/apache/texera/pull/7563
### What `"user".avatar` holds only the last path segment of Google's `picture` claim, and the frontend rebuilds `https://lh3.googleusercontent.com/a/<fragment>` around it. Migration 33 renamed the column from `google_avatar` but deliberately kept every value as-is, so the *value* is still Google-only: no other identity provider can be represented in it. This stores the complete URL the provider supplied, and takes the Google-specific naming off the wire along with it. ### Changes **Avatar value** - New `common/util/AvatarUtil`: keeps an avatar only when it is an `http(s)` URL on an allowlisted host (`googleusercontent.com` today), and drops anything else rather than failing the login. Storing a provider-chosen URL is what makes this necessary — the old fragment-plus-hardcoded-host scheme gave that guarantee implicitly. - `GoogleAuthResource.profileOf` keeps `picture` whole instead of `_.split("/").lastOption`. - `ExternalProfile.avatar` becomes `Option[String]`, so "no avatar we would store" is one case that leaves the column alone. Previously a payload without `picture` overwrote a stored avatar with `""`. - `sql/updates/35.sql` widens the column to `VARCHAR(512)`, normalizes `''` to `NULL`, and promotes existing fragments to absolute URLs. Idempotent via a `NOT LIKE 'http%'` guard. - The frontend fetches the stored URL verbatim; `getAvatar`'s argument and cache key are the URL. **Naming** - The JWT claim `googleAvatar` is now `avatar`. Tokens live for `auth.jwt.expiration-in-minutes` (a week by default), so both `JwtParser` and `auth.service.ts` read the new name and fall back to the old one — otherwise every already-signed-in user loses their avatar until their token is reissued. Both fallbacks are commented as deletable once pre-rename tokens have expired, and are pinned by tests. - The same rename lands on the DTO fields that carry the value to the browser (`UserInfo.avatar`, `WorkflowExecutionEntry.avatar`, `DashboardWorkflowComputingUnit.ownerAvatar`), the matching TS types, and `UserAvatarComponent`'s `@Input`. ### Note for reviewers The JSON keys on `/admin/user/list`, the dashboard user-info map, execution history, and the computing-unit responses change name. Those are consumed only by this frontend, which moves in the same commit — but if anything outside this repo reads those payloads, that rename is the breaking part, not the JWT claim. Adding a second provider now needs nothing here beyond its own `ExternalProfile` mapping and one line in the host allowlist. ### Testing - `sbt scalafmtCheckAll "scalafixAll --check" Test/compile Util/test Auth/test` — clean; `Util/test` 24, `Auth/test` 99. - `WorkflowExecutionService/testOnly *GoogleAuthResourceSpec *ExternalAuthProvisionerSpec *AuthResourceSpec *AdminUserResourceSpec *WorkflowExecutionsResourceSpec *DashboardResourceSpec` — 116 tests, 0 failures. `ComputingUnitManagingService/test` — 91, 0 failures. - New coverage: `AvatarUtilSpec` (allowlist, subdomains, lookalike hosts, non-`http(s)` schemes, blank/absent); avatar cases in `GoogleAuthResourceSpec` (full URL stored, rotation, absent picture, keep-on-absent, disallowed host) and `ExternalAuthProvisionerSpec` (`None` leaves a stored avatar alone); claim back-compat in `JwtParserSpec` and `auth.service.spec.ts`. - Frontend: `yarn ng test` — 201 files / 4419 tests, 0 failures; `yarn format:ci` clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
