crypto.randomUUID() is only available in secure contexts (HTTPS).
Since the app runs over HTTP in development, this caused a blank page
crash on the external links admin page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Admin section moved to dedicated area with horizontal tab navigation
- Sidebar now shows gear icon link to Administration (PLATFORM_ADMIN only)
- External links management page for configuring sidebar shortcuts
- External links displayed in sidebar for all authenticated users
- Backend: Redis-based CRUD endpoints for external link configuration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SSO config (Tenant ID, Client ID, Client Secret, Redirect URI) can now
be managed entirely from the Admin SSO page. Config is stored in Redis
(persistent) and the MSAL client is reinitialized on save — no server
restart or console access required.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend-driven Authorization Code Flow with @azure/msal-node:
- EntraIdService: MSAL ConfidentialClientApplication, auth URL generation, token exchange
- SsoController: /auth/sso/microsoft (initiate) + /auth/sso/microsoft/callback (callback)
- AuthService.loginViaSso(): User provisioning (find by OID, auto-link by email, or create new)
- CSRF protection via state parameter stored in Redis
- SSO status endpoint for frontend feature detection
Frontend:
- "Mit Microsoft anmelden" button on login page (shown only when SSO is configured)
- SsoCallbackPage: handles redirect from backend, sets token, loads user profile
- AuthContext.loginWithToken(): new method for SSO token handling
Configuration:
- AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_REDIRECT_URI env vars
- docker-compose.yml updated to pass Azure vars to core service
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New UserFormModal component for creating and editing users
- AdminUsersPage: add "Neuer Benutzer" button, actions column
- German role labels, toggle activate/deactivate from table
- Uses React Query mutations with query invalidation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses sharp to resize and apply a circular SVG mask to the avatar
before embedding it in the Word document, matching the PDF export.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces text labels (Tel., Mobil, Mail, Adr.) with recolored PNG icons
in the Word export contact section. Sets Arial as default document font
to match Helvetica in the PDF export.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses pngjs to replace all visible pixels in PNG icons with the
configured accent color while preserving alpha transparency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Phone.png, Mobile.png, Mail.png, Address.png icon assets
- Replace hand-drawn vector icons with professional PNG icons
- Icons stored in packages/core-service/assets/icons/ (included in Docker build)
- Also stored in templates/cv/default/ and Icons/ for reference
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace disconnected rectangles+stroke with seamless shape:
earpiece and mouthpiece blocks connected by filled crescent arc
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Landline phone: classic telephone handset with earpiece, mouthpiece and curved connector
- Mobile phone: smartphone outline with display and home button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaced rough vector shapes with proper recognizable icons:
- Phone: smartphone outline with display area and home button
- Email: envelope with cleaner V-flap proportions
- Location: smooth teardrop map pin using bezier curves
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Professional CV-style document generation using pdfkit (PDF) and docx (Word).
Two-column layout with avatar, contact info, languages on the left and work
experience timeline on the right. Skills rendered as chips. Accent color
configurable (default teal #009688) for later admin customization.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Input fields now appear inline next to the section title, matching the
layout pattern used by Projects, Certifications and Attachments sections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full-stack implementation of the Expert Profile tab with 6 sections:
- Skills (tag/chip UI with add/remove)
- Experience (area, years, optional level)
- Languages (language + proficiency level)
- Project History (modal form with dates, role, tasks, company details)
- Certifications (modal form with title, issuer, website, year)
- Attachments (file upload/download as Base64, max 10MB)
Backend: 15 API endpoints, 8 DTOs, full CRUD service with ownership verification.
Frontend: Reusable Modal component (React Portal), ExpertProfileTab orchestrator, 8 section components.
Database: 6 new tables (expert_profiles, expert_experiences, expert_languages, expert_projects, expert_certifications, expert_attachments).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add phone, mobile, street, postalCode, city fields to User model (Prisma + migration)
- Extend UpdateUserDto with validated contact/address fields
- Update UsersService (findById, update, updateProfile) for new fields
- Rename tab "Persönliche Informationen" to "Profil"
- New layout: avatar left column, form right column with fieldset groups
- Move 2FA section from always-visible into "Passwort ändern" tab
- Add orange 2FA warning badge next to page title (clickable → password tab)
- Add responsive CSS for mobile breakpoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add twoFactorEnabled to LoginResponse user type
- Replace useBodyParser with express json() middleware for body limit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Bug fix: include twoFactorEnabled in login response so ProfilePage
shows correct 2FA status after login (not always "Aktivieren")
- Bug fix: restructure 2FA enable/disable handlers to separate API call
from state updates, preventing false error messages on success
- New: avatar field in User model (Base64 data-URL in PostgreSQL TEXT)
- New: UserAvatar component with initials fallback
- New: client-side image resize to 200x200px before upload
- New: avatar upload/remove on ProfilePage with preview
- New: avatar display + "Zum Profil" hint in sidebar
- Increase JSON body size limit to 1mb for avatar uploads
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The 2FA challenge response does not include a refreshToken (token is only
issued after successful 2FA verification). Making the field optional fixes
the TS2741 compilation error that prevented the core service from starting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The login endpoint was incorrectly storing the access token in the
refresh_token cookie. This caused silent refresh to fail after page
reload since the short-lived access token couldn't be used for refresh.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend:
- POST /auth/2fa/setup - generate TOTP secret + QR code (temp Redis storage)
- POST /auth/2fa/enable - verify TOTP code and activate 2FA
- POST /auth/2fa/disable - deactivate 2FA (requires password)
- PATCH /users/me - update own profile (firstName, lastName)
- POST /users/me/change-password - change own password
Frontend:
- New ProfilePage with 3 sections: personal info, password, 2FA
- QR code display for Authenticator app setup
- Clickable user info in sidebar navigates to /profile
- AuthContext extended with twoFactorEnabled + refreshUser
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Query() decorator always returns strings. Using Number() conversion
with fallback to defaults (page=1, limit=20) to prevent NaN errors
in Prisma findMany skip/take calculations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Environment variables are strings from process.env. Explicit
Type decorators ensure class-transformer converts them to numbers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix cookieParser import (default import instead of namespace)
- Cast tenant settings to Prisma.InputJsonValue for type safety
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bcrypt requires native compilation which was skipped by
--ignore-scripts. Added python3/make/g++ and npm rebuild bcrypt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Generate SSH deployment key (Ed25519) for server access
- Define complete server infrastructure (ProxmoxVE VM, Docker, networking)
- Create ACCESS.md with all connection details and SSH instructions
- Create INFRASTRUCTURE.md with VM setup guide and service architecture
- Set up project directory structure per briefing specification
- Add .env.example with all required environment variables
- Add .gitignore for Node.js/Docker/TypeScript project
- Create comprehensive README.md for developer onboarding
- Add Summarize.md changelog
- Include concept and briefing documents
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>