feat: enhance OIDC authentication documentation and add visual aids

- Updated the Auth0, Discord, GitHub, and Google authentication documentation to include detailed setup instructions and benefits of using each provider.
- Introduced ZoomableImage components for better visual representation of setup steps.
- Added troubleshooting sections for common issues encountered during authentication processes.
- Improved security best practices and next steps for users configuring OIDC providers.
- Included new images for various authentication providers to enhance user understanding.
- Updated translation files to support new icon picker features and improve localization.
This commit is contained in:
Daniel Luiz Alves
2025-07-04 00:47:23 -03:00
parent 1d2caa9e34
commit 82861d91e9
53 changed files with 1036 additions and 308 deletions

View File

@@ -3,10 +3,357 @@ title: Auth0
icon: Lock
---
## Auth0
import { ZoomableImage } from "@/components/ui/zoomable-image";
### Prerequisites
Auth0 is one of Palmr's officially supported OIDC providers, offering enterprise-grade authentication through Auth0's identity platform. This integration allows users to sign in to Palmr using Auth0's comprehensive authentication system, making it perfect for enterprise organizations, applications requiring advanced security features, and teams that need centralized identity management.
- Auth0 Application
- Auth0 OAuth Client ID and Secret
- Auth0 OAuth Redirect URI
<ZoomableImage src="/assets/v3/oidc/auth0/sign-in-with-auth0.png" alt="Sign in with Auth0" />
## Why use Auth0 authentication?
Auth0 authentication provides several advantages for enterprise and security-focused organizations:
- **Enterprise-grade security** - Advanced security features like MFA, adaptive authentication, and threat detection
- **Centralized identity management** - Single platform to manage users across multiple applications
- **Flexible authentication options** - Support for social logins, enterprise SSO, and custom databases
- **Compliance ready** - Built-in compliance with SOC 2, GDPR, HIPAA, and other standards
- **Advanced customization** - Rules, hooks, and custom branding capabilities
---
## Prerequisites
Before configuring Auth0 authentication, ensure you have:
- **Auth0 account** - Ability to create applications and manage tenants
- **Admin privileges in Palmr** - Required to configure OIDC settings
- **Domain configuration** - For production deployments with custom domains
> **Note:** Auth0 is pre-configured as an official provider in Palmr, which means the technical configuration is handled automatically. You only need to provide your OAuth credentials.
---
## Setting up Auth0 Application
### Creating an Auth0 application
To get started with Auth0 authentication, you'll need to create an application in your Auth0 Dashboard.
1. **Navigate to Auth0 Dashboard**: Go to [manage.auth0.com](https://manage.auth0.com)
<ZoomableImage src="/assets/v3/oidc/auth0/auth0-dashboard.png" alt="Auth0 Dashboard" />
2. **Create new application**: Click **"Applications"** in the left sidebar, then click **"+ Create Application"**
<ZoomableImage src="/assets/v3/oidc/auth0/create-application.png" alt="Auth0 Create Application" />
3. **Select application type**: Choose **"Single Page Application"** for web-based Palmr instances
<ZoomableImage
src="/assets/v3/oidc/auth0/application-type.png"
alt="Auth0 Application Type Selection"
legend="This is a fake application, you have to use your own."
/>
4. **Enter application details**:
- **Name**: Enter a descriptive name like "Palmr File Sharing"
- **Description**: Add a clear description of your Palmr instance
<ZoomableImage
src="/assets/v3/oidc/auth0/application-details.png"
alt="Auth0 Application Details"
legend="This is a fake application, you have to use your own."
/>
5. **Create application**: Click **"Create"** to generate your Auth0 application
### Configuring application settings
After creating your application, you'll need to configure the settings that Palmr will use.
1. **Configure allowed URLs**: In the **"Allowed Callback URLs"** field, add your Palmr callback URL:
**For production:**
```
https://yourdomain.com/api/auth/providers/auth0/callback
```
**For development:**
```
http://localhost:3000/api/auth/providers/auth0/callback
```
**For custom ports:**
```
https://yourdomain.com:5487/api/auth/providers/auth0/callback
```
<ZoomableImage
src="/assets/v3/oidc/auth0/callback-urls.png"
alt="Auth0 Callback URLs Configuration"
legend="This is a fake application, you have to use your own."
/>
2. **Configure additional URLs**:
- **Allowed Logout URLs**: Add your Palmr logout URL (e.g., `https://yourdomain.com`)
- **Allowed Web Origins**: Add your Palmr domain for CORS support
3. **Save changes**: Click **"Save Changes"** to apply your configuration
### Getting OAuth credentials
Now you'll get the credentials that Palmr will use to authenticate with Auth0.
1. **Copy Domain**: Note your Auth0 domain (e.g., `your-tenant.auth0.com`)
2. **Copy Client ID**: The Client ID is displayed in the **"Client ID"** field
3. **Generate Client Secret**: Click **"Show"** next to Client Secret to reveal it
<ZoomableImage
src="/assets/v3/oidc/auth0/oauth-credentials.png"
alt="Auth0 OAuth Credentials"
legend="The client ID and client secret shown in the image are examples only (fake credentials). You must use your own credentials from Auth0."
/>
4. **Save credentials**: Copy the **Domain**, **Client ID**, and **Client Secret** for later use
> **Important:** Replace `yourdomain.com` with your actual domain. You can add multiple callback URLs for different environments (development, staging, production).
---
## Configuring Palmr
### Accessing OIDC settings
To configure Auth0 authentication in Palmr, you need administrator access to the settings panel.
1. **Login as administrator**: Sign in to Palmr with an admin account
2. **Access settings**: Click your profile picture in the header and select **Settings**
3. **Navigate to authentication**: Find and click on the **Authentication Providers** configuration section
<ZoomableImage src="/assets/v3/oidc/auth-providers.png" alt="Palmr Authentication Providers" />
### Enabling Auth0 provider
Auth0 comes pre-configured as an official provider, so the setup process is streamlined.
1. **Locate Auth0 provider**: Find Auth0 in the list of available providers
2. **Enable the provider**: Toggle the status to **Enabled**
<ZoomableImage src="/assets/v3/oidc/auth0/palmr-enabled-auth0.png" alt="Palmr Auth0 Provider Enabled" />
After enabling the provider, click on the pen icon to configure the provider.
3. **Configure credentials**:
- **Domain**: Paste your Auth0 domain (e.g., `your-tenant.auth0.com`)
- **Client ID**: Paste the Client ID from Auth0 application
- **Client Secret**: Paste the Client Secret from Auth0 application
- **Scopes**: Add the scopes you want to use. The default scopes are `openid`, `profile`, and `email`.
<ZoomableImage
src="/assets/v3/oidc/auth0/edit-auth0.png"
alt="Edit Auth0 Provider"
legend="This is a fake application, you have to use your own."
/>
### Advanced configuration options
Configure additional settings to customize the authentication behavior:
**Auto Registration**: Enable this to automatically create user accounts when someone authenticates for the first time.
**Admin Email Domains**: Specify domains that should automatically receive admin privileges. For example, entering `yourcompany.com` will grant admin access to anyone with an email from that domain.
**Sort Order**: Control where the Auth0 login button appears relative to other authentication providers.
**Icon**: you can choose the icon you want to use for the Auth0 login button (default is `SiAuth0`).
<ZoomableImage src="/assets/v3/oidc/auth0/auth0-icon.png" alt="Auth0 Icon" />
> **Enterprise tip:** Auth0 authentication works great for enterprise organizations requiring advanced security features and centralized identity management.
---
## Account linking
By default, if a user is already registered in Palmr with their Auth0 email, they will be automatically linked to their Palmr account.
> **Note:** You can't disable account linking. If you want to unlink a user from their Auth0 account, you need to delete the user from Palmr.
---
## Technical configuration
Auth0's technical configuration is handled automatically, but understanding the setup can help with troubleshooting:
```yaml
Provider Type: OAuth 2.0 with OIDC Discovery
Issuer URL: https://your-tenant.auth0.com
Authorization Endpoint: /authorize
Token Endpoint: /oauth/token
UserInfo Endpoint: /userinfo
Scopes: openid profile email
```
### Field mappings
Palmr automatically maps Auth0 user information to local user accounts:
- **User ID**: Maps from Auth0's `sub` field
- **Email**: Maps from Auth0's `email` field
- **Full Name**: Maps from Auth0's `name` field
- **First Name**: Maps from Auth0's `given_name` field
- **Last Name**: Maps from Auth0's `family_name` field
- **Avatar**: Maps from Auth0's `picture` field
- **Username**: Maps from Auth0's `nickname` field
### Auth0-specific features
- **Custom Claims**: Can include custom user metadata and app metadata
- **Connection Support**: Works with database, social, and enterprise connections
- **Rules and Hooks**: Can customize authentication flow with custom logic
- **Multi-factor Authentication**: Supports Auth0's MFA features
- **Enterprise SSO**: Integrates with SAML, LDAP, and other enterprise systems
---
## Testing the configuration
### Verifying the setup
After configuring Auth0 authentication, test the integration to ensure everything works correctly.
1. **Check login page**: Navigate to your Palmr login page and verify the "Sign in with Auth0" button appears
2. **Test authentication flow**: Click the Auth0 sign-in button and complete the authentication process
3. **Verify user creation**: Confirm that a new user account is created (if auto-registration is enabled)
### Login flow verification
The complete authentication process should work as follows:
1. **User clicks "Sign in with Auth0"**: The browser redirects to Auth0's authorization page
2. **User authenticates**: User completes authentication through Auth0 (login, MFA, etc.)
3. **Auth0 redirects back to Palmr**: User returns to Palmr with authentication tokens
4. **Palmr creates or updates user**: User account is automatically managed with Auth0 information
5. **User accesses Palmr**: User is logged in with their Auth0 identity
---
## Troubleshooting common issues
### Redirect URI mismatch error
**Error message**: `invalid_redirect_uri`
**Cause**: The redirect URI in your request doesn't match what's configured in Auth0 application.
**Solution**:
1. Check the exact URL in the error message
2. Add this exact URL to your Auth0 application's callback URLs
3. Ensure you include the correct protocol (http/https) and port
4. Remove any trailing slashes unless they're in the callback URL
### Access denied error
**Error message**: `access_denied`
**Cause**: User denied permissions or the application isn't properly configured.
**Solution**:
1. Verify that your Auth0 application requests the correct scopes
2. Check that users are granting permissions during the authorization flow
3. Ensure your application is not restricted or disabled
4. Verify the application has proper permissions set up
### Invalid client error
**Error message**: `invalid_client`
**Cause**: Incorrect Client ID, Client Secret, or Domain.
**Solution**:
1. Double-check that you've copied the credentials correctly from Auth0
2. Ensure there are no extra spaces or characters in the credentials
3. Verify you're using the correct domain format (e.g., `your-tenant.auth0.com`)
4. Generate a new Client Secret if necessary
### Domain configuration issues
**Error message**: Domain not found or invalid
**Cause**: Incorrect Auth0 domain or tenant configuration.
**Solution**:
1. Verify your Auth0 domain is correct (e.g., `your-tenant.auth0.com`)
2. Check that your Auth0 tenant is active and not suspended
3. Ensure you're using the correct region for your tenant
4. Verify DNS resolution for your Auth0 domain
### Custom claims not available
**Cause**: Custom claims not properly configured in Auth0 rules or actions.
**Solution**:
1. Check Auth0 rules and actions for custom claim configuration
2. Verify that custom claims are included in the ID token
3. Ensure the claims are properly formatted and accessible
4. Test with a user that has the expected custom claims
---
## Security best practices
### Credential management
- **Never expose secrets**: Keep your Client Secret secure and never commit it to version control
- **Rotate credentials regularly**: Generate new Client Secrets periodically for enhanced security
- **Use environment variables**: Store sensitive configuration in environment variables, not config files
- **Monitor access logs**: Regularly review authentication logs for suspicious activity
### Scope and permission management
- **Minimal scopes**: Only request `openid`, `profile`, and `email` scopes as required by Palmr
- **User consent**: Ensure users understand what permissions they're granting
- **Regular audits**: Review which users have connected their Auth0 accounts
- **Access reviews**: Periodically check user access and remove inactive accounts
### Production considerations
- **Use HTTPS**: Always use HTTPS in production environments
- **Configure proper domains**: Use production domains in Auth0 application settings
- **Test thoroughly**: Verify the complete authentication flow before going live
- **Plan for failures**: Have fallback authentication methods available
---
## Next steps
With Auth0 authentication configured, you might want to:
- **Configure additional providers**: Set up other OIDC providers for more authentication options
- **Customize user management**: Fine-tune auto-registration and admin assignment rules
- **Review security settings**: Ensure your authentication setup meets your security requirements
- **Monitor usage**: Keep track of authentication patterns and user activity
For more information about OIDC authentication in Palmr, see the [OIDC Authentication overview](/docs/3.1-beta/oidc-authentication).
## Useful resources
- [Auth0 Documentation](https://auth0.com/docs)
- [Auth0 OAuth 2.0 Guide](https://auth0.com/docs/protocols/oauth2)
- [Auth0 OpenID Connect](https://auth0.com/docs/protocols/openid-connect)
- [Auth0 Dashboard](https://manage.auth0.com)

View File

@@ -3,9 +3,11 @@ title: Discord
icon: MessageSquare
---
import { ZoomableImage } from "@/components/ui/zoomable-image";
Discord is one of Palmr's officially supported OIDC providers, offering secure authentication through Discord OAuth 2.0. This integration allows users to sign in to Palmr using their existing Discord accounts, making it perfect for gaming communities, developer teams, and organizations already using Discord.
{/* Imagem: Screenshot da tela de login do Palmr mostrando o botão "Sign in with Discord" em destaque */}
<ZoomableImage src="/assets/v3/oidc/discord/sign-in-with-discord.png" alt="Sign in with Discord" />
## Why use Discord authentication?
@@ -39,14 +41,14 @@ To get started with Discord authentication, you'll need to create an application
1. **Navigate to Discord Developer Portal**: Go to [discord.com/developers/applications](https://discord.com/developers/applications)
{/* Imagem: Screenshot da página inicial do Discord Developer Portal com botão "New Application" em destaque */}
<ZoomableImage src="/assets/v3/oidc/discord/developer-portal-home.png" alt="Discord Developer Portal Home" />
2. **Create new application**: Click **"New Application"** button
3. **Enter application details**:
- **Name**: Enter a descriptive name like "Palmr File Sharing"
- **Team**: Select your team (or leave as personal)
- **Accept Terms of Service and Developer Policy**: Check the box
{/* Imagem: Modal de criação de aplicação no Discord com campos preenchidos */}
<ZoomableImage src="/assets/v3/oidc/discord/create-application-modal.png" alt="Discord Create Application Modal" />
4. **Create application**: Click **"Create"** to generate your application
@@ -59,7 +61,11 @@ After creating your application, you'll need to configure basic settings and bra
- **Icon**: Upload your organization's logo or Palmr-related icon
- **Cover Image**: Optional banner image for better branding
{/* Imagem: Página de configurações gerais da aplicação Discord com campos preenchidos */}
<ZoomableImage
src="/assets/v3/oidc/discord/application-settings.png"
alt="Discord Application Settings"
legend="This is a fake application, you have to use your own."
/>
2. **Configure application details**:
- **Tags**: Add relevant tags (optional)
@@ -70,59 +76,45 @@ After creating your application, you'll need to configure basic settings and bra
Now you'll configure the OAuth2 settings that Palmr will use to authenticate users.
1. **Navigate to OAuth2**: In the left sidebar, click **"OAuth2"** > **"General"**
1. **Navigate to OAuth2**: In the left sidebar, click **"OAuth2"**
{/* Imagem: Menu lateral do Discord Developer Portal com "OAuth2" expandido e "General" em destaque */}
<ZoomableImage src="/assets/v3/oidc/discord/oauth2-general.png" alt="Discord OAuth2 General Settings" />
2. **Configure OAuth2 settings**:
- **Client Secret**: Click **"Reset Secret"** to generate a new client secret
- **Copy credentials**: Save both **Client ID** and **Client Secret** for later use
{/* Imagem: Seção OAuth2 General mostrando Client ID visível e botão "Reset Secret" para gerar Client Secret */}
3. **Add redirect URIs**: In the **"Redirects"** section, add your Palmr callback URLs:
**For production:**
```
https://yourdomain.com/api/auth/callback/discord
https://yourdomain.com/api/auth/providers/discord/callback
```
**For development:**
```
http://localhost:3000/api/auth/callback/discord
http://localhost:3000/api/auth/providers/discord/callback
```
**For custom ports:**
```
https://yourdomain.com:5487/api/auth/callback/discord
https://yourdomain.com:5487/api/auth/providers/discord/callback
```
{/* Imagem: Campo "Redirects" preenchido com as URLs de callback do Palmr para Discord */}
4. **Save changes**: Click **"Save Changes"** to apply your configuration
### Configuring OAuth2 scopes
Discord uses specific scopes to control what information your application can access.
1. **Navigate to OAuth2 URL Generator**: Click **"OAuth2"** > **"URL Generator"**
{/* Imagem: Página URL Generator do Discord OAuth2 mostrando lista de scopes disponíveis */}
2. **Select required scopes**:
4. **Select required scopes**:
- **`identify`** - Access to user's basic account information (required)
- **`email`** - Access to user's email address (required for Palmr)
{/* Imagem: Scopes "identify" e "email" selecionados no Discord URL Generator */}
5. **Save changes**: Click **"Save Changes"** to apply your configuration
3. **Verify permissions**: Review what each scope provides:
- **identify**: Username, discriminator, global name, avatar
- **email**: Email address for account creation and management
> **Important:** Palmr requires both `identify` and `email` scopes to function properly. The `identify` scope provides user identification, while `email` is needed for account creation and management.
<ZoomableImage
src="/assets/v3/oidc/discord/required-scopes.png"
alt="Discord Required Scopes"
legend="This is a fake application, you have to use your own."
/>
---
@@ -134,15 +126,11 @@ To configure Discord authentication in Palmr, you need administrator access to t
1. **Login as administrator**: Sign in to Palmr with an admin account
{/* Imagem: Tela de login do Palmr com credenciais de administrador */}
2. **Access settings**: Click your profile picture in the header and select **Settings**
{/* Imagem: Menu dropdown do usuário no Palmr com a opção "Settings" em destaque */}
3. **Navigate to authentication**: Find and click on the **Authentication Providers** configuration section
3. **Navigate to authentication**: Find and click on the **Authentication** or **OIDC** configuration section
{/* Imagem: Página de configurações do Palmr mostrando as diferentes seções, com Authentication/OIDC em destaque */}
<ZoomableImage src="/assets/v3/oidc/auth-providers.png" alt="Palmr Authentication Providers" />
### Enabling Discord provider
@@ -150,17 +138,22 @@ Discord comes pre-configured as an official provider, so the setup process is st
1. **Locate Discord provider**: Find Discord in the list of available providers
{/* Imagem: Lista de provedores OIDC no Palmr com o Discord listado como provider oficial */}
2. **Enable the provider**: Toggle the status to **Enabled**
{/* Imagem: Card do provedor Discord no Palmr com o toggle "Enabled" ativado */}
<ZoomableImage src="/assets/v3/oidc/discord/palmr-enabled-discord.png" alt="Palmr Discord Provider Enabled" />
After enabling the provider, click on the pen icon to configure the provider.
3. **Configure credentials**:
- **Client ID**: Paste the Client ID from Discord Developer Portal
- **Client Secret**: Paste the Client Secret from Discord Developer Portal
- **Scopes**: Add the scopes you want to use. The default scopes are `identify` and `email`.
{/* Imagem: Formulário de configuração do Discord provider no Palmr com os campos Client ID e Client Secret preenchidos */}
<ZoomableImage
src="/assets/v3/oidc/discord/edit-discord.png"
alt="Edit Discord Provider"
legend="This is a fake application, you have to use your own."
/>
### Advanced configuration options
@@ -172,12 +165,22 @@ Configure additional settings to customize the authentication behavior:
**Sort Order**: Control where the Discord login button appears relative to other authentication providers.
{/* Imagem: Seção de configurações avançadas do Discord provider mostrando Auto Registration e Sort Order */}
**Icon**: you can choose the icon you want to use for the Discord login button (default is `FaDiscord`).
<ZoomableImage src="/assets/v3/oidc/discord/discord-icon.png" alt="Discord Icon" />
> **Community tip:** Discord authentication works great for gaming communities and development teams. Consider enabling auto-registration for trusted Discord communities.
---
## Account linking
By default, if a user is already registered in Palmr with their Discord email, they will be automatically linked to their Palmr account.
> **Note:** You can't disable account linking. If you want to unlink a user from their Discord account, you need to delete the user from Palmr.
---
## Technical configuration
Discord's technical configuration is handled automatically, but understanding the setup can help with troubleshooting:
@@ -189,7 +192,6 @@ Authorization Endpoint: /oauth2/authorize
Token Endpoint: /api/oauth2/token
UserInfo Endpoint: /api/users/@me
Scopes: identify email
Discovery: Disabled (Manual endpoint configuration)
```
### Field mappings
@@ -218,18 +220,10 @@ After configuring Discord authentication, test the integration to ensure everyth
1. **Check login page**: Navigate to your Palmr login page and verify the "Sign in with Discord" button appears
{/* Imagem: Tela de login do Palmr mostrando o botão "Sign in with Discord" visível e funcionando */}
2. **Test authentication flow**: Click the Discord sign-in button and complete the authentication process
{/* Imagem: Fluxo de autenticação do Discord mostrando a tela de autorização do Discord após clicar no botão */}
3. **Verify user creation**: Confirm that a new user account is created (if auto-registration is enabled)
{/* Imagem: Dashboard administrativo do Palmr mostrando o novo usuário criado automaticamente via Discord */}
4. **Check user information**: Verify that Discord username, global name, and avatar are properly imported
### Login flow verification
The complete authentication process should work as follows:
@@ -240,8 +234,6 @@ The complete authentication process should work as follows:
4. **Palmr creates or updates user**: User account is automatically managed with Discord information
5. **User accesses Palmr**: User is logged in with their Discord identity
{/* Imagem: Diagrama de fluxo visual mostrando o processo completo de autenticação Discord -> Palmr */}
---
## Troubleshooting common issues
@@ -250,8 +242,6 @@ The complete authentication process should work as follows:
**Error message**: `invalid_redirect_uri`
{/* Imagem: Screenshot do erro "invalid_redirect_uri" no Discord durante tentativa de login */}
**Cause**: The redirect URI in your request doesn't match what's configured in Discord Developer Portal.
**Solution**:
@@ -265,8 +255,6 @@ The complete authentication process should work as follows:
**Error message**: `access_denied`
{/* Imagem: Screenshot do erro "access_denied" na tela de autorização do Discord */}
**Cause**: User denied permissions or the application doesn't have required scopes.
**Solution**:
@@ -280,8 +268,6 @@ The complete authentication process should work as follows:
**Error message**: `invalid_client`
{/* Imagem: Screenshot do erro "invalid_client" durante tentativa de autenticação com Discord */}
**Cause**: Incorrect Client ID or Client Secret.
**Solution**:
@@ -295,8 +281,6 @@ The complete authentication process should work as follows:
**Error message**: Email not provided or scope missing
{/* Imagem: Interface do Discord Developer Portal mostrando configuração de scopes com "email" em destaque */}
**Cause**: Discord application not configured with email scope or user's email is not verified.
**Solution**:
@@ -321,12 +305,12 @@ The complete authentication process should work as follows:
## Security best practices
### Application security
### Credential management
- **Keep secrets secure**: Never expose your Client Secret in client-side code or public repositories
- **Never expose secrets**: Keep your Client Secret secure and never commit it to version control
- **Rotate credentials regularly**: Generate new Client Secrets periodically for enhanced security
- **Use environment variables**: Store sensitive configuration in environment variables
- **Monitor application usage**: Regularly check Discord Developer Portal for unusual activity
- **Use environment variables**: Store sensitive configuration in environment variables, not config files
- **Monitor access logs**: Regularly review authentication logs for suspicious activity
### Scope and permission management
@@ -340,73 +324,7 @@ The complete authentication process should work as follows:
- **Use HTTPS**: Always use HTTPS in production environments
- **Configure proper domains**: Use production domains in Discord redirect URIs
- **Test thoroughly**: Verify the complete authentication flow before going live
- **Monitor logs**: Keep track of authentication attempts and errors
---
## Example configurations
### Gaming community setup
For a gaming community using Discord:
```yaml
Discord Developer Portal:
Application: Gaming Community Files
Description: File sharing for our gaming community
Redirect URIs: https://files.gamingcommunity.com/api/auth/callback/discord
Scopes: identify, email
Palmr Configuration:
Provider: Discord (Enabled)
Auto Register: Yes
Admin Domains: (leave empty - use manual promotion)
Client ID: 1234567890123456789
Client Secret: abcdefghijklmnopqrstuvwxyz123456
```
{/* Imagem: Configuração completa para comunidade gaming mostrando Discord Developer Portal e Palmr lado a lado */}
### Development team setup
For a software development team:
```yaml
Discord Developer Portal:
Application: DevTeam File Sharing
Description: Secure file sharing for development team
Redirect URIs:
- https://files.devteam.com/api/auth/callback/discord
- http://localhost:3000/api/auth/callback/discord
Scopes: identify, email
Palmr Configuration:
Provider: Discord (Enabled)
Auto Register: Yes
Admin Domains: devteam.com
Client ID: 9876543210987654321
Client Secret: zyxwvutsrqponmlkjihgfedcba654321
```
{/* Imagem: Configuração para equipe de desenvolvimento com múltiplos ambientes (produção e desenvolvimento) */}
---
## Discord vs other providers
### When to choose Discord
- **Gaming communities**: Perfect for organizations centered around gaming
- **Developer teams**: Great for technical teams already using Discord
- **Community-driven projects**: Ideal for open-source projects with Discord communities
- **Informal organizations**: Better suited for casual, community-based groups
### Considerations
- **Limited business features**: Discord lacks enterprise features like SSO management
- **Personal accounts**: Users typically use personal Discord accounts, not business emails
- **Community focus**: Better for communities than traditional business environments
- **User demographics**: Appeals more to younger, tech-savvy user bases
- **Plan for failures**: Have fallback authentication methods available
---
@@ -414,10 +332,10 @@ Palmr Configuration:
With Discord authentication configured, you might want to:
- **Customize user experience**: Adapt Palmr's interface for your Discord community
- **Set up community integrations**: Consider Discord bot integrations for notifications
- **Configure additional providers**: Add other providers for users who don't use Discord
- **Monitor community engagement**: Track how your Discord community uses Palmr
- **Configure additional providers**: Set up other OIDC providers for more authentication options
- **Customize user management**: Fine-tune auto-registration and admin assignment rules
- **Review security settings**: Ensure your authentication setup meets your security requirements
- **Monitor usage**: Keep track of authentication patterns and user activity
For more information about OIDC authentication in Palmr, see the [OIDC Authentication overview](/docs/3.1-beta/oidc-authentication).

View File

@@ -3,10 +3,308 @@ title: GitHub
icon: Github
---
## GitHub
import { ZoomableImage } from "@/components/ui/zoomable-image";
### Prerequisites
GitHub is one of Palmr's officially supported OIDC providers, offering secure authentication through GitHub OAuth 2.0. This integration allows users to sign in to Palmr using their existing GitHub accounts, making it perfect for developer teams, open-source projects, and organizations already using GitHub for version control and collaboration.
- GitHub Application
- GitHub OAuth Client ID and Secret
- GitHub OAuth Redirect URI
<ZoomableImage src="/assets/v3/oidc/github/sign-in-with-github.png" alt="Sign in with GitHub" />
## Why use GitHub authentication?
GitHub authentication provides several advantages for developer-focused organizations and teams:
- **Developer-friendly** - Perfect for teams already using GitHub for development
- **Open-source integration** - Ideal for open-source projects and communities
- **Rich developer profiles** - Access to GitHub usernames, avatars, and organization memberships
- **Repository access** - Can leverage GitHub's permission system for additional features
- **No additional accounts** - Developers can access Palmr with their existing GitHub credentials
---
## Prerequisites
Before configuring GitHub authentication, ensure you have:
- **GitHub account** - Ability to create OAuth Apps on GitHub
- **Admin privileges in Palmr** - Required to configure OIDC settings
> **Note:** GitHub is pre-configured as an official provider in Palmr, which means the technical configuration is handled automatically. You only need to provide your OAuth credentials.
---
## Setting up GitHub OAuth App
### Creating a GitHub OAuth App
To get started with GitHub authentication, you'll need to create an OAuth App in your GitHub Developer Settings.
1. **Navigate to GitHub Developer Settings**: Go to [github.com/settings/developers](https://github.com/settings/developers)
2. **Create new OAuth App**: Click **"New OAuth App"** button
<ZoomableImage src="/assets/v3/oidc/github/developer-settings.png" alt="GitHub Developer Settings" />
3. **Enter application details**:
- **Application name**: Enter a descriptive name like "Palmr File Sharing"
- **Homepage URL**: Enter your Palmr instance URL (e.g., `https://yourdomain.com`)
- **Application description**: Add a clear description of your Palmr instance
- **Authorization callback URL**: Enter your callback URL (see below)
<ZoomableImage
src="/assets/v3/oidc/github/oauth-app-details.png"
alt="GitHub OAuth App Details"
legend="This is a fake application, you have to use your own."
/>
**Set up callback URLs**: In the **"Authorization callback URL"** field, add your Palmr callback URL:
**For production:**
```
https://yourdomain.com/api/auth/providers/github/callback
```
**For development:**
```
http://localhost:3000/api/auth/providers/github/callback
```
**For custom ports:**
```
https://yourdomain.com:5487/api/auth/providers/github/callback
```
4. **Create application**: Click **"Register application"** to generate your OAuth App
### Getting OAuth credentials
Now you'll get the credentials that Palmr will use to authenticate with GitHub.
1. **Copy Client ID**: The Client ID is displayed on your OAuth App page
2. **Generate Client Secret**: Click **"Generate a new client secret"** to create a new secret
<ZoomableImage
src="/assets/v3/oidc/github/oauth-credentials.png"
alt="GitHub OAuth Credentials"
legend="The client ID and client secret shown in the image are examples only (fake credentials). You must use your own credentials from GitHub."
/>
3. **Save credentials**: Copy both the **Client ID** and **Client Secret** for later use
> **Important:** Replace `yourdomain.com` with your actual domain. You can add multiple callback URLs for different environments (development, staging, production) by creating separate OAuth Apps.
---
## Configuring Palmr
### Accessing OIDC settings
To configure GitHub authentication in Palmr, you need administrator access to the settings panel.
1. **Login as administrator**: Sign in to Palmr with an admin account
2. **Access settings**: Click your profile picture in the header and select **Settings**
3. **Navigate to authentication**: Find and click on the **Authentication Providers** configuration section
<ZoomableImage src="/assets/v3/oidc/auth-providers.png" alt="Palmr Authentication Providers" />
### Enabling GitHub provider
GitHub comes pre-configured as an official provider, so the setup process is streamlined.
1. **Locate GitHub provider**: Find GitHub in the list of available providers
2. **Enable the provider**: Toggle the status to **Enabled**
<ZoomableImage src="/assets/v3/oidc/github/enabled-github.png" alt="Palmr GitHub Provider Enabled" />
After enabling the provider, click on the pen icon to configure the provider.
3. **Configure credentials**:
- **Client ID**: Paste the Client ID from GitHub OAuth App
- **Client Secret**: Paste the Client Secret from GitHub OAuth App
- **Scopes**: Add the scopes you want to use. The default scopes are `user:email`.
<ZoomableImage
src="/assets/v3/oidc/github/edit-github.png"
alt="Edit GitHub Provider"
legend="This is a fake application, you have to use your own."
/>
### Advanced configuration options
Configure additional settings to customize the authentication behavior:
**Auto Registration**: Enable this to automatically create user accounts when someone authenticates for the first time.
**Admin Email Domains**: Specify domains that should automatically receive admin privileges. For example, entering `yourcompany.com` will grant admin access to anyone with an email from that domain.
**Sort Order**: Control where the GitHub login button appears relative to other authentication providers.
**Icon**: you can choose the icon you want to use for the GitHub login button (default is `SiGithub`).
<ZoomableImage src="/assets/v3/oidc/github/github-icon.png" alt="GitHub Icon" />
> **Developer tip:** GitHub authentication works great for development teams and open-source projects.
---
## Account linking
By default, if a user is already registered in Palmr with their GitHub email, they will be automatically linked to their Palmr account.
> **Note:** You can't disable account linking. If you want to unlink a user from their GitHub account, you need to delete the user from Palmr.
---
## Technical configuration
GitHub's technical configuration is handled automatically, but understanding the setup can help with troubleshooting:
```yaml
Provider Type: OAuth 2.0 with OIDC Discovery
Issuer URL: https://github.com
Authorization Endpoint: /login/oauth/authorize
Token Endpoint: /login/oauth/access_token
UserInfo Endpoint: https://api.github.com/user
Scopes: user:email
```
### Field mappings
Palmr automatically maps GitHub user information to local user accounts:
- **User ID**: Maps from GitHub's `id` field
- **Email**: Maps from GitHub's `email` field (from user:email scope)
- **Full Name**: Maps from GitHub's `name` field
- **Username**: Maps from GitHub's `login` field
- **Avatar**: Maps from GitHub's `avatar_url` field
---
## Testing the configuration
### Verifying the setup
After configuring GitHub authentication, test the integration to ensure everything works correctly.
1. **Check login page**: Navigate to your Palmr login page and verify the "Sign in with GitHub" button appears
2. **Test authentication flow**: Click the GitHub sign-in button and complete the authentication process
3. **Verify user creation**: Confirm that a new user account is created (if auto-registration is enabled)
### Login flow verification
The complete authentication process should work as follows:
1. **User clicks "Sign in with GitHub"**: The browser redirects to GitHub's authorization page
2. **User authorizes application**: User grants permissions for the requested scopes
3. **GitHub redirects back to Palmr**: User returns to Palmr with authentication tokens
4. **Palmr creates or updates user**: User account is automatically managed with GitHub information
5. **User accesses Palmr**: User is logged in with their GitHub identity
---
## Troubleshooting common issues
### Redirect URI mismatch error
**Error message**: `The redirect_uri MUST match the registered callback URL for this application`
**Cause**: The redirect URI in your request doesn't match what's configured in GitHub OAuth App.
**Solution**:
1. Check the exact URL in the error message
2. Add this exact URL to your GitHub OAuth App's callback URL
3. Ensure you include the correct protocol (http/https) and port
4. Remove any trailing slashes unless they're in the callback URL
### Access denied error
**Error message**: `access_denied`
**Cause**: User denied permissions or the OAuth App isn't properly configured.
**Solution**:
1. Verify that your GitHub OAuth App requests the correct scopes
2. Check that users are granting permissions during the authorization flow
3. Ensure your OAuth App is not restricted or disabled
4. Verify the application has proper permissions set up
### Invalid client error
**Error message**: `invalid_client`
**Cause**: Incorrect Client ID or Client Secret.
**Solution**:
1. Double-check that you've copied the credentials correctly from GitHub
2. Ensure there are no extra spaces or characters in the credentials
3. Generate a new Client Secret if necessary
4. Verify you're using the correct OAuth App in GitHub
### Email not available error
**Error message**: Email not provided or scope missing
**Cause**: GitHub OAuth App not configured with `user:email` scope or user's email is private.
**Solution**:
1. Verify that your GitHub OAuth App requests the `user:email` scope
2. Check that users have public email addresses or have granted email access
3. Ensure the scope configuration matches what Palmr expects
4. Test with a GitHub account that has a public email address
---
## Security best practices
### Credential management
- **Never expose secrets**: Keep your Client Secret secure and never commit it to version control
- **Rotate credentials regularly**: Generate new Client Secrets periodically for enhanced security
- **Use environment variables**: Store sensitive configuration in environment variables, not config files
- **Monitor access logs**: Regularly review authentication logs for suspicious activity
### Scope and permission management
- **Minimal scopes**: Only request `user:email` scopes as required by Palmr
- **User consent**: Ensure users understand what permissions they're granting
- **Regular audits**: Review which users have connected their GitHub accounts
- **Access reviews**: Periodically check user access and remove inactive accounts
### Production considerations
- **Use HTTPS**: Always use HTTPS in production environments
- **Configure proper domains**: Use production domains in GitHub OAuth App
- **Test thoroughly**: Verify the complete authentication flow before going live
- **Plan for failures**: Have fallback authentication methods available
---
## Next steps
With GitHub authentication configured, you might want to:
- **Configure additional providers**: Set up other OIDC providers for more authentication options
- **Customize user management**: Fine-tune auto-registration and admin assignment rules
- **Review security settings**: Ensure your authentication setup meets your security requirements
- **Monitor usage**: Keep track of authentication patterns and user activity
For more information about OIDC authentication in Palmr, see the [OIDC Authentication overview](/docs/3.1-beta/oidc-authentication).
## Useful resources
- [GitHub OAuth Apps Documentation](https://docs.github.com/en/apps/oauth-apps)
- [GitHub OAuth Scopes](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)
- [GitHub Developer Settings](https://github.com/settings/developers)
- [GitHub API Documentation](https://docs.github.com/en/rest)

View File

@@ -3,9 +3,11 @@ title: Google
icon: Chrome
---
import { ZoomableImage } from "@/components/ui/zoomable-image";
Google is one of Palmr's officially supported OIDC providers, offering secure and reliable authentication through Google OAuth 2.0. This integration allows users to sign in to Palmr using their existing Google accounts, providing a seamless single sign-on experience.
{/* Imagem: Screenshot da tela de login do Palmr mostrando o botão "Sign in with Google" em destaque */}
<ZoomableImage src="/assets/v3/oidc/google/sign-in-with-google.png" alt="Sign in with Google" />
## Why use Google authentication?
@@ -39,11 +41,11 @@ To get started with Google authentication, you'll need to set up a project in Go
1. **Navigate to Google Cloud Console**: Go to [console.cloud.google.com](https://console.cloud.google.com/)
{/* Imagem: Screenshot da página inicial do Google Cloud Console com a seleção de projeto em destaque */}
<ZoomableImage src="/assets/v3/oidc/google/cloud-console-home.png" alt="Google Cloud Console Home" />
2. **Create or select a project**: Choose an existing project or create a new one for your Palmr installation
{/* Imagem: Modal de criação/seleção de projeto no Google Cloud Console, mostrando o botão "NEW PROJECT" */}
<ZoomableImage src="/assets/v3/oidc/google/select-project-modal.png" alt="Google Cloud Console Select Project Modal" />
3. **Enable the project**: Ensure the project is active and selected
@@ -53,78 +55,66 @@ The OAuth consent screen is what users see when they authenticate with Google.
1. **Access OAuth consent screen**: Navigate to **APIs & Services** > **OAuth consent screen**
{/* Imagem: Menu lateral do Google Cloud Console com "APIs & Services" expandido e "OAuth consent screen" em destaque */}
<ZoomableImage
src="/assets/v3/oidc/google/oauth-consent-dropdown.png"
alt="Google Cloud Console OAuth Consent Dropdown"
/>
2. **Choose user type**:
- **Internal** - For Google Workspace organizations (users within your domain only)
- **External** - For public use (any Google user can authenticate)
{/* Imagem: Tela de seleção do tipo de usuário (Internal vs External) no OAuth consent screen */}
<ZoomableImage src="/assets/v3/oidc/google/user-type-select.png" alt="Google Cloud Console User Type Select" />
3. **Fill required information**:
- **Application name**: Enter a descriptive name like "Palmr File Sharing"
- **User support email**: Provide a valid support email address
- **Developer contact information**: Add your contact email for Google communications
{/* Imagem: Formulário do OAuth consent screen preenchido com os campos obrigatórios destacados */}
> **Tip:** For business use, choose "Internal" if you have Google Workspace. This restricts access to your organization's users and simplifies the approval process.
### Adding OAuth scopes
Configure the permissions your application will request from users.
1. **Navigate to Scopes**: In the OAuth consent screen configuration, find the **Scopes** section
2. **Add standard scopes**:
- `openid` - Required for OpenID Connect
- `profile` - Access to basic profile information
- `email` - Access to user's email address
{/* Imagem: Seção de Scopes no OAuth consent screen com os scopes openid, profile e email adicionados */}
These scopes provide Palmr with the basic information needed to create and manage user accounts.
### Creating OAuth 2.0 credentials
Now you'll create the actual credentials that Palmr will use to authenticate with Google.
1. **Navigate to Credentials**: Go to **APIs & Services** > **Credentials**
{/* Imagem: Página de Credentials no Google Cloud Console vazia, pronta para criar novas credenciais */}
<ZoomableImage src="/assets/v3/oidc/google/credentials-select.png" alt="Google Cloud Console Credentials select" />
2. **Create OAuth client**: Click **+ CREATE CREDENTIALS** > **OAuth client ID**
{/* Imagem: Dropdown do botão "CREATE CREDENTIALS" com "OAuth client ID" em destaque */}
<ZoomableImage
src="/assets/v3/oidc/google/create-oauth-client-id.png"
alt="Google Cloud Console Create OAuth Client ID"
/>
3. **Select application type**: Choose **Web application**
{/* Imagem: Formulário de criação de OAuth client ID com "Web application" selecionado */}
<ZoomableImage src="/assets/v3/oidc/google/web-app-select.png" alt="Google Cloud Console Web App Select" />
4. **Configure authorized URIs**:
4. **Configure authorized URIs and authorized redirect URIs**:
**For production:**
```
https://yourdomain.com/api/auth/callback/google
```
- Authorized URIs: `https://yourdomain.com`
- Authorized redirect URIs: `https://yourdomain.com/api/auth/providers/google/callback`
**For development:**
```
http://localhost:3000/api/auth/callback/google
```
- Authorized URIs: `http://localhost:3000`
- Authorized redirect URIs: `http://localhost:3000/api/auth/providers/google/callback`
**For custom ports:**
- Authorized URIs: `https://yourdomain.com:5487`
- Authorized redirect URIs: `https://yourdomain.com:5487/api/auth/providers/google/callback`
```
https://yourdomain.com:5487/api/auth/callback/google
```
{/* Imagem: Campo "Authorized redirect URIs" preenchido com as URLs de callback do Palmr */}
<ZoomableImage src="/assets/v3/oidc/google/allowed-urls.png" alt="Google Cloud Console Allowed URLs" />
5. **Create and save credentials**: Click **Create** and copy both the **Client ID** and **Client Secret**
{/* Imagem: Modal final mostrando o Client ID e Client Secret gerados, com botões de cópia em destaque */}
<ZoomableImage
src="/assets/v3/oidc/google/oauth-client-created.png"
alt="Google Cloud Console Client ID and Client Secret"
legend="The client ID and client secret shown in the image are examples only (fake credentials). You must use your own credentials from Google Cloud Console."
/>
> **Important:** Replace `yourdomain.com` with your actual domain. You can add multiple URIs for different environments (development, staging, production).
@@ -138,15 +128,11 @@ To configure Google authentication in Palmr, you need administrator access to th
1. **Login as administrator**: Sign in to Palmr with an admin account
{/* Imagem: Tela de login do Palmr com credenciais de administrador */}
2. **Access settings**: Click your profile picture in the header and select **Settings**
{/* Imagem: Menu dropdown do usuário no Palmr com a opção "Settings" em destaque */}
3. **Navigate to authentication**: Find and click on the **Authentication Providers** configuration section
3. **Navigate to authentication**: Find and click on the **Authentication** or **OIDC** configuration section
{/* Imagem: Página de configurações do Palmr mostrando as diferentes seções, com Authentication/OIDC em destaque */}
<ZoomableImage src="/assets/v3/oidc/auth-providers.png" alt="Palmr Authentication Providers" />
### Enabling Google provider
@@ -154,17 +140,18 @@ Google comes pre-configured as an official provider, so the setup process is str
1. **Locate Google provider**: Find Google in the list of available providers
{/* Imagem: Lista de provedores OIDC no Palmr com o Google listado como provider oficial */}
2. **Enable the provider**: Toggle the status to **Enabled**
{/* Imagem: Card do provedor Google no Palmr com o toggle "Enabled" ativado */}
<ZoomableImage src="/assets/v3/oidc/google/palmr-enabled-google.png" alt="Palmr Authentication Providers" />
After enabling the provider, click on the pen icon to configure the provider.
3. **Configure credentials**:
- **Client ID**: Paste the Client ID from Google Cloud Console
- **Client Secret**: Paste the Client Secret from Google Cloud Console
- **Scopes**: Add the scopes you want to use. The default scopes are `openid`, `profile`, and `email`.
{/* Imagem: Formulário de configuração do Google provider no Palmr com os campos Client ID e Client Secret preenchidos */}
<ZoomableImage src="/assets/v3/oidc/google/edit-google.png" alt="Edit Google Provider" />
### Advanced configuration options
@@ -176,12 +163,22 @@ Configure additional settings to customize the authentication behavior:
**Sort Order**: Control where the Google login button appears relative to other authentication providers.
{/* Imagem: Seção de configurações avançadas do Google provider mostrando Auto Registration, Admin Email Domains e Sort Order */}
**Icon**: you can choose the icon you want to use for the Google login button (default is `FcGoogle`).
<ZoomableImage src="/assets/v3/oidc/google/google-icon.png" alt="Google Icon" />
> **Security consideration:** Be cautious with auto-registration and admin domains. Only enable these if you trust the user base or have domain restrictions in place.
---
## Account linking
By default, if a user is already registered in Palmr with their Google email, they will be automatically linked to their Palmr account.
> **Note:** You can't disable account linking. If you want to unlink a user from their Google account, you need to delete the user from Palmr.
---
## Technical configuration
Google's technical configuration is handled automatically, but understanding the setup can help with troubleshooting:
@@ -193,7 +190,6 @@ Authorization Endpoint: /o/oauth2/v2/auth
Token Endpoint: /o/oauth2/token
UserInfo Endpoint: https://www.googleapis.com/oauth2/v3/userinfo
Scopes: openid profile email
Discovery: Enabled (/.well-known/openid_configuration)
```
### Field mappings
@@ -217,18 +213,10 @@ After configuring Google authentication, test the integration to ensure everythi
1. **Check login page**: Navigate to your Palmr login page and verify the "Sign in with Google" button appears
{/* Imagem: Tela de login do Palmr mostrando o botão "Sign in with Google" visível e funcionando */}
2. **Test authentication flow**: Click the Google sign-in button and complete the authentication process
{/* Imagem: Fluxo de autenticação do Google mostrando a tela de login do Google após clicar no botão */}
3. **Verify user creation**: Confirm that a new user account is created (if auto-registration is enabled)
{/* Imagem: Dashboard administrativo do Palmr mostrando o novo usuário criado automaticamente via Google */}
4. **Check admin privileges**: If you configured admin domains, verify that users from those domains receive admin access
### Login flow verification
The complete authentication process should work as follows:
@@ -239,8 +227,6 @@ The complete authentication process should work as follows:
4. **Palmr creates or updates user**: User account is automatically managed based on your configuration
5. **User accesses Palmr**: User is logged in and can use all features according to their permissions
{/* Imagem: Diagrama de fluxo visual mostrando o processo completo de autenticação Google -> Palmr */}
---
## Troubleshooting common issues
@@ -249,8 +235,6 @@ The complete authentication process should work as follows:
**Error message**: `Error 400: redirect_uri_mismatch`
{/* Imagem: Screenshot do erro "redirect_uri_mismatch" no browser durante tentativa de login */}
**Cause**: The redirect URI in your request doesn't match what's configured in Google Cloud Console.
**Solution**:
@@ -264,8 +248,6 @@ The complete authentication process should work as follows:
**Error message**: `Error 403: access_denied`
{/* Imagem: Screenshot do erro "access_denied" na tela de OAuth do Google */}
**Cause**: User denied permissions or the OAuth consent screen isn't properly configured.
**Solution**:
@@ -279,8 +261,6 @@ The complete authentication process should work as follows:
**Error message**: `Error 401: invalid_client`
{/* Imagem: Screenshot do erro "invalid_client" durante tentativa de autenticação */}
**Cause**: Incorrect Client ID or Client Secret.
**Solution**:
@@ -290,29 +270,15 @@ The complete authentication process should work as follows:
3. Regenerate credentials if necessary
4. Verify you're using the correct project in Google Cloud Console
### Users not receiving admin privileges
**Cause**: Email domain not properly configured in Palmr settings.
{/* Imagem: Configuração de Admin Email Domains no Palmr com exemplo de domínio configurado */}
**Solution**:
1. Verify the admin domain configuration in Palmr settings
2. Check that the user's email domain exactly matches the configured domain
3. Ensure the domain format is correct (e.g., `company.com`, not `@company.com`)
4. Manually promote users through the admin interface if needed
### Discovery endpoint issues
**Cause**: Network connectivity problems or DNS resolution issues.
**Solution**:
1. Test the discovery endpoint manually: `https://accounts.google.com/.well-known/openid_configuration`
2. Check server firewall and network connectivity
3. Verify DNS resolution from your server
4. Consider proxy or CDN configurations that might block the request
1. Check server firewall and network connectivity
2. Verify DNS resolution from your server
3. Consider proxy or CDN configurations that might block the request
---
@@ -341,54 +307,6 @@ The complete authentication process should work as follows:
---
## Example configurations
### Basic setup
For a simple Palmr installation with Google authentication:
```yaml
Google Cloud Console:
Project: palmr-production
OAuth Consent: External
Scopes: openid, profile, email
Authorized URIs: https://files.yourcompany.com/api/auth/callback/google
Palmr Configuration:
Provider: Google (Enabled)
Auto Register: Yes
Admin Domains: yourcompany.com
Client ID: 123456789-abcdefghijklmnop.apps.googleusercontent.com
Client Secret: GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxx
```
{/* Imagem: Comparação lado a lado das configurações no Google Cloud Console e no Palmr para setup básico */}
### Enterprise setup
For Google Workspace organizations:
```yaml
Google Cloud Console:
Project: yourcompany-palmr
OAuth Consent: Internal
Scopes: openid, profile, email
Authorized URIs:
- https://palmr.yourcompany.com/api/auth/callback/google
- https://files.yourcompany.com/api/auth/callback/google
Palmr Configuration:
Provider: Google (Enabled)
Auto Register: Yes
Admin Domains: yourcompany.com, admin.yourcompany.com
Client ID: 987654321-zyxwvutsrqponmlk.apps.googleusercontent.com
Client Secret: GOCSPX-yyyyyyyyyyyyyyyyyyyyyyyy
```
{/* Imagem: Configuração enterprise completa mostrando múltiplos domínios e URIs autorizadas */}
---
## Next steps
With Google authentication configured, you might want to:

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@@ -8,10 +8,11 @@ import { cn } from "@/lib/utils";
interface ZoomableImageProps {
src: string;
alt: string;
legend?: string;
className?: string;
}
export const ZoomableImage: React.FC<ZoomableImageProps> = ({ src, alt, className }) => {
export const ZoomableImage: React.FC<ZoomableImageProps> = ({ src, alt, legend, className }) => {
const [isZoomed, setIsZoomed] = useState(false);
const handleImageClick = () => {
@@ -61,6 +62,7 @@ export const ZoomableImage: React.FC<ZoomableImageProps> = ({ src, alt, classNam
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-all duration-300 rounded-lg flex items-center justify-center">
<ZoomIn className="w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" />
</div>
{legend && <p className="text-sm text-center -mt-4 font-light text-muted-foreground">{legend}</p>}
</div>
{/* Zoomed Modal */}

View File

@@ -1533,5 +1533,20 @@
"passwordRequired": "كلمة المرور مطلوبة",
"nameRequired": "الاسم مطلوب",
"required": "هذا الحقل مطلوب"
},
"iconPicker": {
"title": "اختر أيقونة",
"placeholder": "اختر أيقونة",
"searchPlaceholder": "البحث عن الأيقونات...",
"loadingMore": "جاري تحميل المزيد من الأيقونات...",
"allIconsLoaded": "تم تحميل جميع الأيقونات {count}",
"noIconsFound": "لم يتم العثور على أيقونات لـ \"{search}\"",
"tabs": {
"all": "جميع الأيقونات",
"popular": "الشائعة",
"auth": "مزودي المصادقة"
},
"stats": "{iconCount} أيقونة من {libraryCount} مكتبة",
"categoryBadge": "{category} ({count} أيقونات)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "Passwort ist erforderlich",
"nameRequired": "Name ist erforderlich",
"required": "Dieses Feld ist erforderlich"
},
"iconPicker": {
"title": "Symbol auswählen",
"placeholder": "Wählen Sie ein Symbol",
"searchPlaceholder": "Symbole suchen...",
"loadingMore": "Weitere Symbole werden geladen...",
"allIconsLoaded": "Alle {count} Symbole geladen",
"noIconsFound": "Keine Symbole für \"{search}\" gefunden",
"tabs": {
"all": "Alle Symbole",
"popular": "Beliebt",
"auth": "Authentifizierungsanbieter"
},
"stats": "{iconCount} Symbole aus {libraryCount} Bibliotheken",
"categoryBadge": "{category} ({count} Symbole)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordMinLength": "Password must be at least 6 characters",
"nameRequired": "Name is required",
"required": "This field is required"
},
"iconPicker": {
"title": "Select Icon",
"placeholder": "Select an icon",
"searchPlaceholder": "Search icons...",
"loadingMore": "Loading more icons...",
"allIconsLoaded": "All {count} icons loaded",
"noIconsFound": "No icons found for \"{search}\"",
"tabs": {
"all": "All Icons",
"popular": "Popular",
"auth": "Auth Providers"
},
"stats": "{iconCount} icons from {libraryCount} libraries",
"categoryBadge": "{category} ({count} icons)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "Se requiere la contraseña",
"nameRequired": "El nombre es obligatorio",
"required": "Este campo es obligatorio"
},
"iconPicker": {
"title": "Seleccionar Icono",
"placeholder": "Seleccionar un icono",
"searchPlaceholder": "Buscar iconos...",
"loadingMore": "Cargando más iconos...",
"allIconsLoaded": "Todos los {count} iconos cargados",
"noIconsFound": "No se encontraron iconos para \"{search}\"",
"tabs": {
"all": "Todos los Iconos",
"popular": "Populares",
"auth": "Proveedores de Autenticación"
},
"stats": "{iconCount} iconos de {libraryCount} bibliotecas",
"categoryBadge": "{category} ({count} iconos)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "Le mot de passe est requis",
"nameRequired": "Nome é obrigatório",
"required": "Este campo é obrigatório"
},
"iconPicker": {
"title": "Sélectionner une Icône",
"placeholder": "Sélectionner une icône",
"searchPlaceholder": "Rechercher des icônes...",
"loadingMore": "Chargement d'autres icônes...",
"allIconsLoaded": "Toutes les {count} icônes sont chargées",
"noIconsFound": "Aucune icône trouvée pour \"{search}\"",
"tabs": {
"all": "Toutes les Icônes",
"popular": "Populaires",
"auth": "Fournisseurs d'Authentification"
},
"stats": "{iconCount} icônes de {libraryCount} bibliothèques",
"categoryBadge": "{category} ({count} icônes)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "पासवर्ड आवश्यक है",
"nameRequired": "नाम आवश्यक है",
"required": "यह फ़ील्ड आवश्यक है"
},
"iconPicker": {
"title": "आइकन चुनें",
"placeholder": "एक आइकन चुनें",
"searchPlaceholder": "आइकन खोजें...",
"loadingMore": "अधिक आइकन लोड हो रहे हैं...",
"allIconsLoaded": "सभी {count} आइकन लोड हो गए",
"noIconsFound": "\"{search}\" के लिए कोई आइकन नहीं मिला",
"tabs": {
"all": "सभी आइकन",
"popular": "लोकप्रिय",
"auth": "प्रमाणीकरण प्रदाता"
},
"stats": "{libraryCount} लाइब्रेरी से {iconCount} आइकन",
"categoryBadge": "{category} ({count} आइकन)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordMinLength": "La password deve contenere almeno 6 caratteri",
"nameRequired": "Il nome è obbligatorio",
"required": "Questo campo è obbligatorio"
},
"iconPicker": {
"title": "Seleziona Icona",
"placeholder": "Seleziona un'icona",
"searchPlaceholder": "Cerca icone...",
"loadingMore": "Caricamento altre icone...",
"allIconsLoaded": "Tutte le {count} icone caricate",
"noIconsFound": "Nessuna icona trovata per \"{search}\"",
"tabs": {
"all": "Tutte le Icone",
"popular": "Popolari",
"auth": "Provider di Autenticazione"
},
"stats": "{iconCount} icone da {libraryCount} librerie",
"categoryBadge": "{category} ({count} icone)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "パスワードは必須です",
"nameRequired": "名前は必須です",
"required": "このフィールドは必須です"
},
"iconPicker": {
"title": "アイコンを選択",
"placeholder": "アイコンを選択してください",
"searchPlaceholder": "アイコンを検索...",
"loadingMore": "アイコンを読み込み中...",
"allIconsLoaded": "全{count}個のアイコンを読み込みました",
"noIconsFound": "\"{search}\"に一致するアイコンが見つかりませんでした",
"tabs": {
"all": "すべてのアイコン",
"popular": "人気",
"auth": "認証プロバイダー"
},
"stats": "{libraryCount}ライブラリから{iconCount}個のアイコン",
"categoryBadge": "{category}{count}個のアイコン)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "비밀번호는 필수입니다",
"nameRequired": "이름은 필수입니다",
"required": "이 필드는 필수입니다"
},
"iconPicker": {
"title": "아이콘 선택",
"placeholder": "아이콘 선택",
"searchPlaceholder": "아이콘 검색...",
"loadingMore": "아이콘 더 불러오는 중...",
"allIconsLoaded": "모든 {count}개의 아이콘이 로드됨",
"noIconsFound": "\"{search}\"에 대한 아이콘을 찾을 수 없습니다",
"tabs": {
"all": "모든 아이콘",
"popular": "인기",
"auth": "인증 제공자"
},
"stats": "{libraryCount}개의 라이브러리에서 {iconCount}개의 아이콘",
"categoryBadge": "{category} ({count}개의 아이콘)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordMinLength": "Wachtwoord moet minimaal 6 tekens bevatten",
"nameRequired": "Naam is verplicht",
"required": "Dit veld is verplicht"
},
"iconPicker": {
"title": "Selecteer Pictogram",
"placeholder": "Selecteer een pictogram",
"searchPlaceholder": "Zoek pictogrammen...",
"loadingMore": "Meer pictogrammen laden...",
"allIconsLoaded": "Alle {count} pictogrammen geladen",
"noIconsFound": "Geen pictogrammen gevonden voor \"{search}\"",
"tabs": {
"all": "Alle Pictogrammen",
"popular": "Populair",
"auth": "Authenticatie Providers"
},
"stats": "{iconCount} pictogrammen van {libraryCount} bibliotheken",
"categoryBadge": "{category} ({count} pictogrammen)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordMinLength": "Hasło musi mieć co najmniej 6 znaków",
"nameRequired": "Nazwa jest wymagana",
"required": "To pole jest wymagane"
},
"iconPicker": {
"title": "Wybierz ikonę",
"placeholder": "Wybierz ikonę",
"searchPlaceholder": "Szukaj ikon...",
"loadingMore": "Ładowanie kolejnych ikon...",
"allIconsLoaded": "Załadowano wszystkie {count} ikon",
"noIconsFound": "Nie znaleziono ikon dla \"{search}\"",
"tabs": {
"all": "Wszystkie ikony",
"popular": "Popularne",
"auth": "Dostawcy uwierzytelniania"
},
"stats": "{iconCount} ikon z {libraryCount} bibliotek",
"categoryBadge": "{category} ({count} ikon)"
}
}

View File

@@ -1531,5 +1531,20 @@
"lastNameRequired": "O sobrenome é necessário",
"usernameLength": "O nome de usuário deve ter pelo menos 3 caracteres",
"usernameSpaces": "O nome de usuário não pode conter espaços"
},
"iconPicker": {
"title": "Selecionar ícone",
"placeholder": "Selecione um ícone",
"searchPlaceholder": "Pesquisar ícones...",
"loadingMore": "Carregando mais ícones...",
"allIconsLoaded": "Todos os {count} ícones carregados",
"noIconsFound": "Nenhum ícone encontrado para \"{search}\"",
"tabs": {
"all": "Todos os ícones",
"popular": "Populares",
"auth": "Provedores de autenticação"
},
"stats": "{iconCount} ícones de {libraryCount} bibliotecas",
"categoryBadge": "{category} ({count} ícones)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "Требуется пароль",
"nameRequired": "Требуется имя",
"required": "Это поле обязательно"
},
"iconPicker": {
"title": "Выбрать иконку",
"placeholder": "Выберите иконку",
"searchPlaceholder": "Поиск иконок...",
"loadingMore": "Загрузка дополнительных иконок...",
"allIconsLoaded": "Загружено все {count} иконок",
"noIconsFound": "Не найдено иконок для \"{search}\"",
"tabs": {
"all": "Все иконки",
"popular": "Популярные",
"auth": "Провайдеры аутентификации"
},
"stats": "{iconCount} иконок из {libraryCount} библиотек",
"categoryBadge": "{category} ({count} иконок)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "Şifre gerekli",
"nameRequired": "İsim gereklidir",
"required": "Bu alan zorunludur"
},
"iconPicker": {
"title": "Simge Seç",
"placeholder": "Bir simge seç",
"searchPlaceholder": "Simgeleri ara...",
"loadingMore": "Daha fazla simge yükleniyor...",
"allIconsLoaded": "Tüm {count} simge yüklendi",
"noIconsFound": "\"{search}\" için simge bulunamadı",
"tabs": {
"all": "Tüm Simgeler",
"popular": "Popüler",
"auth": "Kimlik Doğrulama Sağlayıcıları"
},
"stats": "{libraryCount} kütüphaneden {iconCount} simge",
"categoryBadge": "{category} ({count} simge)"
}
}

View File

@@ -1531,5 +1531,20 @@
"passwordRequired": "密码为必填项",
"nameRequired": "名称为必填项",
"required": "此字段为必填项"
},
"iconPicker": {
"title": "选择图标",
"placeholder": "选择一个图标",
"searchPlaceholder": "搜索图标...",
"loadingMore": "正在加载更多图标...",
"allIconsLoaded": "已加载全部 {count} 个图标",
"noIconsFound": "未找到与\"{search}\"相关的图标",
"tabs": {
"all": "所有图标",
"popular": "常用",
"auth": "认证提供商"
},
"stats": "来自 {libraryCount} 个库的 {iconCount} 个图标",
"categoryBadge": "{category}{count} 个图标)"
}
}

View File

@@ -70,6 +70,14 @@ export function EditProviderForm({
const [showClientSecret, setShowClientSecret] = useState(false);
const isOfficial = provider.isOfficial;
// Função para identificar providers oficiais que não devem ter o campo de provider URL editável
const isProviderUrlEditable = (providerName: string): boolean => {
const nonEditableProviders = ["google", "discord", "github"];
return !nonEditableProviders.includes(providerName.toLowerCase());
};
const canEditProviderUrl = isProviderUrlEditable(provider.name);
const updateFormData = (updates: Partial<typeof formData>) => {
const newFormData = { ...formData, ...updates };
setFormData(newFormData);
@@ -320,6 +328,7 @@ export function EditProviderForm({
{isOfficial && (
<div className="space-y-4">
{canEditProviderUrl ? (
<div>
<Label className="mb-2 block">{t("authProviders.form.providerUrl")} *</Label>
<Input
@@ -332,6 +341,7 @@ export function EditProviderForm({
/>
<p className="text-xs text-muted-foreground mt-1">{t("authProviders.form.officialProviderHelp")}</p>
</div>
) : null}
<div>
<Label className="mb-2 block">{t("authProviders.form.icon")}</Label>
<IconPicker

View File

@@ -98,9 +98,7 @@ export function ProviderRow({
{isEditing && (
<div className="border-t border-border dark:border-border p-4 space-y-4 bg-muted/50 dark:bg-muted/20">
<div className="flex items-center justify-between">
<h3 className="font-medium text-foreground dark:text-foreground">
Editar Provider: {provider.displayName}
</h3>
<h3 className="font-medium text-foreground dark:text-foreground">{provider.displayName}</h3>
</div>
<EditProviderForm
key={provider.id}

View File

@@ -2,6 +2,7 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, Search, X } from "lucide-react";
import { useTranslations } from "next-intl";
import * as AiIcons from "react-icons/ai";
import * as BiIcons from "react-icons/bi";
import * as BsIcons from "react-icons/bs";
@@ -85,6 +86,7 @@ interface VirtualizedIconGridProps {
}
function VirtualizedIconGrid({ icons, onIconSelect, renderIcon, showCategories = false }: VirtualizedIconGridProps) {
const t = useTranslations("iconPicker");
const [visibleCount, setVisibleCount] = useState(ICONS_PER_BATCH);
const [isLoading, setIsLoading] = useState(false);
const scrollRef = useRef<HTMLDivElement>(null);
@@ -153,7 +155,10 @@ function VirtualizedIconGrid({ icons, onIconSelect, renderIcon, showCategories =
{iconsByCategory.map(([category, categoryIcons]) => (
<div key={category}>
<Badge variant="secondary" className="text-xs mb-3">
{category} ({icons.filter((icon) => icon.category === category).length} icons)
{t("categoryBadge", {
category,
count: icons.filter((icon) => icon.category === category).length,
})}
</Badge>
<div className="grid grid-cols-8 sm:grid-cols-12 lg:grid-cols-16 xl:grid-cols-20 gap-2 sm:gap-3">
{categoryIcons.map((icon) => (
@@ -172,10 +177,10 @@ function VirtualizedIconGrid({ icons, onIconSelect, renderIcon, showCategories =
{/* Loading indicator and sentinel */}
<div ref={sentinelRef} className="flex justify-center py-4">
{isLoading && <div className="text-sm text-muted-foreground">Carregando mais ícones...</div>}
{isLoading && <div className="text-sm text-muted-foreground">{t("loadingMore")}</div>}
{visibleCount >= icons.length && icons.length > 0 && (
<div className="text-sm text-muted-foreground">
Todos os {icons.length.toLocaleString()} ícones carregados
{t("allIconsLoaded", { count: icons.length.toLocaleString() })}
</div>
)}
</div>
@@ -202,10 +207,10 @@ function VirtualizedIconGrid({ icons, onIconSelect, renderIcon, showCategories =
{/* Loading indicator and sentinel */}
<div ref={sentinelRef} className="flex justify-center py-4">
{isLoading && <div className="text-sm text-muted-foreground">Carregando mais ícones...</div>}
{isLoading && <div className="text-sm text-muted-foreground">{t("loadingMore")}</div>}
{visibleCount >= icons.length && icons.length > 0 && (
<div className="text-sm text-muted-foreground">
Todos os {icons.length.toLocaleString()} ícones carregados
{t("allIconsLoaded", { count: icons.length.toLocaleString() })}
</div>
)}
</div>
@@ -271,10 +276,14 @@ const AUTH_PROVIDER_ICONS = [
"AiOutlineSecurityScan",
];
export function IconPicker({ value, onChange, placeholder = "Select an icon" }: IconPickerProps) {
export function IconPicker({ value, onChange, placeholder }: IconPickerProps) {
const t = useTranslations("iconPicker");
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
// Use translation for placeholder if not provided
const displayPlaceholder = placeholder || t("placeholder");
// Combine ALL icon libraries
const allIcons = useMemo(() => {
const iconSets = [
@@ -388,7 +397,7 @@ export function IconPicker({ value, onChange, placeholder = "Select an icon" }:
<span className="text-sm">{currentIcon.name}</span>
</>
) : (
<span className="text-muted-foreground">{placeholder}</span>
<span className="text-muted-foreground">{displayPlaceholder}</span>
)}
</div>
<ChevronDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
@@ -397,9 +406,12 @@ export function IconPicker({ value, onChange, placeholder = "Select an icon" }:
<DialogContent className="max-w-5xl xl:max-w-6xl max-h-[90vh] overflow-hidden">
<div className="space-y-4 overflow-hidden">
<div className="flex items-center justify-between">
<DialogTitle>Selecionar Ícone</DialogTitle>
<DialogTitle>{t("title")}</DialogTitle>
<div className="text-sm text-muted-foreground">
{allIcons.length.toLocaleString()} ícones de {categories.length} bibliotecas
{t("stats", {
iconCount: allIcons.length.toLocaleString(),
libraryCount: categories.length,
})}
</div>
</div>
@@ -407,7 +419,7 @@ export function IconPicker({ value, onChange, placeholder = "Select an icon" }:
<div className="relative">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
placeholder="Buscar ícones..."
placeholder={t("searchPlaceholder")}
value={search}
onChange={(e) => setSearch(e.target.value)}
className="pl-8"
@@ -426,9 +438,9 @@ export function IconPicker({ value, onChange, placeholder = "Select an icon" }:
<Tabs defaultValue="all" className="w-full overflow-hidden">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="all">Todos os Ícones</TabsTrigger>
<TabsTrigger value="popular">Populares</TabsTrigger>
<TabsTrigger value="auth">Auth Providers</TabsTrigger>
<TabsTrigger value="all">{t("tabs.all")}</TabsTrigger>
<TabsTrigger value="popular">{t("tabs.popular")}</TabsTrigger>
<TabsTrigger value="auth">{t("tabs.auth")}</TabsTrigger>
</TabsList>
{/* All Icons */}
@@ -478,7 +490,7 @@ export function IconPicker({ value, onChange, placeholder = "Select an icon" }:
{search && filteredIcons.length === 0 && (
<div className="text-center py-8 text-muted-foreground">
<Search className="mx-auto h-12 w-12 opacity-50 mb-2" />
<p>Nenhum ícone encontrado para "{search}"</p>
<p>{t("noIconsFound", { search })}</p>
</div>
)}
</div>