Commit Β·
dd02f5b
0
Parent(s):
remove venv from repo
Browse filesThis view is limited to 50 files because it contains too many changes. Β See raw diff
- .env +11 -0
- ai_assistant/__init__.py +0 -0
- ai_assistant/__pycache__/__init__.cpython-313.pyc +0 -0
- ai_assistant/__pycache__/__init__.cpython-314.pyc +0 -0
- ai_assistant/__pycache__/admin.cpython-313.pyc +0 -0
- ai_assistant/__pycache__/admin.cpython-314.pyc +0 -0
- ai_assistant/__pycache__/apps.cpython-313.pyc +0 -0
- ai_assistant/__pycache__/apps.cpython-314.pyc +0 -0
- ai_assistant/__pycache__/models.cpython-313.pyc +0 -0
- ai_assistant/__pycache__/models.cpython-314.pyc +0 -0
- ai_assistant/admin.py +3 -0
- ai_assistant/apps.py +5 -0
- ai_assistant/migrations/__init__.py +0 -0
- ai_assistant/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- ai_assistant/migrations/__pycache__/__init__.cpython-314.pyc +0 -0
- ai_assistant/models.py +3 -0
- ai_assistant/tests.py +3 -0
- ai_assistant/views.py +3 -0
- aureon_backend/__init__.py +0 -0
- aureon_backend/__pycache__/__init__.cpython-313.pyc +0 -0
- aureon_backend/__pycache__/__init__.cpython-314.pyc +0 -0
- aureon_backend/__pycache__/settings.cpython-313.pyc +0 -0
- aureon_backend/__pycache__/settings.cpython-314.pyc +0 -0
- aureon_backend/__pycache__/urls.cpython-313.pyc +0 -0
- aureon_backend/__pycache__/urls.cpython-314.pyc +0 -0
- aureon_backend/__pycache__/wsgi.cpython-313.pyc +0 -0
- aureon_backend/__pycache__/wsgi.cpython-314.pyc +0 -0
- aureon_backend/asgi.py +16 -0
- aureon_backend/settings.py +170 -0
- aureon_backend/urls.py +9 -0
- aureon_backend/wsgi.py +16 -0
- debug_token.py +152 -0
- finance/__init__.py +0 -0
- finance/__pycache__/__init__.cpython-313.pyc +0 -0
- finance/__pycache__/__init__.cpython-314.pyc +0 -0
- finance/__pycache__/admin.cpython-313.pyc +0 -0
- finance/__pycache__/admin.cpython-314.pyc +0 -0
- finance/__pycache__/apps.cpython-313.pyc +0 -0
- finance/__pycache__/apps.cpython-314.pyc +0 -0
- finance/__pycache__/models.cpython-313.pyc +0 -0
- finance/__pycache__/models.cpython-314.pyc +0 -0
- finance/admin.py +3 -0
- finance/apps.py +5 -0
- finance/migrations/__init__.py +0 -0
- finance/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- finance/migrations/__pycache__/__init__.cpython-314.pyc +0 -0
- finance/models.py +3 -0
- finance/tests.py +3 -0
- finance/views.py +3 -0
- importer/__init__.py +0 -0
.env
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# .env file
|
| 2 |
+
DATABASE_URL=postgresql://postgres.sgctwsjvgrvbcjyvwprg:yash9897422911@aws-1-ap-southeast-1.pooler.supabase.com:6543/postgres
|
| 3 |
+
SUPABASE_URL=https://sgctwsjvgrvbcjyvwprg.supabase.co
|
| 4 |
+
SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNnY3R3c2p2Z3J2YmNqeXZ3cHJnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzA3MzgzMDcsImV4cCI6MjA4NjMxNDMwN30.OlcoyXaDu1Hn6xApQAsjO0XeW2klcvJRp-4Elnx_OBg
|
| 5 |
+
SUPABASE_JWT_SECRET=ktkcGAWLUzVmgUdJFfyGROURYbyS9efKJU1dZXEzLRLuNkY8DX3HISRFvwosh3LSsuRbCtUI69eCYAI2UTcpug==
|
| 6 |
+
SECRET_KEY=django-insecure-change-me-later-for-production
|
| 7 |
+
DEBUG=True
|
| 8 |
+
ALLOWED_HOSTS=*
|
| 9 |
+
|
| 10 |
+
SENDGRID_API_KEY=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
|
| 11 |
+
DEFAULT_FROM_EMAIL=codewithyash124@gmail.com
|
ai_assistant/__init__.py
ADDED
|
File without changes
|
ai_assistant/__pycache__/__init__.cpython-313.pyc
ADDED
|
Binary file (183 Bytes). View file
|
|
|
ai_assistant/__pycache__/__init__.cpython-314.pyc
ADDED
|
Binary file (185 Bytes). View file
|
|
|
ai_assistant/__pycache__/admin.cpython-313.pyc
ADDED
|
Binary file (227 Bytes). View file
|
|
|
ai_assistant/__pycache__/admin.cpython-314.pyc
ADDED
|
Binary file (229 Bytes). View file
|
|
|
ai_assistant/__pycache__/apps.cpython-313.pyc
ADDED
|
Binary file (497 Bytes). View file
|
|
|
ai_assistant/__pycache__/apps.cpython-314.pyc
ADDED
|
Binary file (496 Bytes). View file
|
|
|
ai_assistant/__pycache__/models.cpython-313.pyc
ADDED
|
Binary file (224 Bytes). View file
|
|
|
ai_assistant/__pycache__/models.cpython-314.pyc
ADDED
|
Binary file (226 Bytes). View file
|
|
|
ai_assistant/admin.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.contrib import admin
|
| 2 |
+
|
| 3 |
+
# Register your models here.
|
ai_assistant/apps.py
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.apps import AppConfig
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
class AiAssistantConfig(AppConfig):
|
| 5 |
+
name = 'ai_assistant'
|
ai_assistant/migrations/__init__.py
ADDED
|
File without changes
|
ai_assistant/migrations/__pycache__/__init__.cpython-313.pyc
ADDED
|
Binary file (194 Bytes). View file
|
|
|
ai_assistant/migrations/__pycache__/__init__.cpython-314.pyc
ADDED
|
Binary file (196 Bytes). View file
|
|
|
ai_assistant/models.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.db import models
|
| 2 |
+
|
| 3 |
+
# Create your models here.
|
ai_assistant/tests.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.test import TestCase
|
| 2 |
+
|
| 3 |
+
# Create your tests here.
|
ai_assistant/views.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.shortcuts import render
|
| 2 |
+
|
| 3 |
+
# Create your views here.
|
aureon_backend/__init__.py
ADDED
|
File without changes
|
aureon_backend/__pycache__/__init__.cpython-313.pyc
ADDED
|
Binary file (185 Bytes). View file
|
|
|
aureon_backend/__pycache__/__init__.cpython-314.pyc
ADDED
|
Binary file (187 Bytes). View file
|
|
|
aureon_backend/__pycache__/settings.cpython-313.pyc
ADDED
|
Binary file (3.46 kB). View file
|
|
|
aureon_backend/__pycache__/settings.cpython-314.pyc
ADDED
|
Binary file (4.52 kB). View file
|
|
|
aureon_backend/__pycache__/urls.cpython-313.pyc
ADDED
|
Binary file (473 Bytes). View file
|
|
|
aureon_backend/__pycache__/urls.cpython-314.pyc
ADDED
|
Binary file (475 Bytes). View file
|
|
|
aureon_backend/__pycache__/wsgi.cpython-313.pyc
ADDED
|
Binary file (687 Bytes). View file
|
|
|
aureon_backend/__pycache__/wsgi.cpython-314.pyc
ADDED
|
Binary file (684 Bytes). View file
|
|
|
aureon_backend/asgi.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
ASGI config for aureon_backend project.
|
| 3 |
+
|
| 4 |
+
It exposes the ASGI callable as a module-level variable named ``application``.
|
| 5 |
+
|
| 6 |
+
For more information on this file, see
|
| 7 |
+
https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
import os
|
| 11 |
+
|
| 12 |
+
from django.core.asgi import get_asgi_application
|
| 13 |
+
|
| 14 |
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'aureon_backend.settings')
|
| 15 |
+
|
| 16 |
+
application = get_asgi_application()
|
aureon_backend/settings.py
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# backend/aureon_backend/settings.py
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
import dj_database_url
|
| 6 |
+
from dotenv import load_dotenv
|
| 7 |
+
|
| 8 |
+
load_dotenv()
|
| 9 |
+
|
| 10 |
+
BASE_DIR = Path(__file__).resolve().parent.parent
|
| 11 |
+
SECRET_KEY = os.getenv('SECRET_KEY', 'django-insecure-default-key')
|
| 12 |
+
DEBUG = os.getenv('DEBUG', 'True') == 'True'
|
| 13 |
+
ALLOWED_HOSTS = ['*']
|
| 14 |
+
|
| 15 |
+
INSTALLED_APPS = [
|
| 16 |
+
'django.contrib.admin',
|
| 17 |
+
'django.contrib.auth',
|
| 18 |
+
'django.contrib.contenttypes',
|
| 19 |
+
'django.contrib.sessions',
|
| 20 |
+
'django.contrib.messages',
|
| 21 |
+
'django.contrib.staticfiles',
|
| 22 |
+
'rest_framework',
|
| 23 |
+
'corsheaders',
|
| 24 |
+
'users',
|
| 25 |
+
'finance',
|
| 26 |
+
'ai_assistant',
|
| 27 |
+
'importer',
|
| 28 |
+
]
|
| 29 |
+
|
| 30 |
+
MIDDLEWARE = [
|
| 31 |
+
'corsheaders.middleware.CorsMiddleware',
|
| 32 |
+
'django.middleware.security.SecurityMiddleware',
|
| 33 |
+
'django.contrib.sessions.middleware.SessionMiddleware',
|
| 34 |
+
'django.middleware.common.CommonMiddleware',
|
| 35 |
+
'django.middleware.csrf.CsrfViewMiddleware',
|
| 36 |
+
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
| 37 |
+
'django.contrib.messages.middleware.MessageMiddleware',
|
| 38 |
+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
| 39 |
+
]
|
| 40 |
+
|
| 41 |
+
ROOT_URLCONF = 'aureon_backend.urls'
|
| 42 |
+
|
| 43 |
+
TEMPLATES = [
|
| 44 |
+
{
|
| 45 |
+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
| 46 |
+
'DIRS': [],
|
| 47 |
+
'APP_DIRS': True,
|
| 48 |
+
'OPTIONS': {
|
| 49 |
+
'context_processors': [
|
| 50 |
+
'django.template.context_processors.debug',
|
| 51 |
+
'django.template.context_processors.request',
|
| 52 |
+
'django.contrib.auth.context_processors.auth',
|
| 53 |
+
'django.contrib.messages.context_processors.messages',
|
| 54 |
+
],
|
| 55 |
+
},
|
| 56 |
+
},
|
| 57 |
+
]
|
| 58 |
+
|
| 59 |
+
WSGI_APPLICATION = 'aureon_backend.wsgi.application'
|
| 60 |
+
|
| 61 |
+
DATABASES = {
|
| 62 |
+
'default': dj_database_url.config(
|
| 63 |
+
default=os.getenv('DATABASE_URL'),
|
| 64 |
+
conn_max_age=600,
|
| 65 |
+
conn_health_checks=True,
|
| 66 |
+
ssl_require=True,
|
| 67 |
+
)
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
AUTH_PASSWORD_VALIDATORS = [
|
| 71 |
+
{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'},
|
| 72 |
+
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
|
| 73 |
+
{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'},
|
| 74 |
+
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'},
|
| 75 |
+
]
|
| 76 |
+
|
| 77 |
+
LANGUAGE_CODE = 'en-us'
|
| 78 |
+
TIME_ZONE = 'UTC'
|
| 79 |
+
USE_I18N = True
|
| 80 |
+
USE_TZ = True
|
| 81 |
+
STATIC_URL = 'static/'
|
| 82 |
+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
| 83 |
+
|
| 84 |
+
AUTH_USER_MODEL = 'users.User'
|
| 85 |
+
|
| 86 |
+
REST_FRAMEWORK = {
|
| 87 |
+
'DEFAULT_AUTHENTICATION_CLASSES': [
|
| 88 |
+
'users.authentication.SupabaseAuthentication',
|
| 89 |
+
],
|
| 90 |
+
'DEFAULT_PERMISSION_CLASSES': [
|
| 91 |
+
'rest_framework.permissions.IsAuthenticated',
|
| 92 |
+
],
|
| 93 |
+
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
# Supabase Configuration
|
| 97 |
+
SUPABASE_URL = os.getenv('SUPABASE_URL')
|
| 98 |
+
SUPABASE_KEY = os.getenv('SUPABASE_KEY')
|
| 99 |
+
SUPABASE_JWT_SECRET = os.getenv('SUPABASE_JWT_SECRET') # Optional - only needed for HS256
|
| 100 |
+
|
| 101 |
+
# CORS Configuration
|
| 102 |
+
CORS_ALLOW_ALL_ORIGINS = True
|
| 103 |
+
CORS_ALLOW_CREDENTIALS = True
|
| 104 |
+
CORS_ALLOW_HEADERS = [
|
| 105 |
+
'accept',
|
| 106 |
+
'accept-encoding',
|
| 107 |
+
'authorization',
|
| 108 |
+
'content-type',
|
| 109 |
+
'dnt',
|
| 110 |
+
'origin',
|
| 111 |
+
'user-agent',
|
| 112 |
+
'x-csrftoken',
|
| 113 |
+
'x-requested-with',
|
| 114 |
+
]
|
| 115 |
+
CORS_ALLOW_METHODS = [
|
| 116 |
+
'DELETE',
|
| 117 |
+
'GET',
|
| 118 |
+
'OPTIONS',
|
| 119 |
+
'PATCH',
|
| 120 |
+
'POST',
|
| 121 |
+
'PUT',
|
| 122 |
+
]
|
| 123 |
+
|
| 124 |
+
# CSRF Settings
|
| 125 |
+
CSRF_TRUSTED_ORIGINS = ['http://localhost:5173', 'http://127.0.0.1:5173']
|
| 126 |
+
CSRF_COOKIE_SECURE = False
|
| 127 |
+
CSRF_COOKIE_HTTPONLY = False
|
| 128 |
+
|
| 129 |
+
# Cache Configuration (required for JWKS key caching)
|
| 130 |
+
CACHES = {
|
| 131 |
+
'default': {
|
| 132 |
+
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
| 133 |
+
'LOCATION': 'unique-snowflake',
|
| 134 |
+
'TIMEOUT': 3600, # 1 hour
|
| 135 |
+
'OPTIONS': {
|
| 136 |
+
'MAX_ENTRIES': 1000
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
# Email Settings (SendGrid)
|
| 142 |
+
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
| 143 |
+
EMAIL_HOST = 'smtp.sendgrid.net'
|
| 144 |
+
EMAIL_PORT = 587
|
| 145 |
+
EMAIL_USE_TLS = True
|
| 146 |
+
EMAIL_HOST_USER = 'apikey'
|
| 147 |
+
EMAIL_HOST_PASSWORD = os.getenv('SENDGRID_API_KEY', '')
|
| 148 |
+
DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'noreply@aureon.com')
|
| 149 |
+
|
| 150 |
+
# Logging Configuration
|
| 151 |
+
LOGGING = {
|
| 152 |
+
'version': 1,
|
| 153 |
+
'disable_existing_loggers': False,
|
| 154 |
+
'handlers': {
|
| 155 |
+
'console': {
|
| 156 |
+
'class': 'logging.StreamHandler',
|
| 157 |
+
},
|
| 158 |
+
},
|
| 159 |
+
'root': {
|
| 160 |
+
'handlers': ['console'],
|
| 161 |
+
'level': 'INFO',
|
| 162 |
+
},
|
| 163 |
+
'loggers': {
|
| 164 |
+
'django': {
|
| 165 |
+
'handlers': ['console'],
|
| 166 |
+
'level': 'INFO',
|
| 167 |
+
'propagate': False,
|
| 168 |
+
},
|
| 169 |
+
},
|
| 170 |
+
}
|
aureon_backend/urls.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# backend/aureon_backend/urls.py
|
| 2 |
+
from django.contrib import admin
|
| 3 |
+
from django.urls import path, include
|
| 4 |
+
|
| 5 |
+
urlpatterns = [
|
| 6 |
+
path('admin/', admin.site.urls),
|
| 7 |
+
path('api/auth/', include('users.urls')), # This creates /api/auth/me/
|
| 8 |
+
# path('api/finance/', include('finance.urls')), # We will uncomment this later
|
| 9 |
+
]
|
aureon_backend/wsgi.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
WSGI config for aureon_backend project.
|
| 3 |
+
|
| 4 |
+
It exposes the WSGI callable as a module-level variable named ``application``.
|
| 5 |
+
|
| 6 |
+
For more information on this file, see
|
| 7 |
+
https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
import os
|
| 11 |
+
|
| 12 |
+
from django.core.wsgi import get_wsgi_application
|
| 13 |
+
|
| 14 |
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'aureon_backend.settings')
|
| 15 |
+
|
| 16 |
+
application = get_wsgi_application()
|
debug_token.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# backend/debug_token.py
|
| 2 |
+
"""
|
| 3 |
+
Run this script to debug JWT token issues:
|
| 4 |
+
python debug_token.py
|
| 5 |
+
|
| 6 |
+
This will help you understand what's in your token and verify your JWT secret.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
import jwt
|
| 10 |
+
import json
|
| 11 |
+
import sys
|
| 12 |
+
import os
|
| 13 |
+
|
| 14 |
+
# Add the parent directory to the path so we can import settings
|
| 15 |
+
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
| 16 |
+
|
| 17 |
+
# Try to load Django settings
|
| 18 |
+
try:
|
| 19 |
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'aureon_backend.settings')
|
| 20 |
+
import django
|
| 21 |
+
django.setup()
|
| 22 |
+
from django.conf import settings
|
| 23 |
+
SUPABASE_JWT_SECRET = settings.SUPABASE_JWT_SECRET
|
| 24 |
+
print(f"β
Loaded JWT_SECRET from Django settings")
|
| 25 |
+
print(f" JWT_SECRET (first 20 chars): {SUPABASE_JWT_SECRET[:20]}...")
|
| 26 |
+
except Exception as e:
|
| 27 |
+
print(f"β οΈ Could not load Django settings: {e}")
|
| 28 |
+
print(f" Please enter your JWT_SECRET manually below")
|
| 29 |
+
SUPABASE_JWT_SECRET = None
|
| 30 |
+
|
| 31 |
+
print("\n" + "="*60)
|
| 32 |
+
print("SUPABASE JWT TOKEN DEBUGGER")
|
| 33 |
+
print("="*60)
|
| 34 |
+
|
| 35 |
+
# Get token from user
|
| 36 |
+
print("\nPaste your Supabase token here:")
|
| 37 |
+
print("(You can get it from localStorage in your browser console)")
|
| 38 |
+
print("localStorage.getItem('supabase_token')")
|
| 39 |
+
print()
|
| 40 |
+
token = input("Token: ").strip()
|
| 41 |
+
|
| 42 |
+
if not token:
|
| 43 |
+
print("β No token provided!")
|
| 44 |
+
sys.exit(1)
|
| 45 |
+
|
| 46 |
+
print("\n" + "-"*60)
|
| 47 |
+
print("STEP 1: Decode Header (unverified)")
|
| 48 |
+
print("-"*60)
|
| 49 |
+
|
| 50 |
+
try:
|
| 51 |
+
header = jwt.get_unverified_header(token)
|
| 52 |
+
print("β
Token Header:")
|
| 53 |
+
print(json.dumps(header, indent=2))
|
| 54 |
+
algorithm = header.get('alg', 'UNKNOWN')
|
| 55 |
+
print(f"\nπ Algorithm: {algorithm}")
|
| 56 |
+
except Exception as e:
|
| 57 |
+
print(f"β Could not decode header: {e}")
|
| 58 |
+
sys.exit(1)
|
| 59 |
+
|
| 60 |
+
print("\n" + "-"*60)
|
| 61 |
+
print("STEP 2: Decode Payload (unverified)")
|
| 62 |
+
print("-"*60)
|
| 63 |
+
|
| 64 |
+
try:
|
| 65 |
+
# Decode without verification to see the contents
|
| 66 |
+
payload = jwt.decode(token, options={"verify_signature": False})
|
| 67 |
+
print("β
Token Payload:")
|
| 68 |
+
print(json.dumps(payload, indent=2))
|
| 69 |
+
|
| 70 |
+
print(f"\nπ Key Information:")
|
| 71 |
+
print(f" User ID (sub): {payload.get('sub', 'NOT FOUND')}")
|
| 72 |
+
print(f" Email: {payload.get('email', 'NOT FOUND')}")
|
| 73 |
+
print(f" Audience: {payload.get('aud', 'NOT FOUND')}")
|
| 74 |
+
print(f" Issuer: {payload.get('iss', 'NOT FOUND')}")
|
| 75 |
+
|
| 76 |
+
# Check expiration
|
| 77 |
+
import time
|
| 78 |
+
exp = payload.get('exp')
|
| 79 |
+
if exp:
|
| 80 |
+
exp_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(exp))
|
| 81 |
+
is_expired = exp < time.time()
|
| 82 |
+
print(f" Expires: {exp_date} {'(EXPIRED!)' if is_expired else '(valid)'}")
|
| 83 |
+
|
| 84 |
+
except Exception as e:
|
| 85 |
+
print(f"β Could not decode payload: {e}")
|
| 86 |
+
sys.exit(1)
|
| 87 |
+
|
| 88 |
+
print("\n" + "-"*60)
|
| 89 |
+
print("STEP 3: Verify Signature")
|
| 90 |
+
print("-"*60)
|
| 91 |
+
|
| 92 |
+
if not SUPABASE_JWT_SECRET:
|
| 93 |
+
print("Enter your SUPABASE_JWT_SECRET:")
|
| 94 |
+
SUPABASE_JWT_SECRET = input("JWT_SECRET: ").strip()
|
| 95 |
+
|
| 96 |
+
if not SUPABASE_JWT_SECRET:
|
| 97 |
+
print("β οΈ No JWT_SECRET provided - skipping verification")
|
| 98 |
+
else:
|
| 99 |
+
try:
|
| 100 |
+
# Try to decode with verification
|
| 101 |
+
verified_payload = jwt.decode(
|
| 102 |
+
token,
|
| 103 |
+
SUPABASE_JWT_SECRET,
|
| 104 |
+
algorithms=[algorithm],
|
| 105 |
+
audience="authenticated"
|
| 106 |
+
)
|
| 107 |
+
print("β
Signature verification PASSED!")
|
| 108 |
+
print(" Your JWT_SECRET is CORRECT!")
|
| 109 |
+
|
| 110 |
+
except jwt.InvalidSignatureError:
|
| 111 |
+
print("β Signature verification FAILED!")
|
| 112 |
+
print(" Your JWT_SECRET is WRONG!")
|
| 113 |
+
print("\n How to find the correct JWT_SECRET:")
|
| 114 |
+
print(" 1. Go to your Supabase Dashboard")
|
| 115 |
+
print(" 2. Settings β API")
|
| 116 |
+
print(" 3. Look for 'JWT Secret' (NOT the service key)")
|
| 117 |
+
print(" 4. Copy that value to your .env file as SUPABASE_JWT_SECRET")
|
| 118 |
+
|
| 119 |
+
except jwt.ExpiredSignatureError:
|
| 120 |
+
print("β Token has EXPIRED!")
|
| 121 |
+
print(" Solution: Logout and login again to get a new token")
|
| 122 |
+
|
| 123 |
+
except jwt.InvalidAudienceError:
|
| 124 |
+
print("β Invalid audience!")
|
| 125 |
+
print(" The token audience doesn't match 'authenticated'")
|
| 126 |
+
|
| 127 |
+
except jwt.InvalidAlgorithmError as e:
|
| 128 |
+
print(f"β Algorithm error: {e}")
|
| 129 |
+
print(f" The token uses {algorithm} but it's not allowed")
|
| 130 |
+
|
| 131 |
+
except Exception as e:
|
| 132 |
+
print(f"β Verification error: {type(e).__name__}: {e}")
|
| 133 |
+
|
| 134 |
+
print("\n" + "="*60)
|
| 135 |
+
print("SUMMARY")
|
| 136 |
+
print("="*60)
|
| 137 |
+
|
| 138 |
+
print(f"\nβ Token structure: Valid")
|
| 139 |
+
print(f"β Algorithm: {algorithm}")
|
| 140 |
+
print(f"β User ID present: {'Yes' if payload.get('sub') else 'No'}")
|
| 141 |
+
print(f"β Email present: {'Yes' if payload.get('email') else 'No'}")
|
| 142 |
+
|
| 143 |
+
if SUPABASE_JWT_SECRET:
|
| 144 |
+
print(f"\nNext steps:")
|
| 145 |
+
print(f"1. Make sure backend/aureon_backend/settings.py uses:")
|
| 146 |
+
print(f" algorithms=['{algorithm}']")
|
| 147 |
+
print(f"2. Make sure your .env has the correct JWT_SECRET")
|
| 148 |
+
print(f"3. Restart Django server")
|
| 149 |
+
else:
|
| 150 |
+
print(f"\nβ οΈ Could not verify signature - JWT_SECRET not provided")
|
| 151 |
+
|
| 152 |
+
print("\n")
|
finance/__init__.py
ADDED
|
File without changes
|
finance/__pycache__/__init__.cpython-313.pyc
ADDED
|
Binary file (178 Bytes). View file
|
|
|
finance/__pycache__/__init__.cpython-314.pyc
ADDED
|
Binary file (180 Bytes). View file
|
|
|
finance/__pycache__/admin.cpython-313.pyc
ADDED
|
Binary file (222 Bytes). View file
|
|
|
finance/__pycache__/admin.cpython-314.pyc
ADDED
|
Binary file (224 Bytes). View file
|
|
|
finance/__pycache__/apps.cpython-313.pyc
ADDED
|
Binary file (483 Bytes). View file
|
|
|
finance/__pycache__/apps.cpython-314.pyc
ADDED
|
Binary file (482 Bytes). View file
|
|
|
finance/__pycache__/models.cpython-313.pyc
ADDED
|
Binary file (219 Bytes). View file
|
|
|
finance/__pycache__/models.cpython-314.pyc
ADDED
|
Binary file (221 Bytes). View file
|
|
|
finance/admin.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.contrib import admin
|
| 2 |
+
|
| 3 |
+
# Register your models here.
|
finance/apps.py
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.apps import AppConfig
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
class FinanceConfig(AppConfig):
|
| 5 |
+
name = 'finance'
|
finance/migrations/__init__.py
ADDED
|
File without changes
|
finance/migrations/__pycache__/__init__.cpython-313.pyc
ADDED
|
Binary file (189 Bytes). View file
|
|
|
finance/migrations/__pycache__/__init__.cpython-314.pyc
ADDED
|
Binary file (191 Bytes). View file
|
|
|
finance/models.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.db import models
|
| 2 |
+
|
| 3 |
+
# Create your models here.
|
finance/tests.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.test import TestCase
|
| 2 |
+
|
| 3 |
+
# Create your tests here.
|
finance/views.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from django.shortcuts import render
|
| 2 |
+
|
| 3 |
+
# Create your views here.
|
importer/__init__.py
ADDED
|
File without changes
|