Commit graph

144 commits

Author SHA1 Message Date
Till-JS
a6fc1cb66e feat(onboarding): add Matrix onboarding bot for profile setup
- Add matrix-onboarding-bot service that guides users through profile setup
- Extend mana-core-auth GlobalSettings with displayName, interests, onboardingCompleted fields
- Implement state machine for onboarding flow (NAME → INTERESTS → LANGUAGE → SUMMARY)
- Support commands: !start, !profile, !edit, !skip, !help
- Add German and English localization
- Integrate with mana-core-auth Settings API for profile persistence

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 12:42:41 +01:00
Till-JS
c13c313886 🐛 fix(gifts): reorder controller routes to fix 'me/*' matching
NestJS matches routes in declaration order. The dynamic :code route was
matching before me/created and me/received, treating 'me' as a gift code.
Moved specific routes before the dynamic parameter route.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 12:38:23 +01:00
Till-JS
209a474f17 🩹 fix(gifts): add duplicate claim check to first_come type
Users can now only redeem first_come gift codes once, making it
suitable for promo codes that should be unlimited but once per user.
2026-02-14 12:19:43 +01:00
Till-JS
2521a1ea73 feat(matrix): sync recent emojis across apps via mana-core-auth
- Add recentEmojis field to GlobalSettings in shared-theme
- Create userSettings store for Matrix app with JWT token management
- Exchange session cookie for JWT after SSO login
- Update MessageInput to use userSettings instead of localStorage
- Add recentEmojis support to mana-core-auth settings API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 11:30:17 +01:00
Till-JS
284cd004aa 🩹 fix(auth): fix gift code route prefix and JWT issuer validation
- Remove duplicate route prefix in GiftsController (was /api/v1/api/v1/gifts)
- Fix JwtAuthGuard to use JWT_ISSUER as fallback when BASE_URL is not set
- Add comprehensive GIFT_CODES.md documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 23:54:36 +01:00
Till-JS
0485ce4b07 🩹 fix(auth): correct healthcheck endpoint path
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 23:48:45 +01:00
Till-JS
9d7768495d 🔧 fix(auth): add build tools for bcrypt native module 2026-02-13 23:41:35 +01:00
Till-JS
0701635edb 🔧 fix(auth): update Dockerfile for workspace dependencies
Add shared-storage package to Docker build context to resolve
workspace dependency.
2026-02-13 23:36:56 +01:00
Till-JS
e8c3b97f8f feat(auth): add gift codes and enhanced credit system
- Add gift code creation, redemption, and refund endpoints
- Add Stripe payment link generation for credits
- Add gifts database schema
- Enhance credits controller with new operations
2026-02-13 23:29:30 +01:00
Till-JS
c2842e2546 feat(auth): add avatar upload with S3/MinIO and subscription plans seed
- Add StorageModule for avatar uploads via S3/MinIO
- Create presigned URL endpoint for direct browser uploads
- Create direct upload endpoint (multipart/form-data)
- Add manacore-storage bucket to shared-storage package
- Add manacore-storage bucket to docker-compose.dev.yml
- Create subscription plans seed script (pnpm db:seed:plans)
- Plans: Free (150 credits), Pro (2000/€9.99/mo), Enterprise (10000/€49/mo)
- Update TODO list with completed tasks
2026-02-13 23:06:24 +01:00
Till-JS
ce4e982651 feat(auth): add profile management endpoints
Add backend endpoints for user profile management:
- GET /auth/profile - retrieve user profile data
- POST /auth/profile - update name and profile image
- POST /auth/change-password - change password (requires current)
- DELETE /auth/account - soft-delete account (requires password)

Security features:
- Password verification before sensitive actions
- Soft-delete preserves data for retention
- Security events logged for audit trail
- Rate limiting on sensitive endpoints

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 22:29:32 +01:00
Till-JS
ae30ce3323 feat(auth): add Stripe credit purchases and subscription management
- Add StripeService for PaymentIntent creation and webhook verification
- Add credit purchase flow (POST /credits/purchase)
- Add stripe_customers table for Stripe customer mapping
- Add subscriptions schema (plans, subscriptions, invoices)
- Add SubscriptionsService with Checkout, Portal, Cancel, Reactivate
- Add subscription plans (Free: 150 Mana, Pro: €9.99, Enterprise: €49.99)
- Handle subscription and invoice webhooks
- Update roadmap with completed tasks

