1a7ef09805
Dashboard: - ApexCharts bar chart (income vs fixed costs vs expenses) and donut chart - KPI cards: income, fixed costs, savings rate with configurable goal - Greeting with time-of-day and locale-aware date/time display Authentication & security: - Email-based login (no username), case-insensitive lookup - JWT access/refresh tokens with rotation and blacklist - TOTP 2FA with QR code, backup codes (copy + PDF export) - 2FA recovery via email code - Cloudflare Turnstile CAPTCHA on login and register Email flows: - Email verification on registration (24h token) - Password reset flow (15min token, anti-enumeration) - Brevo SMTP integration with HTML + plaintext email templates - Notification emails: 2FA recovery, password changed, email changed Settings page: - 2FA management (enable/disable, QR, backup codes) - Active sessions list with per-device revoke - Data export: ZIP with 6 PDFs via fpdf2 - Notification preferences (3 toggles) - Danger zone: account deletion with mandatory export + confirmation phrase UI & layout: - Sidebar with collapsible/flyout mode, Angular signal-based dropdowns - Dark mode (class-based), language switcher (DE/FR/IT/EN) - Mobile-responsive layout with touch-friendly targets - Roboto font via @fontsource (GDPR-compliant, no Google CDN) - Pure Tailwind CSS v3 Infrastructure: - Forgejo Actions CI/CD pipeline (auto-deploy on push to main) - Gunicorn + Nginx + PostgreSQL production setup - Rate limiting, HSTS, secure cookies, CSRF protection
56 lines
2.9 KiB
Python
56 lines
2.9 KiB
Python
import os
|
|
from django.contrib import admin
|
|
from django.urls import path, include
|
|
from django.conf import settings
|
|
from django.conf.urls.static import static
|
|
from rest_framework.routers import DefaultRouter
|
|
from rest_framework_simplejwt.views import TokenRefreshView
|
|
from finance.views import (
|
|
AccountViewSet, TransactionViewSet, BudgetViewSet,
|
|
ExpenseViewSet, DeadlineViewSet, ProfileView, RegisterView, LogoutView, ChangePasswordView,
|
|
ICalUrlView, ICalFeedView, NotificationsView, SearchView,
|
|
LoginView, TwoFactorLoginView, TwoFactorSetupView, TwoFactorEnableView, TwoFactorDisableView,
|
|
TwoFactorRecoverRequestView, TwoFactorRecoverConfirmView,
|
|
SessionListView, SessionRevokeView, SessionRevokeAllView,
|
|
DataExportView, NotificationPrefsView,
|
|
VerifyEmailView, PasswordResetRequestView, PasswordResetConfirmView,
|
|
)
|
|
|
|
router = DefaultRouter()
|
|
router.register(r'accounts', AccountViewSet, basename='account')
|
|
router.register(r'transactions', TransactionViewSet, basename='transaction')
|
|
router.register(r'budgets', BudgetViewSet, basename='budget')
|
|
router.register(r'expenses', ExpenseViewSet, basename='expense')
|
|
router.register(r'deadlines', DeadlineViewSet, basename='deadline')
|
|
|
|
_admin_url = os.environ.get('ADMIN_URL', 'manage/').strip('/')+ '/'
|
|
|
|
urlpatterns = [
|
|
path(_admin_url, admin.site.urls),
|
|
path('api/', include(router.urls)),
|
|
path('api/profile/', ProfileView.as_view()),
|
|
path('api/auth/register/', RegisterView.as_view()),
|
|
path('api/auth/token/', LoginView.as_view()),
|
|
path('api/auth/token/refresh/', TokenRefreshView.as_view()),
|
|
path('api/auth/logout/', LogoutView.as_view()),
|
|
path('api/auth/password/', ChangePasswordView.as_view()),
|
|
path('api/auth/verify-email/', VerifyEmailView.as_view()),
|
|
path('api/auth/password-reset/', PasswordResetRequestView.as_view()),
|
|
path('api/auth/password-reset/confirm/', PasswordResetConfirmView.as_view()),
|
|
path('api/auth/2fa/login/', TwoFactorLoginView.as_view()),
|
|
path('api/auth/2fa/setup/', TwoFactorSetupView.as_view()),
|
|
path('api/auth/2fa/enable/', TwoFactorEnableView.as_view()),
|
|
path('api/auth/2fa/disable/', TwoFactorDisableView.as_view()),
|
|
path('api/auth/2fa/recover/', TwoFactorRecoverRequestView.as_view()),
|
|
path('api/auth/2fa/recover/confirm/', TwoFactorRecoverConfirmView.as_view()),
|
|
path('api/auth/sessions/', SessionListView.as_view()),
|
|
path('api/auth/sessions/revoke-all/', SessionRevokeAllView.as_view()),
|
|
path('api/auth/sessions/<str:session_key>/', SessionRevokeView.as_view()),
|
|
path('api/export/', DataExportView.as_view()),
|
|
path('api/notifications/prefs/', NotificationPrefsView.as_view()),
|
|
path('api/search/', SearchView.as_view()),
|
|
path('api/notifications/', NotificationsView.as_view()),
|
|
path('api/calendar/ical-url/', ICalUrlView.as_view()),
|
|
path('api/calendar/ical/<int:user_id>/<str:token>/', ICalFeedView.as_view()),
|
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|