Add a simple login page at /login for OIDC authorization flows.
When users access the authorization endpoint without being logged in,
Better Auth redirects them to this page. After successful login,
users are redirected back to continue the authorization flow.
- Create OidcLoginController with login page HTML
- Add controller to AuthModule
- Exclude /login from global prefix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Better Auth's OIDC discovery document advertises endpoints at
/api/auth/oauth2/* paths. Add routes for these native paths to
ensure Matrix Synapse and other OIDC clients can complete the
authorization flow.
Routes added:
- GET /api/auth/oauth2/authorize
- POST /api/auth/oauth2/token
- GET /api/auth/oauth2/userinfo
- GET /api/auth/jwks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Better Auth's discovery document points to /api/auth/jwks,
so we need to expose this route directly in NestJS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add OidcController to expose Better Auth OIDC Provider endpoints
- Add handleOidcRequest method to BetterAuthService
- Exclude OIDC routes from global /api/v1 prefix
- Register OidcController in AuthModule
Endpoints:
- GET /.well-known/openid-configuration
- GET /api/oidc/authorize
- POST /api/oidc/token
- GET /api/oidc/userinfo
- GET /api/oidc/jwks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add OIDC Provider plugin to Better Auth configuration
- Add OIDC database tables (oauth_applications, oauth_access_tokens,
oauth_authorization_codes, oauth_consents)
- Configure Synapse as OIDC client in homeserver.yaml
- Update Element Web config for SSO support
- Add seed script for OIDC clients (db:seed:oidc)
- Update Cloudflare tunnel config with Matrix URLs
This enables Single Sign-On between Mana Core Auth and Matrix/Synapse,
allowing users to authenticate via their existing Mana account.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GET /api/auth/reset-password/:token endpoint to handle email links
- Create password-reset-redirect store to track source app URLs
- Include callbackURL in reset emails for proper app redirection
- Add redirectTo parameter to forgotPassword in shared-auth
- Create /reset-password page in calendar app with DE/EN translations
- Update calendar authStore with resetPasswordWithToken method
Fixes 404 error when clicking password reset link from email
Add sourceAppUrl tracking during registration to redirect users back
to the app they registered from after email verification. Includes
URL validation for security (only *.mana.how, mana.how, localhost).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Better Auth generates verification URLs with /api/auth/verify-email path,
but NestJS uses /api/v1 prefix. This adds a passthrough controller to
handle the native Better Auth routes and properly verify user emails.
- Add BetterAuthPassthroughController for /api/auth/* routes
- Add verifyEmail method to BetterAuthService
- Exclude /api/auth/* from global prefix in main.ts
- Register passthrough controller in AuthModule
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Better Auth requires emailVerification config to be a separate top-level
option, not under emailAndPassword. Added sendOnSignUp: true to trigger
verification emails on registration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add sendVerificationEmail function in email.service.ts
- Enable requireEmailVerification in Better Auth config
- New users must verify their email before logging in
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change from auth.api.forgetPassword to auth.api.requestPasswordReset
to match Better Auth's actual endpoint naming.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Access inviter.user.name instead of inviter.name to match Better Auth's
organization plugin type structure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add nodemailer-based email service with Brevo SMTP integration
- Implement password reset, invitation, and welcome email templates
- Update better-auth.config.ts to use email service for sendResetPassword and sendInvitationEmail
- Add SMTP environment variables to docker-compose.macmini.yml
- Change minimum password length from 12 to 8 characters
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add rememberMe field to sessions schema
- Mock non-existent service imports in tests
- Add missing docker-entrypoint.sh for clock-backend
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Merge till-dev branch containing:
- Planta plant care tracking application
- Clock backend with alarms, timers, world clocks
- Zitare backend with favorites and lists
- Various app improvements and fixes
- Auth system updates
- Infrastructure improvements
Note: Some type-check issues may need resolution after merge.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements sliding window expiration for refresh tokens to allow active
users to stay signed in indefinitely while maintaining security through
inactivity timeouts.
Changes:
- Extend refresh token expiration from NOW on each refresh (not from login)
- Preserve rememberMe flag across token rotations
- Active users: stay signed in forever (7/30 day sliding window)
- Inactive users: signed out after 7 days (regular) or 30 days (rememberMe)
This matches industry standards (Gmail, Slack, GitHub) where active users
remain authenticated while inactive users are automatically signed out.
Add required name field (min 2 chars) to all registration forms to fix
Better Auth validation error. Updates backend DTO, shared-auth service,
shared-auth-ui RegisterPage component, i18n translations, and all app
auth stores and register pages.
- Fix `requestPasswordReset` method name (was incorrectly `forgetPassword`)
- Add proper TypeScript types for password reset, session, and JWT methods
- Consolidate API accessor from `orgApi` to `api` for all Better Auth calls
- Remove unnecessary `as any` casts by extending BetterAuthAPI interface
- Clean up unused imports
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## Runtime Environment Fix
- Updated all web app hooks.server.ts to use $env/dynamic/private
- This allows Docker containers to inject env vars at runtime
- Updated docker-compose.staging.yml with HTTPS staging domains
- Fixes Mixed Content errors when accessing staging via domains
## New Features
- Added email service to mana-core-auth for sending emails
- Added storage module to chat backend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add password reset functionality to mana-core-auth using Better Auth
- Add forgot-password and reset-password endpoints with DTOs
- Update shared-auth package with resetPassword method and endpoint
- Update manacore-web auth store with resetPassword method
- Refactor reset-password pages to use mana-core-auth instead of Supabase
- Remove Supabase dependencies from manacore-web package.json
- Remove Supabase server code (hooks.server.ts, supabase.ts, API routes)
- Update Dockerfile to remove shared-supabase dependency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed remaining NestJS dependency injection issues by converting type-only imports to regular imports for all injectable services used in controllers and service dependencies.
Changes:
- feedback.service.ts: Fixed AiService import (was causing "argument Function at index [1]" error)
- auth.controller.ts: Fixed BetterAuthService import
- feedback.controller.ts: Fixed FeedbackService import
- credits.controller.ts: Fixed CreditsService import
- settings.controller.ts: Fixed SettingsService import
Root cause: Type-only imports (`import { type X }`) are erased at compile time, causing NestJS to fail dependency injection at runtime. All injectable classes must use regular imports.
Verified locally: All modules initialize successfully without DI errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Found and fixed type-only ConfigService imports in 6 service files that were causing "Nest can't resolve dependencies" errors:
- better-auth.service.ts (BetterAuthService)
- ai.service.ts (AiService)
- settings.service.ts
- feedback.service.ts
- credits.service.ts
- jwt-auth.guard.ts
- optional-auth.guard.ts
Type-only imports are erased at compile time, preventing NestJS from injecting the ConfigService class at runtime.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add build:packages step to all test.yml jobs (fixes @manacore/shared-nestjs-auth not found)
- Handle missing coverage artifacts gracefully in test-coverage.yml
- Update .prettierignore to exclude apps-archived/ and problematic files
- Format all source files to pass CI checks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update auth.controller.spec.ts to expect accessToken/refreshToken/expiresIn
- Refactor jwt-validation.spec.ts to test minimal claims (sub, email, role, sid)
- Remove B2B/B2C org and credit_balance claims from tests (fetched via API now)
- Add Better Auth CLI config for schema generation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace jsonwebtoken RS256 validation with jose EdDSA
- Add JWKS endpoint to expose Better Auth public keys
- Use createRemoteJWKSet for token validation
- Fix issuer mismatch (use env var consistently)
- Add jwks table to schema for Better Auth JWT plugin
- Install jose library for JWT verification