Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement OpenID Connect Authentication Strategy #2149

Merged
merged 3 commits into from
Jan 13, 2025

Conversation

AmruthPillai
Copy link
Owner

@AmruthPillai AmruthPillai commented Jan 13, 2025

Here's a quick demo of it working:

Screen.Recording.2025-01-13.at.3.46.26.PM.mov

To get started with OpenID configuration, just make sure to run the latest version of the image (v4.3.7) and add the following environment variables (also documented in the .env.example file):

# OpenID (Optional)
OPENID_AUTHORIZATION_URL=
OPENID_CALLBACK_URL=http://localhost:5173/api/auth/openid/callback
OPENID_CLIENT_ID=
OPENID_CLIENT_SECRET=
OPENID_ISSUER=
OPENID_TOKEN_URL=
OPENID_USER_INFO_URL=

You should have received these values from OpenID Servers such as Keycloak or Authentik.

Fixes #703.

Summary by CodeRabbit

  • New Features

    • Added OpenID authentication as a new login option
    • Introduced support for OpenID Connect authentication providers
  • Configuration

    • Added new optional environment variables for OpenID configuration
    • Updated configuration schemas to support OpenID authentication
  • Dependencies

    • Updated package dependencies to support OpenID authentication
    • Added type definitions for express-session and passport-openidconnect
  • Version

    • Bumped application version to 4.3.7

Copy link

coderabbitai bot commented Jan 13, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This pull request introduces comprehensive support for OpenID Connect (OIDC) authentication across the application. The implementation adds new environment variables, updates configuration schemas, extends the authentication strategy, and modifies client-side and server-side components to enable generic OIDC login. The changes allow self-hosted instances to integrate with identity providers like Keycloak or Authelia by configuring OpenID-specific parameters.

Changes

File Change Summary
.env.example Added OpenID configuration variables
apps/client/src/pages/auth/_components/social-auth.tsx Added OpenID authentication button
apps/server/src/auth/* Implemented OpenID strategy, guard, and controller methods
libs/dto/src/auth/providers.ts, libs/dto/src/user/user.ts Updated provider enums to include "openid"
package.json Added OpenID-related dependencies and updated version
Docker Compose files Added OpenID environment variable placeholders
Prisma schema Added "openid" to Provider enum

Sequence Diagram

sequenceDiagram
    participant User
    participant Client
    participant Server
    participant OpenIDProvider
    
    User->>Client: Click OpenID Login
    Client->>Server: Request OpenID Authentication
    Server->>OpenIDProvider: Redirect to Authorization
    OpenIDProvider->>User: Authentication Prompt
    User->>OpenIDProvider: Authenticate
    OpenIDProvider->>Server: Return Authentication Code
    Server->>OpenIDProvider: Request Token
    OpenIDProvider->>Server: Provide Token
    Server->>Server: Validate User
    Server->>Client: Return Authentication Token
    Client->>User: Log In Successful
Loading

Assessment against linked issues

Objective Addressed Explanation
Configure OIDC Client ID & Secret
Automatic user creation for new OIDC users
Support generic OIDC authentication domain

Possibly related PRs

Poem

🐰 Hop, hop, authentication's new dance!
OpenID joins our login's grand romance
With Keycloak's embrace and Authelia's might
Our users now login with pure delight
A rabbit's security, swift and bright! 🔐


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33cb3db and 227870a.

📒 Files selected for processing (4)
  • apps/server/src/auth/auth.service.ts (1 hunks)
  • apps/server/src/auth/strategy/github.strategy.ts (1 hunks)
  • apps/server/src/auth/strategy/google.strategy.ts (1 hunks)
  • apps/server/src/auth/strategy/openid.strategy.ts (1 hunks)

Finishing Touches

  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

apps/server/src/main.ts Fixed Show fixed Hide fixed
Copy link

nx-cloud bot commented Jan 13, 2025

View your CI Pipeline Execution ↗ for commit 227870a.

Command Status Duration Result
nx run-many -t build ✅ Succeeded 46s View ↗
nx run-many -t lint ✅ Succeeded 1m 16s View ↗

☁️ Nx Cloud last updated this comment at 2025-01-13 15:25:29 UTC

Copy link

@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

♻️ Duplicate comments (1)
apps/server/src/main.ts (1)

25-33: ⚠️ Potential issue

Critical security improvements needed for session configuration.

Several security concerns need to be addressed:

  1. Using ACCESS_TOKEN_SECRET for session secret is not recommended as it serves a different purpose
  2. Memory session store (default) is not suitable for production
  3. Missing essential security options:
    • Session expiry
    • Cookie same-site policy
    • Cookie max-age

Apply these security improvements:

 app.use(
   session({
     resave: false,
     saveUninitialized: false,
-    secret: configService.getOrThrow("ACCESS_TOKEN_SECRET"),
+    secret: configService.getOrThrow("SESSION_SECRET"), // Use a dedicated secret
+    store: new RedisStore({ // Or another production-ready session store
+      url: configService.get("REDIS_URL"),
+    }),
     cookie: {
       httpOnly: true,
       secure: process.env.NODE_ENV === "production",
+      sameSite: "lax",
+      maxAge: 24 * 60 * 60 * 1000, // 24 hours
     },
+    name: "sid", // Don't reveal technology stack
   }),
 );

Don't forget to:

  1. Add SESSION_SECRET to your environment variables
  2. Set up a production-ready session store (Redis recommended)
  3. Update the configuration schema to include new variables
🧹 Nitpick comments (4)
apps/server/src/auth/strategy/openid.strategy.ts (3)

57-71: Handle user creation errors more specifically

In the nested try-catch blocks, catching all errors and assuming the user already exists may mask other issues during user creation. It's better to catch specific errors related to user existence (e.g., unique constraint violations) and handle other exceptions appropriately.

Consider revising the error handling as follows:

          } catch (error) {
-            throw new BadRequestException(ErrorMessage.UserAlreadyExists);
+            if (/* check if error indicates user already exists */) {
+              throw new BadRequestException(ErrorMessage.UserAlreadyExists);
+            } else {
+              throw error;
+            }
          }

