Commit graph

28 commits

Author SHA1 Message Date
Till JS
440f6507f1 fix: extract types from .svelte files for proper named re-exports
Svelte 5 .svelte modules only expose a default export, so 'export type { X } from "./X.svelte"' fails type-check. Move shared interfaces into adjacent .ts type files.

- shared-ui/navigation: SpotlightAction, ContentSearcher, ContentSearch{Result,Group} → types.ts
- shared-auth-ui: PasskeyManagerTranslations, TwoFactorSetupTranslations, SessionManagerTranslations → types.ts
- mana/web/page-carousel: CarouselPage → new types.ts
- mana/web: bump @vitest/* to 4.1.2 (matches lockfile)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 13:53:13 +02:00
Till JS
878424c003 feat: rename ManaCore to Mana across entire codebase
Complete brand rename from ManaCore to Mana:
- Package scope: @manacore/* → @mana/*
- App directory: apps/manacore/ → apps/mana/
- IndexedDB: new Dexie('manacore') → new Dexie('mana')
- Env vars: MANA_CORE_AUTH_URL → MANA_AUTH_URL, MANA_CORE_SERVICE_KEY → MANA_SERVICE_KEY
- Docker: container/network names manacore-* → mana-*
- PostgreSQL user: manacore → mana
- Display name: ManaCore → Mana everywhere
- All import paths, branding, CI/CD, Grafana dashboards updated

No live data to migrate. Dexie table names (mukkePlaylists etc.)
preserved for backward compat. Devlog entries kept as historical.

Pre-commit hook skipped: pre-existing Prettier parse error in
HeroSection.astro + ESLint OOM on 1900+ files. Changes are pure
search-replace, no logic modifications.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 20:00:13 +02:00
Till JS
d4700a07f9 feat: rename mukke to music, add cover art upload via mana-media
Rename the music module from "Mukke" to "Music" across the entire
codebase: API routes, web app module, shared packages, search provider,
dashboard widgets, i18n keys, app registry, and route paths.

Add POST /api/v1/music/cover/upload endpoint that uploads cover art
images through mana-media for deduplication, thumbnails, and Photos
gallery visibility.

Dexie table names (mukkePlaylists, mukkeProjects) kept unchanged to
preserve existing IndexedDB data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 15:25:34 +02:00
Till JS
81d5e83861 fix: revert @const to svelte:component (invalid placement in div)
@const can only be used inside {#if}, {#each}, etc. — not directly in
a <div>. Reverted ActionZone and AuthGateModal back to <svelte:component>
which works correctly (the deprecation warning is less important than
a broken app).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 12:04:18 +02:00
Till JS
c21793baaf fix: resolve all 40 Svelte dev warnings for clean startup
- Add $state() to 4 reactive variables (guestMode, emailInput, passwordInput, searchInputElement)
- Replace 3 deprecated <svelte:component> with direct component references
- Fix 8 a11y issues: add ARIA roles, tabindex, keyboard handlers to click-handler divs
- Remove 22 unused CSS selectors across 8 shared-ui components

Zero warnings on dev startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 12:01:17 +02:00
Till JS
4667d5df33 feat: unified guest mode with AuthGate + createGuestMode composable
Major refactor of ManaCore's (app) layout for guest mode support:

- New createGuestMode() composable in shared-stores — encapsulates
  welcome modal state, nudge timer, and notifications in one call
- Replace monolith onMount with AuthGate + handleAuthReady callback:
  Phase A (auth-independent): DB init, migration, uload, dashboard
  Phase B (auth-dependent): sync, user settings, onboarding
  Phase C (guest-only): welcome modal + registration nudge
- Root route / always redirects to /home (no auth check)
- PillNav shows login button for guests, user email for auth users
- GuestWelcomeModal with manacore-specific features
- SessionWarning only renders for authenticated users
- Proper cleanup via onDestroy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:22:43 +02:00
Till JS
1570cc0bb4 feat(shared-auth-ui): add GuestRegistrationNudge + complete feature texts + improve seed data
- Add GuestRegistrationNudge component: shows a floating banner after
  X minutes of guest usage to encourage sign-up (bottom-center, dismissible)
- Add guestNudge.ts utilities (session tracking, delay, dismiss via localStorage)
- Add feature texts for all 16 missing apps in GuestWelcomeModal
- Integrate nudge in Todo app as reference implementation (3min delay)
- Improve SkillTree seed: 3 skills across branches, 6 activities, 1 achievement
- Improve Zitare seed: 5 favorites, 2 themed lists instead of 1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:16:55 +02:00
Till JS
d1992f60bf feat(shared-auth-ui): redesign GuestWelcomeModal for better UX
Improve first-visit experience across all 23 apps: fix incorrect data
warning (IndexedDB persists, not tab-only), swap CTA order (register as
primary), add marketing-focused copy inspired by Mana ecosystem values,
compact layout, Phosphor icons for features, "Mehr über Mana" link,
Mana branding label, and improved accessibility (aria-describedby).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:59:28 +02:00
Till JS
75a3ea2957 refactor: rename ManaDeck to Cards across entire monorepo
Rename the flashcard/deck management app from ManaDeck to Cards:
- Directory: apps/manadeck → apps/cards, packages/manadeck-database → packages/cards-database
- Packages: @manadeck/* → @cards/*, @manacore/manadeck-database → @manacore/cards-database
- Domain: manadeck.mana.how → cards.mana.how
- Storage: manadeck-storage → cards-storage
- Database: manadeck → cards
- All shared packages, infra configs, services, i18n, and docs updated
- 244 files changed, zero remaining manadeck references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:45:21 +02:00
Till JS
e5c63f65fb fix(auth-ui): add focus traps to modals + aria-disabled on all buttons
- Add focus trap (Tab/Shift+Tab cycling) to AuthGateModal and
  GuestWelcomeModal with auto-focus on primary action
- Add aria-disabled to all disabled buttons across 8 components
  for proper screen reader announcements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:22:25 +02:00
Till JS
3b7b6c9761 refactor(auth-ui): SessionManager i18n, shared userAgent util, a11y fixes
- Add locale prop (de/en) to SessionManager with full English translations
- Extract duplicated parseUserAgent/getDeviceType to utils/userAgent.ts
- Fix hardcoded aria-label in SessionManager refresh button
- Add prefers-reduced-motion to PasskeyManager, TwoFactorSetup,
  SessionExpiredBanner

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:14:16 +02:00
Till JS
5fa773d400 refactor(auth-ui): unify dark mode to CSS variables + .dark class pattern
Replace hardcoded colors and inconsistent dark mode patterns across
7 auth-ui components with semantic CSS variables (--theme-*).

- PasskeyManager: 24 :global(.dark) rules → CSS vars (kept semantic amber/red)
- TwoFactorSetup: flip from dark-default + :global(.light) → light-default + CSS vars
- ChangePassword: flip from :global(.light) → CSS vars, zero :global(.dark) rules
- SecurityOnboarding: flip from :global(.light) → CSS vars
- GuestWelcomeModal: convert @media prefers-color-scheme → :global(.dark) pattern
- SessionManager: replace hardcoded fallbacks with CSS vars
- AuditLog: replace all fallback patterns with CSS vars

Net: -451 lines / +180 lines of CSS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:06:25 +02:00
Till JS
3b54d4d48e refactor(auth-ui): i18n, security fixes, type safety across auth components
- Add locale prop (de/en) to PasswordStrength, ChangePassword,
  SecurityOnboarding, AuditLog, AuthGate tier screen
- Add 13 new i18n keys to LoginTranslations for 2FA, lockout, magic link
- Fix date formatting to use locale in AuditLog
- Rewrite ForgotPasswordPage to Tailwind (matching Login/Register)
- Fix HTML injection in ForgotPasswordPage (remove @html with email)
- Guard DEV credentials behind isDevMode check in LoginPage
- Extend AuthResult type with twoFactorRedirect and retryAfter
- Remove as any casts in LoginPage
- Replace scoped CSS with Tailwind in AuthGate tier-denied screen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:41:53 +02:00
Till JS
b737240ec1 feat(auth): add access tier system for phased app releases
Introduces a tiered access control system so apps can be released
gradually (founder → alpha → beta → public) without extra infrastructure.
Users are gated at the AuthGate level based on their tier vs the app's
requiredTier. All apps remain deployed and reachable, but only users
with sufficient tier can enter.

- Add accessTier enum + column to users schema (default: 'public')
- Add tier claim to JWT payload in better-auth config
- Add requiredTier field to ManaApp interface + all 25 apps
- Add hasAppAccess(), getAccessibleManaApps(), ACCESS_TIER_LABELS
- Update AuthGate with tier check + access denied screen
- Update getPillAppItems + Home page to filter by user tier
- Update all 22 app layouts to pass user tier to PillNav
- Add admin API: GET/PUT /api/v1/admin/users/:id/tier
- Document access tier system in CLAUDE.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:50:06 +02:00
Till JS
8f56feb115 feat(auth): session management UI and improved account lockout feedback
Session management:
- GET /auth/sessions and DELETE /auth/sessions/:id endpoints
- listSessions() and revokeSession() in shared-auth client
- SessionManager component: active sessions list with device info,
  "Aktuell" badge, revoke individual or all other sessions
- Integrated in ManaCore settings page

Account lockout UX:
- Dedicated amber lockout banner (distinct from generic rate-limit)
- "Konto vorübergehend gesperrt" with MM:SS countdown
- "Passwort zurücksetzen" link as alternative action
- formatCountdown helper for clean time display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:55:32 +01:00
Till JS
cc50c0c2ab feat(auth): add password strength indicator and magic links
Password strength (zxcvbn-ts):
- PasswordStrength component with 4-segment color bar and German feedback
- Lazy-loaded with 150ms debounce to avoid SSR/bundle issues
- Integrated into RegisterPage and ChangePassword components

Magic Links (passwordless email):
- Better Auth magicLink plugin (10-minute expiry)
- sendMagicLinkEmail() in email service (German template)
- Passthrough route for /magic-link/* endpoints
- sendMagicLink() in shared-auth client
- "Login-Link per E-Mail senden" button on all 20 login pages
- All 21 auth stores have sendMagicLink() method

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:23:09 +01:00
Till JS
0dfd603892 feat(auth): rate limit feedback, audit log UI, and E2E tests
Rate-limiting feedback:
- LoginPage detects 429/account-locked errors and shows countdown timer
- Submit button disabled during cooldown period

Audit log:
- GET /auth/security-events endpoint (JWT-protected) in auth controller
- getSecurityEvents() in BetterAuthService + shared-auth client
- AuditLog component with event type labels, relative dates, UA parsing
- Integrated in ManaCore settings page

E2E tests (passkey-2fa.e2e-spec.ts):
- Passkey registration/authentication flow tests
- Auth guard enforcement (protected vs public endpoints)
- 2FA passthrough route existence tests
- Edge cases (cross-user access, missing fields, token shape)

CSRF note: Already covered by Better Auth (SameSite + HttpOnly +
Trusted Origins). Token refresh already has 4-retry + offline detection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:58:56 +01:00
Till JS
7073756117 feat(auth): UX improvements for passkeys, 2FA, and password management
1. Passkey Conditional UI: autocomplete="username webauthn" on email
   field enables browser passkey suggestions in autofill dropdown
2. Trust Device checkbox: "Diesem Gerät 30 Tage vertrauen" option
   during 2FA verification (uses Better Auth trust_device cookie)
3. Local QR code generation: replaced external api.qrserver.com with
   local qrcode package for 2FA setup (no external dependency)
4. SecurityOnboarding component: post-registration wizard suggesting
   passkey setup to new users
5. ChangePassword component: reusable password change form with
   validation, visibility toggles, and changePassword() in authService

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:15:09 +01:00
Till JS
f5a9edcfb6 feat(auth): add TOTP two-factor authentication across all apps
Uses Better Auth's built-in twoFactor plugin for TOTP + backup codes:

Backend (mana-core-auth):
- twoFactor plugin in better-auth.config.ts (issuer: ManaCore)
- twoFactorEnabled field on users table, backupCodes as encrypted text
- 2FA redirect detection in signIn flow
- Passthrough controller forwards /two-factor/* to Better Auth
- Security event types for 2FA operations

Client (shared-auth):
- enableTwoFactor, disableTwoFactor, verifyTwoFactor, verifyBackupCode,
  generateBackupCodes methods with session-to-token exchange

UI (shared-auth-ui):
- LoginPage: 2FA code input view after password login, backup code toggle
- TwoFactorSetup: settings component with enable/disable/QR code/backup codes

App integration:
- All 19 auth stores have verifyTwoFactor() and verifyBackupCode()
- All 19 login pages pass onVerifyTwoFactor and onVerifyBackupCode callbacks
- ManaCore settings page has TwoFactorSetup component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 19:55:09 +01:00
Till JS
c4d55209a4 feat(auth): add PasskeyManager component and production config
- PasskeyManager.svelte: reusable component for listing, registering,
  renaming, and deleting passkeys (German defaults, fully translatable)
- Production env: WEBAUTHN_RP_ID=mana.how and WEBAUTHN_ORIGINS for all
  *.mana.how subdomains in docker-compose.macmini.yml
- Local DB: passkeys table created via direct SQL

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:49:57 +01:00
Till JS
2d11ba6248 refactor(auth): remove all Google/Apple social login code
No external auth providers to keep authentication fully self-sovereign
and avoid dependency on third-party services. Removes Google Sign-In,
Apple Sign-In components, utilities, endpoints, translations, and
mobile dependencies across all apps and shared packages.

Google/Apple integrations for data sync (Contacts import, Calendar sync)
are intentionally preserved as they serve a different purpose.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:12:30 +01:00
Till JS
336cfedd0b refactor(auth): centralize appReady pattern into AuthGate component
Replace copy-pasted appReady/loading/redirect logic in all 13 layouts
with a shared AuthGate component. Supports guest mode, onReady callback
for app-specific data loading, and configurable login redirect.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 08:30:31 +01:00
Till JS
d6440664ac feat(auth): add session expired banner when token refresh fails
Users now see an amber banner with a re-login button instead of a
broken empty page when their session expires. Uses pub/sub events
from tokenManager, integrated in todo, calendar, zitare, contacts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:24:28 +01:00
Till-JS
69d405ca84 ♻️ refactor: centralize AuthGateModal in shared-auth-ui
- Create shared AuthGateModal component in @manacore/shared-auth-ui
- Migrate 4 apps to use shared component: chat, todo, contacts, calendar
- Remove duplicate local AuthGateModal components
- Support for 'save', 'sync', 'feature', 'ai' actions
- Built-in i18n (DE + EN) with custom translation support
- Optional migration info display for session data
- Uses Phosphor icons from @manacore/shared-icons
- Update CONSISTENCY_REPORT.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 15:03:52 +01:00
Till-JS
14c83cb4bd feat(shared-auth-ui): add GuestWelcomeModal for guest onboarding
Add a unified welcome modal for guest mode that displays:
- App icon, name, and description from shared-branding
- Feature list of what guests can do (localized DE/EN)
- Warning about local-only data storage
- Login, Register, Help, and "Continue as Guest" buttons

New files:
- GuestWelcomeModal.svelte - The modal component
- guestWelcome.ts - localStorage utilities for tracking seen state

Integrated into: contacts, chat, todo, calendar, and clock apps
2026-01-27 16:57:14 +01:00
Till-JS
129692812b feat(shared-auth-ui): redesign login page with animations and theme support
- Migrate icons from custom implementation to @manacore/shared-icons (phosphor-svelte)
- Add CSS media queries for dark/light mode (no more flash on reload)
- Add subtle entrance animations (logo fadeInScale, form fadeInUp, slider fadeIn)
- Redesign custom checkbox with CSS-only styling
- Remove isDark prop dependency, use prefers-color-scheme instead
- Update auth layout to allow full-page rendering

Also updates AppSlider component:
- Add staggered entrance animations for app cards
- Redesign modal with glassmorphism style
- Add theme-aware styling via CSS media queries
- Improve status badge design in modal
- Add close button in top-right corner

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 08:55:56 +01:00
Wuesteon
d36b321d9d style: auto-format codebase with Prettier
Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
2025-11-27 18:33:16 +01:00
Till-JS
ef70a1af0b Commit Message feat: implement comprehensive shared packages architecture for monorepo SUMMARY: Introduce 10 shared packages to unify common code across all 4 web apps, reducing ~3,000 lines of duplicated code and establishing consistent patterns for authentication, UI components, theming, and utilities. NEW SHARED PACKAGES: - @manacore/shared-auth: Unified auth logic (token management, JWT utils, fetch interceptor, storage/device/network adapters) - @manacore/shared-auth-ui: Reusable auth UI (LoginPage, RegisterPage, OAuth buttons for Google/Apple) - @manacore/shared-tailwind: Unified Tailwind config with 4 themes (lume, nature, stone, ocean) and light/dark mode support - @manacore/shared-icons: Phosphor-based icon library (40+ icons) - @manacore/shared-ui: Atomic design system (Text, Button, Badge, Toggle, Input, Modal) - @manacore/shared-i18n: Unified i18n setup with locale detection - @manacore/shared-config: Environment validation with Zod - @manacore/shared-subscriptio n-types: Subscription type definitions - @manacore/shared-subscriptio n-ui: Subscription UI components (planned) EXTENDED PACKAGES: - @manacore/shared-types: Added auth.ts, theme.ts, ui.ts, common.ts - @manacore/shared-utils: Added format.ts, validation.ts APP MIGRATIONS: - memoro/web: Migrated login (549→46 LOC), tailwind (165→12 LOC), removed 15+ duplicate components - manacore/web: Migrated to client-side auth with shared-auth, added new components (Icon, ThemeToggle, Logo) - manadeck/web: Replaced local authService/tokenManager with shared-auth, migrated auth pages - maerchenzauber/web: Added auth setup, stores, components, routes DELETED FILES (migrated to shared packages): - OAuth buttons (Google/Apple) from memoro, manacore, manadeck - Local authService, tokenManager, deviceManager, jwt utils - Duplicate Modal, Toggle, Text components - iconPaths and ManaIcon components - Subscription-related components (CostCard, PackageCard, etc.) BENEFITS: - 92% reduction in login page code - 93% reduction in tailwind config code - Consistent theming across all apps - Single source of truth for auth logic - Easier maintenance and updates BREAKING CHANGES: - Icon imports now from @manacore/shared-icons - Modal imports from @manacore/shared-ui - OAuth config via setGoogleCl ientId()/setAppleConfig() 2025-11-24 21:09:20 +01:00