Files
base_abp/CHANGELOG.md

377 lines
23 KiB
Markdown

# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Fixed
- **Users Table Display and React Warnings (2025-10-19)**
- Fixed React DOM warnings about unrecognized props `searchableColumnCount` and `filterableColumnCount` in DataTableSkeleton
- Updated `users-table.tsx` and `users/page.tsx` to use correct `filterCount` prop instead
- Fixed ABP response unwrapping in axios interceptor - responses were not being unwrapped correctly
- Added `isAbpResponse()` helper function that detects ABP format without requiring `__abp` flag
- Interceptor now automatically detects and unwraps ABP responses with structure: `{ result, success, targetUrl, error, unAuthorizedRequest }`
- Users table now correctly displays data from API instead of showing empty rows
- **Improves**: React console cleanliness and TanStack Table data binding with ABP backend
### Changed
- **Users Table Code Quality Improvements (2025-10-19)**
- Removed unnecessary `useMemo` wrapper for static column definitions (performance optimization)
- Implemented `UsersTableContext` for proper mutation success handling and data refetching
- Created `users-table-context.tsx` with `UsersTableProvider` and `useUsersTable` hook
- Actions dropdown now properly triggers table refresh after mutations (activate, deactivate, delete, edit)
- Improved error type safety: added `ApiError` interface and `isApiError()` type guard
- Replaced all `(error as any)` casts with proper type checking
- Enhanced avatar initials with defensive fallback: name → surname → username → '?'
- Removed unused `handleMutationSuccess` function (replaced with context)
- Removed unused `UsersTableWithActions` export wrapper
- Better separation of concerns: mutation handlers now use React Context instead of prop drilling
- **Benefits**: Type-safe error handling, automatic table refresh on mutations, cleaner code architecture
- **Authentication Flow with Auth.js Session (2025-10-19)**
- Fixed critical authentication issue where API requests were not sending Authorization header
- Axios interceptor now retrieves JWT token from **Auth.js session** instead of localStorage
- Updated `src/lib/api-client/abp-axios.ts` to use `getSession()` from next-auth/react (client-side only)
- Fixed server-side execution error: interceptor now detects client vs server environment
- Client-side: uses `getSession()` to retrieve token from Auth.js session
- Added 2-second timeout to `getSession()` to prevent hanging on unauthenticated pages
- Server-side: falls back to localStorage (empty during initial login, which is expected)
- Fixed `Abp.TenantId` header logic: only sent when user is a tenant (not HOST)
- Added validation for tenant ID: only sends header if value is valid number/numeric string
- For HOST users (no tenant), `tenantId` is `null` and header is not sent
- Updated `src/auth.ts` to capture and store tenant ID in JWT session callback
- Created `src/types/next-auth.d.ts` with TypeScript type definitions for extended session
- Updated `src/contexts/auth-context.tsx` to use correct session path (`session.user.accessToken`)
- Token flow: Login → Auth.js session → Axios interceptor → Backend API
- Maintains localStorage fallback for backward compatibility
- **IMPORTANT**: This fixes 401 Unauthorized errors in Users module and all protected endpoints
### Added
- **Dynamic Dashboard Page (2025-10-18)**
- Created new `/dashboard/dynamicDashboard` route with 3 charts (area, bar, and pie graphs)
- Implemented Next.js parallel routes pattern (@area_stats, @bar_stats, @pie_stats)
- Added "Dynamic Dashboard" navigation item to sidebar with keyboard shortcut (d + y)
- Included 3 metric cards: Total Revenue, Active Users, and Conversion Rate
- Responsive grid layout optimized for desktop and mobile views
- **TweakCN Themes Integration (2025-10-18)**
- Created `tweakcn-themes.css` with dual theme system (traditional + TweakCN)
- Added 5 complete TweakCN theme palettes:
* **Cosmic Night**: Purple/violet palette with cosmic aesthetic
* **Rose Pine**: Soft rose/pink tones for elegant interfaces
* **Nord**: Cool blue palette inspired by Arctic aurora
* **Catppuccin**: Warm amber/yellow tones for cozy feel
* **Indigo Dream**: Elegant indigo/purple palette with vibrant accents
- Each theme includes complete light/dark mode variables
- Full compatibility with existing shadcn/ui components
- Integrated shadow system to globals.css:
* 8 shadow levels (2xs, xs, sm, md, lg, xl, 2xl, default)
* Optimized for both light and dark modes
* Accessible via Tailwind utilities and CSS variables
- Added font family tokens:
* `--font-sans`, `--font-serif`, `--font-mono`
* Available in @theme inline for Tailwind integration
- Updated ThemeSwitcher component:
* New "TweakCN Themes" section in dropdown
* Visual color previews for each theme
* Organized by category (Default, Scaled, Monospaced, TweakCN)
- Full oklch color space support for better color consistency
- All themes include complete token sets:
* Semantic colors (background, foreground, primary, secondary)
* Component colors (card, popover, sidebar variants)
* Functional colors (destructive, accent, border, input, ring)
* Chart colors (chart-1 through chart-5)
- **Kubb Integration for API Code Generation (2025-10-17)**
- Migrated from `@hey-api/openapi-ts` to **Kubb** for comprehensive API client generation
- Integrated **TanStack React Query (v5)** for server state management with automatic caching and refetching
- Generated React Query hooks (useQuery, useMutation) from OpenAPI spec in `src/api/hooks/`
- Generated Zod validation schemas from OpenAPI spec in `src/api/zod/`
- Generated TypeScript types in `src/api/types/`
- Generated Axios client functions in `src/api/client/`
- Created `kubb.config.ts` with ABP-optimized configuration:
- Custom query keys based on operation ID and parameters
- Infinite query support for pagination (skipCount parameter)
- Zod parser integration for response validation
- Custom axios client with ABP interceptors
- Created `src/lib/api-client/abp-axios.ts` - ABP-configured axios client with interceptors:
- Automatic JWT Bearer token injection from localStorage or Auth.js session
- Automatic `Abp.TenantId` header for multi-tenancy
- **Automatic ABP result unwrapping** (`{ result, success, error }``result`)
- Error handling with toast notifications
- Automatic redirect to login on 401 unauthorized
- Created `src/lib/api-client/abp-hooks.ts` - ABP helper hooks:
- `useAbpMutation()` - Enhanced mutation with success/error toasts and cache invalidation
- `getAbpPaginationParams()` - Convert page/pageSize to ABP's skipCount/maxResultCount
- `getTotalPages()` - Calculate total pages from ABP paged result
- `formatAbpValidationErrors()` - Format validation errors for display
- Created `src/lib/react-query/query-client.ts` - React Query client configuration:
- 5-minute stale time
- 10-minute cache time
- Retry logic with exponential backoff
- Refetch on window focus
- Updated `src/components/layout/providers.tsx` to include QueryClientProvider
- Added React Query DevTools for development debugging
- Created `src/features/examples/api-usage-example.tsx` - Example component demonstrating:
- Query hooks with pagination
- Mutation hooks with ABP helper
- Direct mutations with cache invalidation
- Delete mutations with confirmation
- Optimistic updates pattern
- Created `src/lib/auth/index.ts` - Consolidated exports for all auth utilities
- Re-exports JWT token management from `src/lib/auth.ts`
- Re-exports all utilities from auth directory (jwt-decoder, providers, cache, dynamic-providers)
- Allows clean imports: `import { decodeJwt, getAuthToken } from '@/lib/auth'`
- Created comprehensive API documentation in `src/api/README.md`:
- Quick start guide
- Query patterns (basic, paginated, with refetch)
- Mutation patterns (create, update, delete)
- Optimistic updates examples
- ABP-specific features documentation
- Type imports and Zod validation usage
- Infinite queries for scroll pagination
- Server-side rendering examples
- Updated `package.json` scripts:
- `generate:api` now uses Kubb instead of Orval
- Changed backend URL from 44314 to 44312
- Kept `generate:api:legacy` for backwards compatibility
- Created `AUTH_MODULE_STRUCTURE.md` - Comprehensive documentation of authentication architecture:
- Explains dual auth system (Auth.js for OIDC + ABP JWT)
- Documents all auth-related files and their purposes
- Usage examples for each utility
- Import patterns and best practices
- Created `GIT_TRACKING_GUIDE.md` - Guide for Git workflow with generated files:
- Which files to commit vs ignore
- Explanation of generated vs infrastructure files
- Workflow recommendations for team development
- CI/CD pipeline examples
- Created `MIGRATION_CLEANUP.md` - Documents migration from @hey-api to Kubb:
- Cleanup status and verification steps
- Comparison table of features
- Benefits of Kubb over hey-api
- Updated `CLAUDE.md` with Kubb documentation:
- Complete API Integration section with Kubb + React Query
- Usage examples for queries, mutations, and server-side fetching
- ABP integration features documentation
- Zod integration for form validation
- Important files section updated with Kubb-related files
- Updated tech stack and version information
- **Dependencies added:**
- `@kubb/cli@4.1.3`
- `@kubb/core@4.1.3`
- `@kubb/plugin-client@4.1.3`
- `@kubb/plugin-oas@4.1.3`
- `@kubb/plugin-react-query@4.1.3`
- `@kubb/plugin-ts@4.1.3`
- `@kubb/plugin-zod@4.1.3`
- `@tanstack/react-query@5.90.5` (updated from 5.90.2)
- **Benefits:**
- ✅ Full type-safety with TypeScript, Zod validation, and typed hooks
- ✅ React Query automatic caching, refetching, and optimistic updates
- ✅ Native ABP integration with result unwrapping and error handling
- ✅ Reduced boilerplate code with auto-generated hooks
- ✅ Better developer experience with IntelliSense and DevTools
- ✅ Single source of truth from OpenAPI specification
- **Dynamic OIDC Provider Configuration (Portainer-style)**
- Implemented runtime dynamic provider loading from database without rebuild
- Auth.js v5 lazy initialization fetches providers on each request (with caching)
- Created `src/lib/auth/dynamic-providers.ts` to fetch and convert backend providers to Auth.js format
- Created `src/lib/auth/provider-cache.ts` with Next.js unstable_cache (15-minute TTL)
- Fallback memory cache for resilience when Next.js cache unavailable
- Manual cache invalidation via `revalidateProviderCache()` after admin changes
- **Admin UI for Provider Management**
- Created `/dashboard/settings/auth-providers` page for CRUD operations on auth providers
- Full-featured provider table with enable/disable, test connection, edit, and delete actions
- Create/Edit dialog with form validation (Zod schema)
- Supports OIDC, OAuth2, and SAML (future) provider types
- Real-time configuration with automatic cache invalidation
- Provider display order configuration for sign-in page
- Claim mappings editor (JSON format)
- Security: Client secrets shown masked, only updated when changed
- **Dynamic Sign-In Provider Buttons**
- Updated `CustomSignInForm` to fetch providers from `getCachedProvidersForUI()`
- Dynamically renders OAuth buttons based on enabled providers in database
- No more hardcoded provider buttons (e.g., removed hardcoded Authentik)
- Generic `handleOAuthSignIn()` works with any provider
- Loading states and error handling for provider fetch
- Providers sorted by displayOrder from database
- **Auth.js Credentials Provider Integration**
- Integrated Auth.js (NextAuth.js v5) with Credentials provider for direct login with backend
- Users can now log in using username/password through Auth.js authentication
- Credentials provider calls ASP.NET Core `/api/TokenAuth/Authenticate` endpoint
- Seamless integration with existing OIDC providers (Authentik, etc.)
- Single authentication system supporting both credentials and external OIDC providers
- **Authentik SSO Button in Sign-In Page**
- Added "Sign in with Authentik" button to the main login page
- Users can choose between traditional credentials or SSO authentication
- Visual separator between credentials and OAuth login options
- Consistent design with shadcn-ui components
- Automatic redirect to callback URL after successful OAuth authentication
- **Auth.js (NextAuth.js v5) Integration for SSO**
- Configured Auth.js with OIDC provider support for external authentication
- Created `/testSSO` page for testing Single Sign-On with Authentik
- Implemented token exchange flow: Authentik OIDC → Backend JWT
- Added automatic token refresh when backend JWT expires
- **JWT Utilities**
- Created `src/lib/auth/jwt-decoder.ts` with JWT parsing and validation functions
- Created `src/lib/auth/token-exchange.ts` for external token exchange with backend
- Functions: `decodeJwt()`, `isTokenExpired()`, `getTokenTtl()`, `formatTokenTtl()`
- User info extraction from JWT tokens
- **Test SSO Components**
- Created `AuthStatusCard` component to display current authentication state
- Created `TokenViewer` component to inspect and decode JWT tokens with accordion UI
- Created `AuthentikButton` component for sign-in/sign-out with Authentik
- All components use shadcn-ui for consistent styling
- **External Authentication Support**
- Extended `AuthContext` with `loginWithExternal()` method
- Support for both traditional (username/password) and OIDC authentication
- Unified token management for both authentication methods
- **Auth.js Configuration**
- Created `src/auth.ts` with Auth.js configuration and callbacks
- Created `src/app/api/auth/[...nextauth]/route.ts` for Auth.js API routes
- JWT callback performs token exchange with backend on initial sign-in
- Session callback exposes backend JWT to client
- Automatic token refresh before expiration (5-minute threshold)
- **Provider Configuration UI**
- Created `ProviderConfigCheck` component to display backend provider status
- Automatically fetches enabled providers from backend API
- Shows configuration issues and setup instructions in real-time
- Provides SQL script helper values for easy setup
- **Backend Integration**
- Created `providers.ts` helper to fetch provider config from backend
- Function `getEnabledProviders()` calls `ExternalAuthProviderAppService`
- Dynamic provider loading from database
- **Documentation and Setup**
- Updated `env.example.txt` with Auth.js and Authentik configuration variables
- Added instructions for generating AUTH_SECRET
- Documented Authentik OIDC provider setup steps
- Created `setup-authentik-provider.sql` script for easy database setup
- Added comprehensive troubleshooting guide
- Explained hybrid approach (backend config + env vars)
- **TypeScript Type Generation from OpenAPI**
- Added `@hey-api/openapi-ts` for automatic type generation from backend Swagger spec
- Created `openapi-ts.config.ts` configuration using local swagger.json file (avoids SSL certificate issues)
- Added `pnpm generate:api` script that downloads swagger.json and generates types
- Added `pnpm generate:api:download` to download swagger.json from backend
- Added `pnpm generate:api:types` to generate types from local file
- Generated API client in `src/client/` with full type-safety
- Added `swagger.json` to `.gitignore` (temporary file)
- **JWT Authentication Helpers**
- Created `src/lib/auth.ts` with token management functions
- `getAuthToken()`, `setAuthTokens()`, `clearAuthToken()` helpers
- Multi-tenancy support with `getTenantId()` and `setTenantId()`
- User info storage helpers
- **Configured API Client**
- Created `src/lib/api/client.ts` with ASP.NET Boilerplate interceptors
- Automatic `Authorization: Bearer` header injection
- Automatic `Abp.TenantId` header for multi-tenancy
- Response unwrapping for ABP format (`{ result, success, error }`)
- Error handling and automatic redirect on unauthorized requests
- **Documentation**
- Created `src/lib/api/README.md` with comprehensive usage examples
- Created `TROUBLESHOOTING.md` with solutions to common issues
- Updated `CLAUDE.md` with TypeScript type generation workflow
- Added OpenAPI client documentation and benefits
- Documented SSL certificate workaround for localhost development
- **Project Setup**
- Added `src/client/` to `.gitignore` (generated files)
- Created `CLAUDE.md` with comprehensive project documentation for Claude Code
- Project overview and architecture description
- Common commands for both .NET backend and Next.js frontend
- Key concepts (Dynamic OIDC, Multi-tenancy, Database configuration)
- Development workflow guidelines
- Important files reference
- Version information
- Created `CHANGELOG.md` to track all project changes
- Added changelog management rules to `CLAUDE.md`
### Removed
- Removed Clerk authentication dependencies (`@clerk/nextjs`, `@clerk/themes`)
- Removed Clerk configuration from project (replaced with native JWT authentication)
- Removed all Clerk-related components and hooks from the codebase
- Removed Clerk references from `.gitignore`
### Fixed
- **Fixed .gitignore blocking entire Web.Ui directory (2025-10-17)**
- Root `.gitignore` had `src/ASPBaseOIDC.Web.Ui/` on line 260 ignoring all frontend files
- Removed that line and added explanatory comment
- Web.Ui directory has its own `.gitignore` for node_modules, .next, etc.
- All new infrastructure files now properly tracked in Git
- Generated files (`src/api/`) correctly ignored by local .gitignore
- **Fixed Middleware Authentication Protection (Critical Security Fix)**
- Fixed `authorized` callback in `auth.ts` that was allowing unauthenticated access by default
- Changed default behavior from `return true` (allow all) to `return isLoggedIn` (require auth)
- Middleware now properly requires authentication for ALL routes by default (except public routes)
- Added explicit list of public routes that don't require authentication
- Root path (`/`) now redirects to dashboard if authenticated, or sign-in if not
- Authenticated users trying to access auth pages are redirected to dashboard
- All other routes now properly require authentication before access
- **IMPORTANT**: Restart dev server after this change for it to take effect
- Fixed import path for generated API client (use `@/client/client.gen` instead of `@/client`)
- Resolved "Export client doesn't exist" error in auth-context.tsx
- Fixed SSL certificate issues when generating types from localhost by downloading swagger.json first
### Removed
- **Cleaned up legacy API generation system (2025-10-17)**
- Removed `@hey-api/openapi-ts` configuration file (`openapi-ts.config.ts`)
- Deleted error logs from old openapi-ts attempts (3 files)
- Updated `.gitignore` to only reference Kubb (`/src/api/`) instead of old client path
- Removed `/src/client` reference from .gitignore (no longer generated)
- System now uses **only Kubb** for API code generation
### Changed
- **Improved Theme Toggle Animation with Polygon Effect (2025-10-18)**
- Updated `ModeToggle` component with diagonal wipe animation (polygon effect)
- Added `wipe-in-dark` and `wipe-in-light` keyframes to `globals.css`
- Animation direction changes based on target theme:
- Light → Dark: wipes from left to right
- Dark → Light: wipes from right to left
- Uses View Transitions API with `@supports` feature detection
- Dynamic CSS injection for animation switching
- Maintains fallback for browsers without View Transitions support
- Same button and functionality, enhanced visual transition
- **Improved Theme Selector UI (2025-10-17)**
- Created new `ThemeSwitcher` component using DropdownMenu instead of Select
- Visual color previews for each theme option (3 color swatches per theme)
- Check icon indicator for currently active theme
- Improved UX with dropdown menu interface similar to modern design systems
- Grouped themes by category: Default, Scaled, and Monospaced
- Replaced `ThemeSelector` with `ThemeSwitcher` in Header component
- Maintains all existing functionality with `useThemeConfig()` hook
- **Auth.js Migrated to Lazy Initialization**
- Refactored `src/auth.ts` from static configuration to lazy initialization pattern
- `NextAuth()` now accepts async function that fetches providers dynamically
- Credentials provider always included alongside dynamic OIDC providers
- Providers array built at runtime: `[credentialsProvider, ...dynamicProviders]`
- Benefits: zero-downtime provider updates, multi-tenant ready, no hardcoded configs
- **Migrated to Auth.js for All Authentication**
- Updated `custom-sign-in-form.tsx` to use `signIn()` from `next-auth/react` instead of custom login
- Updated `auth-context.tsx` to use `useSession()` hook from Auth.js
- Updated `middleware.ts` to use Auth.js middleware for route protection
- Updated `lib/api/client.ts` to retrieve tokens from Auth.js session
- Modified `auth.ts` to support both Credentials and OIDC authentication methods
- JWT callback handles both credential-based and OIDC-based authentication flows
- Session callback exposes tokens (accessToken, encryptedAccessToken) to client
- Changed login page redirect from `/testSSO` to `/auth/sign-in`
- **Complete Authentication System Replacement**
- Replaced Clerk authentication with custom JWT-based authentication system
- Created `AuthProvider` and `useAuth` hook to manage authentication state
- Updated all components to use `useAuth` instead of Clerk's `useUser`
- Frontend now stores JWT tokens in localStorage instead of using Clerk
- Updated development workflow to include type generation step after backend changes
- **Custom Authentication Components**
- Created `CustomSignInForm` component replacing Clerk's SignIn
- Created `CustomSignUpForm` component replacing Clerk's SignUp
- Created `CustomUserProfile` component replacing Clerk's UserProfile
- Updated sign-in-view.tsx, sign-up-view.tsx, and profile-view-page.tsx to use custom components
- **Route Protection**
- Implemented Next.js middleware for route protection
- Middleware handles authentication redirects and route guards
- Simplified page.tsx files to rely on middleware for auth checks
- **Component Updates**
- Updated `providers.tsx` to use `AuthProvider` instead of `ClerkProvider`
- Updated `user-nav.tsx` to use `useAuth` hook with custom logout functionality
- Updated `app-sidebar.tsx` to use `useAuth` hook
- Maintained existing UI/UX while swapping authentication providers