Replace the pseudo-code comment with actual error checking logic based on your application's error handling mechanisms.


60-60: Consider retrieving locale from the OpenID profile

Currently, the locale is hardcoded as "en-US". If the OpenID provider supplies locale information, consider using it to set the user's preferred locale.

You can modify the code to extract the locale:

           locale: "en-US",
+          // Assuming the profile contains locale information
+          // locale: profile._json.locale || "en-US",

Ensure to verify the actual path to the locale information in the profile object.


33-73: Simplify and improve error handling in the validate method

The validate method can be refactored to enhance readability and maintainability. Nested try-catch blocks can be flattened, and the logic for user lookup and creation can be made clearer.

Consider refactoring the method:

  • Use await with proper try-catch blocks for each asynchronous operation.
  • Separate user lookup and creation into distinct functions if appropriate.
  • Handle specific exceptions rather than using broad catches.

This refactor will make the code easier to understand and maintain.

apps/client/src/pages/auth/_components/social-auth.tsx (1)

36-47: Consider adding error handling and loading states.

While the OpenID button implementation follows the existing pattern, consider enhancing user experience with:

  • Loading state during authentication
  • Error handling for failed authentication attempts
  • Feedback for users when OpenID server is unreachable

Example implementation:

 {providers.includes("openid") && (
   <Button
     asChild
     size="lg"
+    disabled={isLoading}
     className="w-full !bg-[#dc2626] !text-white hover:!bg-[#dc2626]/80"
   >
     <a href="/api/auth/openid">
-      <Fingerprint className="mr-3 size-4" />
+      {isLoading ? (
+        <Spinner className="mr-3 size-4" />
+      ) : (
+        <Fingerprint className="mr-3 size-4" />
+      )}
       {t`OpenID`}
     </a>
   </Button>
 )}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f8f2fe and 33cb3db.

