Skip to content

Push notification and auth improvements#1049

Merged
Isti01 merged 3 commits into
stagingfrom
feature/push-notification-and-auth-improvements
Jul 9, 2026
Merged

Push notification and auth improvements#1049
Isti01 merged 3 commits into
stagingfrom
feature/push-notification-and-auth-improvements

Conversation

@Isti01

@Isti01 Isti01 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added new login security options to reject unverified email sign-ins and prevent account merging across different login providers.
    • Improved push notification delivery reliability with better retry handling and cleaner removal of invalid recipients.
  • Bug Fixes

    • QR code generation now validates input more strictly, including a maximum allowed size.
    • Login failures now return clearer messages and keep users on the login screen when an error occurs.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Isti01, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3aa26a48-10ac-4837-977a-6b194f18f65a

📥 Commits

Reviewing files that changed from the base of the PR and between ae53d64 and bac5d01.

📒 Files selected for processing (10)
  • backend/build.gradle.kts
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginComponent.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginRejectedException.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginService.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/keycloak/KeycloakUserInfoResponse.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/FirebaseMessagingConfiguration.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationService.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationServiceCredentials.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/EntrypointController.kt
📝 Walkthrough

Walkthrough

The pull request adds SSO login security controls, refactors Firebase notification delivery around cached OAuth credentials and reactive retries, bounds QR image sizes, and updates backend dependencies.

Changes

SSO security controls

Layer / File(s) Summary
SSO settings and rejection contract
backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginComponent.kt, backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/keycloak/KeycloakUserInfoResponse.kt, backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginRejectedException.kt
Adds server-side SSO security settings, maps Keycloak email verification, and introduces a typed OAuth2 login rejection exception.
Provider login validation
backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginService.kt
Google and Keycloak login flows can reject unverified emails and cross-provider account merges.
OAuth2 failure routing
backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt, backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/EntrypointController.kt
OAuth2 failures are URL-encoded into redirects, and error-bearing requests render the authentication selection page without automatic provider redirection.

Push notification delivery

Layer / File(s) Summary
FCM credential acquisition
backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationServiceCredentials.kt
Parses service-account credentials, signs JWT assertions, fetches access tokens, and caches them until near expiry.
Reactive notification delivery
backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationService.kt
Uses bounded reactive concurrency, retries 5xx/429 responses, tracks send outcomes, removes stale tokens, and manages transaction scopes explicitly.

API and build updates

Layer / File(s) Summary
QR validation and dependencies
backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationApiController.kt, backend/build.gradle.kts
Rejects QR sizes above 2048 and updates Jackson, Mustache, and Google authentication dependencies.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant IdentityProvider
  participant LoginService
  participant SecurityConfig
  participant EntrypointController
  IdentityProvider->>LoginService: provide identity and email verification
  LoginService->>SecurityConfig: reject invalid login
  SecurityConfig->>EntrypointController: redirect with encoded error
  EntrypointController->>EntrypointController: render auth selection
Loading
sequenceDiagram
  participant PushNotificationService
  participant Credentials
  participant FCM
  participant TokenRepository
  PushNotificationService->>TokenRepository: fetch tokens
  PushNotificationService->>Credentials: get access token
  Credentials->>FCM: refresh OAuth token when needed
  PushNotificationService->>FCM: send notifications with retries
  FCM-->>PushNotificationService: delivery results
  PushNotificationService->>TokenRepository: delete stale tokens
Loading

Possibly related PRs

  • kir-dev/cmsch#1035: Both pull requests update the dependency set in backend/build.gradle.kts.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 matches the main themes of the changeset: push notifications and authentication improvements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/push-notification-and-auth-improvements

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.

@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmsch-cst Ready Ready Preview, Comment Jul 9, 2026 9:24pm
cmsch-felezobal Ready Ready Preview, Comment Jul 9, 2026 9:24pm
cmsch-golyakorte Ready Ready Preview, Comment Jul 9, 2026 9:24pm
cmsch-seniortabor Ready Ready Preview, Comment Jul 9, 2026 9:24pm
cmsch-skktv Ready Ready Preview, Comment Jul 9, 2026 9:24pm
cmsch-snyt Ready Ready Preview, Comment Jul 9, 2026 9:24pm
cmsch-vitorlaskupa Ready Ready Preview, Comment Jul 9, 2026 9:24pm

