Problem
- Starting OAuth from Discourse hit GET /api/oauth/authorize and 302’d to /login?next=/oauth/consent…
- The login page and AuthRedirect always navigated to /console when a session existed, ignoring next, which aborted the OAuth flow and dropped users in the console.
Changes
- Backend (src/oauth/server.go)
- When not logged in, redirect directly to /oauth/consent?<original_query> instead of /login?next=…
- Keep no-store headers; preserve the original authorize querystring.
- Frontend
- web/src/helpers/auth.jsx: AuthRedirect now honors the login page’s next query param and only redirects to safe internal paths (starts with “/”, not “//”); otherwise falls back to /console.
- web/src/components/auth/LoginForm.jsx: After successful login and after 2FA success, navigate to next when present and safe; otherwise go to /console.
Result
- The OAuth authorize flow now reliably reaches the consent screen.
- On approval, the server issues an authorization code and 302’s back to the client’s redirect_uri (e.g., Discourse), completing SSO as expected.
Security
- Sanitize next to avoid open-redirects by allowing only same-origin internal paths.
Compatibility
- No behavior change for normal username/password sign-ins outside the OAuth flow.
- No changes to token/userinfo endpoints.
Testing
- Manually verified end-to-end with Discourse OAuth2 Basic:
- authorize → consent → approve → redirect with code
- Lint checks pass for modified files.
Why
- First-time “Initialize Keys” caused a nil pointer panic when adding the first JWK to a nil JWKS set.
- As a result, the returned kid was missing and the first key appeared as “historical” until a second rotation.
- Improve first-time UX: only show Key Management when the server is healthy and guide admins to the correct init flow.
Backend (bug fix)
- src/oauth/server.go
- RotateSigningKey / GenerateAndPersistKey / ImportPEMKey:
- If simpleJWKSSet is nil, create a new jwk.NewSet() before AddKey, otherwise AddKey as usual.
- Ensure currentKeyID is updated; enforceKeyRetention remains unchanged.
- This prevents the nil pointer panic, ensures the first key is added to JWKS, and is immediately the current key.
Frontend (UX)
- web/src/components/settings/oauth2/OAuth2ServerSettings.jsx
- Show “Key Management” only when OAuth2 is enabled AND server is healthy (serverInfo present).
- Refine the warning banner text to instruct: enable OAuth2 & SSO → Save configuration → Key Management → Initialize Keys.
- web/src/components/settings/oauth2/modals/JWKSManagerModal.jsx
- Dynamic primary action in “Key List” tab:
- No keys → “Initialize Keys”
- Has keys → “Rotate Keys”
- Simplify error handling by relying on `message` + localized fallback.
Notes
- No API surface changes; functional bugfix plus UI/UX improvements.
- Linting passed; no new warnings.
Test plan
1) Start with OAuth2 enabled and no signing keys.
2) Open “Key Management” → click “Initialize Keys”.
3) Expect: success response with new kid; table shows the new kid as Current; JWKS endpoint returns the key; no server panic.
This commit consolidates OAuth2 client management components and
enhances the overall user experience with improved UI consistency.
### Major Changes:
**Component Consolidation:**
- Merge CreateOAuth2ClientModal.jsx and EditOAuth2ClientModal.jsx into OAuth2ClientModal.jsx
- Extract inline Modal.info into dedicated ClientInfoModal.jsx component
- Adopt consistent SideSheet + Card layout following EditTokenModal.jsx style
**UI/UX Improvements:**
- Replace custom client type selection with SemiUI RadioGroup component
- Use 'card' type RadioGroup with descriptive 'extra' prop for better UX
- Remove all Row/Col components in favor of flexbox and margin-based layouts
- Refactor redirect URI section to mimic JSONEditor.jsx visual style
- Add responsive design support for mobile devices
**Form Enhancements:**
- Add 'required' attributes to all mandatory form fields
- Implement placeholders for grant types, scopes, and redirect URI inputs
- Set grant types and scopes to default empty arrays
- Add dynamic validation and conditional rendering for client types
- Improve redirect URI management with template filling functionality
**Bug Fixes:**
- Fix SideSheet closing direction consistency between create/edit modes
- Resolve client_type submission issue (object vs string)
- Prevent "Client Credentials" selection for public clients
- Fix grant type filtering when switching between client types
- Resolve i18n issues for API scope options (api:read, api:write)
**Code Quality:**
- Extract RedirectUriCard as reusable sub-component
- Add comprehensive internationalization support
- Implement proper state management and form validation
- Follow single responsibility principle for component separation
**Files Modified:**
- web/src/components/settings/oauth2/modals/OAuth2ClientModal.jsx
- web/src/components/settings/oauth2/modals/ClientInfoModal.jsx (new)
- web/src/components/settings/oauth2/OAuth2ClientSettings.jsx
- web/src/i18n/locales/en.json
**Files Removed:**
- web/src/components/settings/oauth2/modals/CreateOAuth2ClientModal.jsx
- web/src/components/settings/oauth2/modals/EditOAuth2ClientModal.jsx
This refactoring significantly improves code maintainability, reduces
duplication, and provides a more consistent and intuitive user interface
for OAuth2 client management.
- Refactor JWKSManagerModal with tab-based navigation using Card components
- Add comprehensive i18n support with English translations for all text
- Optimize header actions: refresh button only appears in key list tab
- Improve responsive design using ResponsiveModal component
- Move cautionary text from bottom to Card titles for better visibility
- Update button styles: danger type for delete, circle shape for status tags
- Standardize code formatting (single quotes, multiline formatting)
- Enhance user workflow: separate Import PEM and Generate PEM operations
- Remove redundant cancel buttons as modal already has close icon
Breaking changes: None
Affects: JWKS key management, OAuth2 settings UI
- **Empty Component Enhancement:**
- Replace custom User icon with professional IllustrationNoResult from Semi Design
- Add dark mode support with IllustrationNoResultDark component
- Standardize illustration size to 150x150px for consistency
- Add proper padding (30px) to match design system standards
- **Style Modernization:**
- Convert inline styles to Tailwind CSS classes where appropriate
- Replace `style={{ marginBottom: 16 }}` with `className='mb-4'`
- Remove redundant `style={{ marginTop: 8 }}` from Table component
- Remove custom `style={{ marginTop: 16 }}` from pagination and button
- **Pagination Simplification:**
- Simplify showTotal configuration from custom function to boolean `true`
- Remove unnecessary `size='small'` property from pagination
- Clean up pagination styling for better consistency
- **Design System Alignment:**
- Ensure Empty component matches UsersTable styling patterns
- Improve visual consistency across OAuth2 management interfaces
- Follow Semi Design illustration guidelines for empty states
- **Code Quality:**
- Reduce inline style usage in favor of utility classes
- Simplify component props where default behavior is sufficient
- Maintain functionality while improving maintainability
This update enhances visual consistency and follows modern React styling practices while maintaining all existing functionality.
- **Table Layout Optimization:**
- Remove description column from OAuth2 client table to save space
- Add tooltip on client name hover to display full description
- Adjust table scroll width from 1200px to 1000px for better layout
- Improve client name column width to 180px for better readability
- **Action Button Simplification:**
- Replace icon-only buttons with text labels for better accessibility
- Simplify Popconfirm content by removing complex styled layouts
- Remove unnecessary Tooltip wrappers around action buttons
- Clean up unused Lucide icon imports (Edit, Key, Trash2)
- **Code Display Enhancement:**
- Replace basic <pre> tags with CodeViewer component in modal dialogs
- Add syntax highlighting for JSON content in ServerInfoModal and JWKSInfoModal
- Implement copy-to-clipboard functionality for server info and JWKS data
- Add performance optimization for large content display
- Provide expandable/collapsible interface for better UX
- **Component Architecture:**
- Import and integrate CodeViewer component in both modal components
- Set appropriate props: content, title, and language='json'
- Maintain loading states and error handling functionality
- **Internationalization:**
- Add English translations for new UI elements:
* '暂无描述': 'No description'
* 'OAuth2 服务器配置': 'OAuth2 Server Configuration'
* 'JWKS 密钥集': 'JWKS Key Set'
- **User Experience Improvements:**
- Enhanced tooltip interaction for description display
- Better visual feedback with cursor-help styling
- Improved code readability with professional dark theme
- Consistent styling across all OAuth2 management interfaces
This update focuses on UI/UX improvements while maintaining full functionality and adding modern code viewing capabilities to the OAuth2 management system.
- **UI Restructuring:**
- Separate client info into individual table columns (name, ID, description)
- Replace icon-only action buttons with text labels for better UX
- Adjust table scroll width from 1000px to 1200px for new column layout
- Remove unnecessary Tooltip wrappers and Lucide icons (Edit, Key, Trash2)
- **Component Architecture:**
- Extract all modal dialogs into separate reusable components:
* SecretDisplayModal.jsx - for displaying regenerated client secrets
* ServerInfoModal.jsx - for OAuth2 server configuration info
* JWKSInfoModal.jsx - for JWKS key set information
- Simplify main component by removing ~60 lines of inline modal code
- Implement proper state management for each modal component
- **Code Quality:**
- Remove unused imports and clean up component dependencies
- Consolidate modal logic into dedicated components with error handling
- Improve code maintainability and reusability across the application
- **Internationalization:**
- Add English translation for '客户端名称': 'Client Name'
- Remove duplicate translation keys to fix linter warnings
- Ensure all new components support full i18n functionality
- **User Experience:**
- Enhance table readability with dedicated columns for each data type
- Maintain copyable client ID functionality in separate column
- Improve action button accessibility with clear text labels
- Add loading states and proper error handling in modal components
This refactoring improves code organization, enhances user experience, and follows React best practices for component composition and separation of concerns.
- Add responsive layout for user info section with flex-col on mobile
- Optimize button layout: vertical stack on mobile, horizontal on desktop
- Implement mobile-first approach with sm: breakpoints throughout
- Adjust container width: max-w-sm on mobile, max-w-lg on desktop
- Enhance touch targets with larger buttons (size='large') on mobile
- Improve content hierarchy with primary action button on top for mobile
- Add responsive padding and spacing: px-3 sm:px-4, py-6 sm:py-8
- Optimize text sizing: text-sm sm:text-base for better mobile readability
- Implement responsive gaps: gap-4 sm:gap-6 for icon spacing
- Add break-all class for long URL text wrapping
- Adjust meta info card spacing and dot separator sizing
- Ensure consistent responsive padding across all content sections
This update significantly improves the mobile user experience while
maintaining the desktop layout, following mobile-first design principles
with Tailwind CSS responsive utilities.
- Redesign OAuth consent page layout with centered card design
- Implement GitHub-style authorization flow presentation
- Add application popover with detailed information on hover
- Replace generic icons with scope-specific icons (email, profile, admin, etc.)
- Integrate i18n support for all hardcoded strings
- Optimize permission display with encapsulated ScopeItem component
- Improve visual hierarchy with Semi UI Divider components
- Unify avatar sizes and implement dynamic color generation
- Move action buttons and redirect info to card footer
- Add separate meta information card for technical details
- Remove redundant color styles to rely on Semi UI theming
- Enhance user account section with clearer GitHub-style messaging
- Replace dot separators with Lucide icons for better visual consistency
- Add site logo with fallback mechanism for branding
- Implement responsive design with Tailwind CSS utilities
This redesign significantly improves the OAuth consent experience by following
modern UI patterns and providing clearer information hierarchy for users.