Credit pricing: 1 Mana = 1 Cent (no volume discounts)
2026-02-13 22:21:23 +01:00
Till-JS
ab15c2367b feat(gdpr): add DSGVO improvements for self-service data page
- Add account deletion confirmation email
- Extend data export with sessions, security events, transactions
- Add DSGVO info banner with privacy policy link
- Add data retention periods section
- Add cookie info (no tracking cookies)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 13:43:23 +01:00
Till-JS
02a5172c7c feat(admin): add GDPR user-data endpoints to photos, clock, storage backends
- Add admin modules with GET/DELETE /api/v1/admin/user-data/:userId
- Photos: albums, favorites, tags counting and deletion
- Clock: alarms, timers, world clocks, presets counting and deletion
- Storage: files, folders, shares, tags counting and deletion
- Update UserDataService to include photos, clock, storage backends
- Add ADMIN_SERVICE_KEY env var to all backends in docker-compose
- Build storage-backend locally instead of using GHCR image

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 13:43:16 +01:00
Till-JS
bc8cd98a27 fix(auth): correct MeController route prefix
Remove duplicate api/v1 prefix - NestJS already adds it globally.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 13:22:58 +01:00
Till-JS
9881e84ee3 feat(auth): add GDPR self-service endpoints for user data
Add /api/v1/me/data endpoints for users to view, export, and delete
their own data without admin privileges (GDPR compliance).

Backend:
- New MeModule with MeController and MeService
- GET /api/v1/me/data - view own data summary
- GET /api/v1/me/data/export - download as JSON
- DELETE /api/v1/me/data - delete all own data

Frontend:
- New /settings/my-data page with full data overview
- Export button for JSON download
- DeleteConfirmationModal with email verification
- Link from settings page to my-data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 13:20:08 +01:00
Till-JS
8b6ff0c679 feat(auth): add API key management for STT/TTS services
- Add api_keys schema in mana-core-auth with SHA-256 hashing
- Create NestJS module with CRUD endpoints and validation
- Add external auth module to STT/TTS for sk_live_ key validation
- Create web UI page at /api-keys for key management
- Support rate limiting per key with configurable limits
- Cache validation results for 5 minutes to reduce auth service load

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 02:12:05 +01:00
Till-JS
a2e2a5b73c feat(admin): add user data dashboard for cross-project data visualization
Add comprehensive admin dashboard to view and manage user data across all projects:

Backend:
- Add admin endpoints to Chat, Todo, Contacts, Calendar, Picture, Zitare, Presi
- Each backend exposes GET/DELETE /api/v1/admin/user-data/:userId
- Service-to-service auth via X-Service-Key header

Aggregation (mana-core-auth):
- GET /api/v1/admin/users - Paginated user list with search
- GET /api/v1/admin/users/:userId/data - Aggregated data from all backends
- DELETE /api/v1/admin/users/:userId/data - GDPR deletion across all projects

Frontend (ManaCore web):
- New User Data tab in admin navigation
- User search page at /admin/user-data
- User detail page with ProjectDataCard components
- GDPR deletion dialog with email confirmation

Presi:
- Migrate user_id from UUID to TEXT for Better Auth compatibility
- Add SQL migration script
2026-02-11 14:59:18 +01:00
Till-JS
85df234ff2 feat(mana-core-auth): auto-link Matrix users on OIDC login
When users log into Matrix via OIDC (Sign in with Mana Core), their
Matrix user ID is now automatically linked to their Mana account.
This enables automatic bot authentication without requiring a
separate !login command.