Request Review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationServiceCredentials.kt (1)

40-50: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Inconsistent null handling and a redundant "".let wrapper.

project_id fails fast via !!, but client_email and private_key use Any?.toString(), which silently yields the literal string "null" when the key is absent. A missing client_email would then be signed into the JWT iss and surface as an opaque token-endpoint rejection rather than a clear configuration error. The outer "".let { } is also a no-op.

♻️ Suggested refactor
-    private val key: ServiceAccountKey = "".let {
-        JsonMapper.builder().configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS, true).build()
-            .readValue<Map<String, Any>>(accountKey).let { node ->
-                ServiceAccountKey(
-                    projectId = node["project_id"]!!.toString(),
-                    clientEmail = node["client_email"].toString(),
-                    privateKey = node["private_key"].toString(),
-                    tokenUri = node["token_uri"]?.toString() ?: "https://oauth2.googleapis.com/token",
-                )
-            }
-    }
+    private val key: ServiceAccountKey =
+        JsonMapper.builder().configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS, true).build()
+            .readValue<Map<String, Any>>(accountKey).let { node ->
+                ServiceAccountKey(
+                    projectId = node["project_id"]?.toString() ?: error("Missing project_id in service account key"),
+                    clientEmail = node["client_email"]?.toString() ?: error("Missing client_email in service account key"),
+                    privateKey = node["private_key"]?.toString() ?: error("Missing private_key in service account key"),
+                    tokenUri = node["token_uri"]?.toString() ?: "https://oauth2.googleapis.com/token",
+                )
+            }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationServiceCredentials.kt`
around lines 40 - 50, The ServiceAccountKey parsing in
PushNotificationServiceCredentials should handle missing required fields
consistently and remove the redundant empty-string let wrapper. Update the
readValue<Map<String, Any>>(accountKey) mapping so projectId, clientEmail, and
privateKey all fail fast with a clear configuration error instead of relying on
Any?.toString() returning "null". Keep tokenUri defaulting as-is, and use the
existing ServiceAccountKey construction path to make the validation explicit and
easier to locate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginService.kt`:
- Around line 94-104: Add the same blank-email guard used in the Keycloak flow
to the Google login path in LoginService so email lookup only happens when
profile.email is not blank. Update the Google branch around the existing
profile.emailVerified / users.findByEmailIgnoreCase logic to skip the lookup and
merge checks for empty emails, keeping behavior consistent with the Keycloak
flow and avoiding accidental matches on blank-email accounts.

---

Nitpick comments:
In
`@backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationServiceCredentials.kt`:
- Around line 40-50: The ServiceAccountKey parsing in
PushNotificationServiceCredentials should handle missing required fields
consistently and remove the redundant empty-string let wrapper. Update the
readValue<Map<String, Any>>(accountKey) mapping so projectId, clientEmail, and
privateKey all fail fast with a clear configuration error instead of relying on
Any?.toString() returning "null". Keep tokenUri defaulting as-is, and use the
existing ServiceAccountKey construction path to make the validation explicit and
easier to locate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3c30336d-8c4b-4b72-8d70-e103ba436ef6

📥 Commits

Reviewing files that changed from the base of the PR and between 4918879 and ae53d64.

📒 Files selected for processing (11)
  • backend/build.gradle.kts
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/app/ApplicationApiController.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginComponent.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginRejectedException.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/LoginService.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/keycloak/KeycloakUserInfoResponse.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/FirebaseMessagingConfiguration.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationService.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/PushNotificationServiceCredentials.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt
  • backend/src/main/kotlin/hu/bme/sch/cmsch/controller/admin/EntrypointController.kt
💤 Files with no reviewable changes (2)
  • backend/build.gradle.kts
  • backend/src/main/kotlin/hu/bme/sch/cmsch/component/pushnotification/FirebaseMessagingConfiguration.kt

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