⛔ Files ignored due to path filters (52)
  • apps/client/src/locales/af-ZA/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/am-ET/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ar-SA/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/bg-BG/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/bn-BD/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ca-ES/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/cs-CZ/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/da-DK/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/de-DE/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/el-GR/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/en-US/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/es-ES/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/fa-IR/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/fi-FI/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/fr-FR/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/he-IL/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/hi-IN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/hu-HU/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/id-ID/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/it-IT/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ja-JP/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/km-KH/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/kn-IN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ko-KR/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/lt-LT/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/lv-LV/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ml-IN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/mr-IN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ms-MY/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ne-NP/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/nl-NL/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/no-NO/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/or-IN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/pl-PL/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/pt-BR/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/pt-PT/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ro-RO/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ru-RU/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/sk-SK/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/sq-AL/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/sr-SP/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/sv-SE/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/ta-IN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/te-IN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/th-TH/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/tr-TR/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/uk-UA/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/uz-UZ/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/vi-VN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/zh-CN/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • apps/client/src/locales/zh-TW/messages.po is excluded by !apps/client/src/locales/*/messages.po
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • .env.example (1 hunks)
  • apps/client/src/pages/auth/_components/social-auth.tsx (2 hunks)
  • apps/server/src/auth/auth.controller.ts (2 hunks)
  • apps/server/src/auth/auth.module.ts (2 hunks)
  • apps/server/src/auth/auth.service.ts (1 hunks)
  • apps/server/src/auth/guards/openid.guard.ts (1 hunks)
  • apps/server/src/auth/strategy/openid.strategy.ts (1 hunks)
  • apps/server/src/config/schema.ts (1 hunks)
  • apps/server/src/main.ts (2 hunks)
  • libs/dto/src/auth/providers.ts (1 hunks)
  • libs/dto/src/user/user.ts (1 hunks)
  • package.json (6 hunks)
  • tools/compose/nginx-proxy-manager.yml (1 hunks)
  • tools/compose/simple.yml (1 hunks)
  • tools/compose/swarm.yml (1 hunks)
  • tools/compose/traefik-secure.yml (1 hunks)
  • tools/compose/traefik.yml (1 hunks)
  • tools/prisma/migrations/20250113145008_add_openid_provider_to_enums/migration.sql (1 hunks)
  • tools/prisma/schema.prisma (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • tools/compose/nginx-proxy-manager.yml
  • tools/compose/traefik.yml
🔇 Additional comments (15)
apps/server/src/auth/guards/openid.guard.ts (1)

1-5: OpenIDGuard is correctly implemented

The OpenIDGuard class correctly extends AuthGuard with the "openid" strategy, enabling OpenID authentication in the application.

libs/dto/src/auth/providers.ts (1)

4-4: Added "openid" to authentication providers

The addition of "openid" to the authProvidersSchema correctly includes OpenID as a valid authentication provider.

libs/dto/src/user/user.ts (1)

29-29: LGTM! Provider enum updated correctly.

The addition of "openid" to the provider enum is consistent with the OpenID Connect implementation while maintaining backward compatibility.

apps/server/src/auth/auth.module.ts (1)

67-95: LGTM! OpenID strategy configuration is well-implemented.

The implementation follows the established pattern for OAuth providers and includes proper validation of all required OpenID configuration parameters with appropriate fallback to DummyStrategy.

apps/server/src/auth/auth.controller.ts (1)

151-166: LGTM! OpenID endpoints are properly implemented.

The OpenID authentication endpoints follow the established OAuth flow pattern, with proper guard usage and consistent error handling.

tools/prisma/migrations/20250113145008_add_openid_provider_to_enums/migration.sql (2)

1-2: LGTM! Migration is correctly implemented.

The migration properly adds the 'openid' value to the Provider enum using the correct PostgreSQL syntax.


Line range hint 73-79: Verify callback URL configuration security.

Ensure that the OpenID callback URL configuration is properly validated and matches the URL registered with the OpenID provider to prevent callback URL manipulation attacks.

Run this script to check the callback URL configuration:

✅ Verification successful

Callback URL configuration is properly secured

The implementation follows security best practices with environment-based configuration, URL validation through zod schema, and no dynamic manipulation of callback paths that could lead to callback URL manipulation attacks.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check OpenID callback URL configuration across the codebase
# Look for hardcoded callback URLs or dynamic URL construction

rg -g '!{*.md,*.json}' -i 'callback.*url|redirect.*url' 

Length of output: 3955

tools/prisma/schema.prisma (1)

14-14: LGTM! The Provider enum extension is correct.

The addition of 'openid' to the Provider enum is properly implemented and aligns with the existing authentication providers.

.env.example (2)

72-79: LGTM! OpenID configuration variables are well-structured.

The OpenID configuration section follows the established pattern and includes all necessary OIDC parameters.


75-76: Ensure secure handling of OpenID credentials.

The OPENID_CLIENT_ID and OPENID_CLIENT_SECRET are sensitive credentials. Ensure these are properly secured in production environments and never committed to version control.

✅ Verification successful

OpenID credential handling verified as secure

The codebase demonstrates secure handling of OpenID credentials:

  • Credentials are properly externalized to environment variables
  • Configuration is validated through schema checks
  • No hardcoded credentials found in any files
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if any OpenID credentials are accidentally committed
rg -g '!.env.example' "OPENID_(CLIENT_ID|CLIENT_SECRET)=[^$]"

Length of output: 63


Script:

#!/bin/bash
# Search for any environment or configuration files
fd -t f "^\.env" -X echo "=== {} ===" -X cat {}

# Search for any potential credential patterns with different cases
rg -i "openid.*client.*(?:id|secret).*=" --type-not example

# Look for how these credentials are used in the code
ast-grep --pattern 'process.env.OPENID_$_'

Length of output: 325


Script:

#!/bin/bash
# List all .env files
echo "=== Environment Files ==="
fd "^\.env"

# Search for OpenID credentials in all files except .env.example
echo -e "\n=== Credential Patterns ==="
rg -i "openid.*client" -g "!.env.example"

# Look for environment variable usage
echo -e "\n=== Credential Usage ==="
rg "OPENID_CLIENT" -g "!.env.example"

Length of output: 2788

tools/compose/simple.yml (1)

109-117: LGTM! OpenID configuration in simple deployment is correct.

The OpenID environment variables are properly configured for the simple deployment scenario, with the correct callback URL port (3000) matching the container's exposed port.

tools/compose/traefik-secure.yml (1)

118-125: LGTM! OpenID configuration in secure deployment is correct.

The OpenID environment variables are properly configured for secure deployment:

  • Uses HTTPS protocol
  • Consistent with the domain configuration
  • Follows the same pattern as other OAuth providers
tools/compose/swarm.yml (1)

129-136: LGTM! OpenID configuration in swarm deployment is correct.

The OpenID environment variables are properly configured for swarm deployment:

  • Uses HTTPS protocol
  • Consistent with the domain configuration
  • Maintains consistency with other deployment configurations
package.json (2)

4-4: LGTM! OpenID Connect dependencies are properly configured.

The version bump and addition of OpenID Connect related dependencies align well with the PR objectives. The necessary packages for implementing OpenID Connect authentication are included:

  • express-session for session management
  • passport-openidconnect for the authentication strategy
  • Corresponding TypeScript type definitions

Also applies to: 65-65, 79-79, 196-196, 220-220


176-176: Verify the @tanstack/react-query update.

The update of @tanstack/react-query from ^5.64.0 to ^5.64.1 appears unrelated to the OpenID Connect implementation. Please ensure this update was intentional and verify its compatibility.

Run this script to check the changelog for any breaking changes:

✅ Verification successful

The @tanstack/react-query update to 5.64.1 is safe.

This patch update only adds TypeScript type improvements for query/mutation keys with no runtime changes. While unrelated to OpenID Connect, keeping dependencies up to date is good practice.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check @tanstack/react-query changelog for version 5.64.1
gh api repos/TanStack/query/releases | jq '.[] | select(.tag_name == "v5.64.1") | .body'

Length of output: 1105

apps/server/src/auth/strategy/openid.strategy.ts Outdated Show resolved Hide resolved
apps/server/src/auth/strategy/openid.strategy.ts Outdated Show resolved Hide resolved
apps/server/src/auth/strategy/openid.strategy.ts Outdated Show resolved Hide resolved
apps/server/src/config/schema.ts Show resolved Hide resolved
apps/server/src/auth/auth.service.ts Outdated Show resolved Hide resolved
@AmruthPillai AmruthPillai merged commit 21af624 into main Jan 13, 2025
2 of 3 checks passed
@AmruthPillai AmruthPillai deleted the feat/implement-openid-connect-strategy branch January 13, 2025 15:22
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.

[FEATURE] Generic OIDC login auth
1 participant