- Add autoLinkOnOidcLogin() method to MatrixSessionService
- Hook into OIDC userinfo endpoint to create links automatically
- Calculate Matrix user ID from email using Synapse's template

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:50:28 +01:00
Till-JS
75937d6ce9 fix(mana-core-auth): align JWT issuer validation with Better Auth signing config
Better Auth signs JWTs with issuer=BASE_URL (https://auth.mana.how) for OIDC
compatibility, but validation was using jwt.issuer config which defaults to
'manacore'. This caused "unexpected iss claim value" errors.

Fixed in:
- better-auth.service.ts validateToken()
- jwt-auth.guard.ts
- optional-auth.guard.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:50:04 +01:00
Till-JS
0538a6ca10 fix(mana-core-auth): use Better Auth signJWT in refresh endpoint
The refresh endpoint was using manual jwt.sign with RSA keys, but the
server doesn't have JWT_PRIVATE_KEY configured. Changed to use Better
Auth's signJWT method which uses the JWKS/EdDSA keys from the database.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:40:37 +01:00
Till-JS
c196144d1c fix(mana-core-auth): return real refreshToken from signIn endpoint
Same issue as sessionToToken - the signIn method was returning the
session cookie token as refreshToken, but the /api/v1/auth/refresh
endpoint expects the actual refreshToken field from the sessions table.

Now signIn:
- Fetches the session from database after Better Auth creates it
- Uses existing refreshToken if available
- Generates and stores a new refreshToken if missing
- Returns the actual refreshToken that works with token refresh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:37:54 +01:00
Till-JS
d64016d1e5 fix(mana-core-auth): exclude /api/auth/get-session from global prefix
The get-session endpoint needs to be accessible at /api/auth/get-session
(without the /api/v1 prefix) for SSO to work.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:29:17 +01:00
Till-JS
95e9b3764d feat(mana-core-auth): add /api/auth/get-session endpoint for SSO
The SSO flow in client apps calls /api/auth/get-session with cookies
to check if the user has a valid session. This endpoint was missing
from the NestJS passthrough controller.

Now the endpoint forwards the request with cookies to Better Auth's
native handler and returns the session data.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:27:39 +01:00
Till-JS
5c688d713e fix(mana-core-auth): return real refreshToken in SSO session-to-token exchange
The sessionToToken method was incorrectly returning the session cookie
token instead of the actual refreshToken from the database. This caused
"No refresh token available" errors when users logged in via SSO
(cross-domain cookie) because the /api/v1/auth/refresh endpoint expects
the refreshToken field from the sessions table, not the cookie token.

Now the method:
- Fetches the session from database by cookie token
- Uses existing refreshToken if available
- Generates and stores a new refreshToken if missing
- Returns the actual refreshToken that works with token refresh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:05:44 +01:00
Till-JS
2777f604fd feat(bots): enable Redis SSO for todo-bot and calendar-bot
- Activate Redis session storage in both bots for cross-bot SSO
- Update SessionHelper to async methods for Redis-backed SessionService
- Fix async/await issues in todo-bot and calendar-bot matrix.service.ts
- Remove unused imports from calendar-api and todo-api services
- Add CALENDAR_BACKEND_URL and MANA_CORE_SERVICE_KEY to .env.development

Note: SessionService methods are now async (Redis-backed). Other bots
need their matrix.service.ts updated to await these async calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:51:23 +01:00
Till-JS
feaf27dd14 feat(auth): implement cross-subdomain SSO for all web apps
Add Single Sign-On (SSO) support across all mana.how subdomains:

- Add trySSO() method to @manacore/shared-auth that exchanges session
  cookies for JWT tokens
- Add /api/v1/auth/session-to-token endpoint to mana-core-auth service
- Update all 15 web apps to try SSO during auth initialization

SSO Flow:
1. User logs in on any app (e.g., calendar.mana.how)
2. Session cookie is set with Domain=.mana.how
3. When visiting another app (e.g., todo.mana.how), it checks for
   local tokens first
4. If no local tokens, tries SSO via session cookie
5. Session cookie is exchanged for JWT tokens via new endpoint
6. User is automatically authenticated

Apps updated: calendar, chat, clock, contacts, manacore, manadeck,
nutriphi, picture, planta, presi, questions, skilltree, storage,
todo, zitare

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 13:17:04 +01:00
Till-JS
352070fb2f docs(auth): add SSO documentation and test credentials
- Document cross-domain SSO with COOKIE_DOMAIN configuration
- Add production test credentials for automated testing
- Explain cookie-based SSO flow across *.mana.how subdomains

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 04:09:07 +01:00
Till-JS
f03c09ff17 feat(auth): enable cross-domain SSO via shared cookies on .mana.how
- Configure Better Auth with crossSubDomainCookies for .mana.how domain
- Add COOKIE_DOMAIN environment variable (production: .mana.how)
- Sync trustedOrigins with all production subdomains
- Users now login once and are authenticated across all apps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 03:58:29 +01:00
Till-JS
fe33f4b355 fix(mana-core-auth): complete production readiness with test fixes
- Fix LoggerService mock in better-auth.service.spec.ts
- Fix name assertion in auth.controller.spec.ts (empty string fallback)
- Fix createRemoteJWKSet mock in jwt-auth.guard.spec.ts
- Add Grafana dashboard for Auth Service monitoring
- Add 10 auth-specific Prometheus alert rules
- Update production readiness plan to 100% complete

All 199 unit tests passing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 14:18:58 +01:00
Till-JS
ab49be0bee 🐛 fix(matrix-mana-bot): resolve QEMU emulation failure in CI
- Build matrix-mana-bot only for linux/amd64 (arm64 fails due to QEMU)
- Move pnpm overrides for cpu-features and ssh2 to root package.json
- These native deps cause illegal instruction errors under QEMU emulation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:59:04 +01:00
Till-JS
8cd5021b50 🐛 fix(mana-core-auth): use BASE_URL as JWT issuer for OIDC compatibility
OIDC providers like Synapse expect the JWT issuer claim to match the
discovery document's issuer URL. Changed JWT plugin config from
JWT_ISSUER to BASE_URL to ensure consistency.

Also adds:
- @manacore/credit-operations package with operation definitions
- @manacore/shared-credit-ui package with React Native and Svelte components
- CreditInterceptor and @UseCredits decorator in nestjs-integration
- Credit system integration in chat backend
2026-02-01 13:55:05 +01:00
Till-JS
075051a1d4 add-dep: add jsonwebtoken to mana-core-auth dependencies 2026-02-01 13:27:23 +01:00
Till-JS
c0117b2699 🐛 fix: add missing jwt import in better-auth.service 2026-02-01 13:26:11 +01:00
Till-JS
efb077b9ea 🐛 fix(mana-core-auth): use EdDSA for OIDC id_token signing
Set useJWTPlugin: true so id_tokens are signed with EdDSA keys
from JWKS instead of HS256. This fixes Synapse OIDC integration
which verifies tokens via JWKS endpoint.
2026-02-01 13:24:55 +01:00
Till-JS
f0cf1bc804 🐛 fix(mana-core-auth): OIDC token exchange now works with body-parser
- Removed debug logging that exposed sensitive client_secret in production logs
- The body-parser middleware in main.ts correctly handles form-urlencoded token requests
- handleOidcRequest properly converts parsed body to URLSearchParams for Better Auth
2026-02-01 12:28:41 +01:00
Till-JS
4f90f2863d debug: add logging to handleOidcRequest for token exchange debugging 2026-02-01 12:23:05 +01:00
Till-JS
b4493ce3fa debug: add token endpoint logging 2026-02-01 05:58:47 +01:00
Till-JS
805477bd77 fix(seed): use simple password for test user (encoding issues with special chars) 2026-02-01 05:13:42 +01:00
Till-JS
fd61692912 🌱 seed: add test user t@t.de to dev seed script
- Add t@t.de with password +üp+üp+üp to DEV_USERS array
- Refactor seed script to iterate over multiple users
- Ensures test user is always available after db:seed:dev
2026-02-01 05:07:39 +01:00
Till-JS
4599db54a4 📝 docs(mana-core-auth): add comment explaining OAuth token form-urlencoded support
Documents that the token endpoint accepts both JSON and form-urlencoded
bodies per OAuth2 spec, with form data parsed by body-parser middleware.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:12:16 +01:00
Till-JS
0d9864784f 🐛 fix(mana-core-auth): use body-parser for urlencoded OAuth token requests 2026-02-01 04:00:44 +01:00
Till-JS
550083241f 🐛 fix(mana-core-auth): add explicit urlencoded body parser for OAuth token endpoint 2026-02-01 03:56:17 +01:00
Till-JS
191c7b4cc7 🐛 fix(mana-core-auth): handle form-urlencoded token requests
Better Auth OIDC token endpoint now correctly handles both:
- application/x-www-form-urlencoded (OAuth 2.0 spec)
- application/json

This fixes SSO login from Synapse which uses form-urlencoded.
2026-02-01 03:48:55 +01:00
Till-JS
744d0c9c61 fix(mana-core-auth): remove non-existent id field from trusted client
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:28:51 +01:00
Till-JS
c949f5d02a fix(mana-core-auth): fix type compatibility for trusted client config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:28:06 +01:00
Till-JS
01a2c78e39 fix(mana-core-auth): add all required fields to trusted client config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:27:33 +01:00
Till-JS
bb428d4b38 fix(mana-core-auth): add Matrix Synapse as trusted OIDC client
Configure Matrix Synapse as a trusted client that skips the consent screen.
This enables seamless SSO login without requiring user consent for each login.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:26:30 +01:00
Till-JS
ee05b6c3ca fix(mana-core-auth): use correct property name 'redirectUrls' for Better Auth
Better Auth expects 'redirectUrls' (lowercase 'urls') but schema had
'redirectURLs' (uppercase 'URLs'). This caused the redirect URI validation
to fail because Drizzle returned the wrong property name.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:22:06 +01:00
Till-JS
8207d38ca5 fix(mana-core-auth): use comma-separated redirect_urls for Better Auth OIDC
Better Auth's OIDC provider expects redirect_urls to be a comma-separated
string, not a JSON array. Updated seed script and schema documentation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:12:16 +01:00