|
1 | 1 | """ |
2 | 2 | Django settings for core project. |
3 | | -
|
4 | | -Generated by 'django-admin startproject' using Django 6.0.2. |
5 | | -
|
6 | | -For more information on this file, see |
7 | | -https://docs.djangoproject.com/en/6.0/topics/settings/ |
8 | | -
|
9 | | -For the full list of settings and their values, see |
10 | | -https://docs.djangoproject.com/en/6.0/ref/settings/ |
11 | 3 | """ |
12 | 4 |
|
13 | 5 | from pathlib import Path |
|
19 | 11 | # Build paths inside the project like this: BASE_DIR / 'subdir'. |
20 | 12 | BASE_DIR = Path(__file__).resolve().parent.parent |
21 | 13 |
|
22 | | - |
23 | | -# Quick-start development settings - unsuitable for production |
24 | | -# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ |
25 | | - |
26 | 14 | # SECURITY WARNING: keep the secret key used in production secret! |
27 | 15 | SECRET_KEY = os.getenv('SECRET_KEY', 'django-insecure-4!)sv6=xv!rd-%py*h**vhrm)m(%-_2^j()bs&j9uj2u8!fkv6') |
28 | 16 |
|
|
31 | 19 |
|
32 | 20 | ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '').split(',') if os.getenv('ALLOWED_HOSTS') else ['*'] |
33 | 21 |
|
34 | | - |
35 | 22 | # Application definition |
36 | | - |
37 | 23 | INSTALLED_APPS = [ |
38 | 24 | 'django.contrib.admin', |
39 | 25 | 'django.contrib.auth', |
|
49 | 35 | ] |
50 | 36 |
|
51 | 37 | MIDDLEWARE = [ |
52 | | - 'corsheaders.middleware.CorsMiddleware', |
| 38 | + 'corsheaders.middleware.CorsMiddleware', # Preflight and CORS must be FIRST |
53 | 39 | 'django.middleware.security.SecurityMiddleware', |
54 | 40 | 'whitenoise.middleware.WhiteNoiseMiddleware', |
55 | 41 | 'django.contrib.sessions.middleware.SessionMiddleware', |
|
61 | 47 | ] |
62 | 48 |
|
63 | 49 | ROOT_URLCONF = 'core.urls' |
| 50 | + |
| 51 | +# IMPORTANT: User requested no trailing slashes. |
| 52 | +# Disabling APPEND_SLASH prevents Django from automatically redirecting to / versions. |
64 | 53 | APPEND_SLASH = False |
65 | 54 |
|
66 | 55 | TEMPLATES = [ |
|
80 | 69 |
|
81 | 70 | WSGI_APPLICATION = 'core.wsgi.application' |
82 | 71 |
|
83 | | - |
84 | 72 | # Database |
85 | | -# https://docs.djangoproject.com/en/6.0/ref/settings/#databases |
86 | | - |
87 | 73 | DATABASES = {} |
88 | 74 |
|
89 | | -# CORS settings |
| 75 | +# CORS settings - Bulletproof for Netlify migration |
90 | 76 | CORS_ALLOW_ALL_ORIGINS = True |
| 77 | +CORS_ORIGIN_ALLOW_ALL = True # Legacy compatibility |
91 | 78 | CORS_ALLOW_CREDENTIALS = True |
92 | | -# Fallback for strict environments (Netlify + Vercel) |
| 79 | + |
| 80 | +# Explicitly Trusting modern origins to prevent browser-side rejections |
93 | 81 | CORS_ALLOWED_ORIGINS = [ |
94 | 82 | "https://hrms-lite-frontend.vercel.app", |
95 | 83 | "https://hrms-lite-version.netlify.app", |
96 | 84 | ] |
| 85 | + |
97 | 86 | CORS_ALLOWED_ORIGIN_REGEXES = [ |
98 | 87 | r"^https://.*\.netlify\.app$", |
99 | 88 | r"^https://.*\.vercel\.app$", |
100 | 89 | ] |
101 | 90 |
|
| 91 | +# CSRF security for POST requests from cross-origin domains |
| 92 | +CSRF_TRUSTED_ORIGINS = [ |
| 93 | + "https://hrms-lite-frontend.vercel.app", |
| 94 | + "https://hrms-lite-version.netlify.app", |
| 95 | +] |
102 | 96 |
|
103 | 97 | # Password validation |
104 | | -# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators |
105 | | - |
106 | 98 | AUTH_PASSWORD_VALIDATORS = [ |
107 | | - { |
108 | | - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', |
109 | | - }, |
110 | | - { |
111 | | - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', |
112 | | - }, |
113 | | - { |
114 | | - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', |
115 | | - }, |
116 | | - { |
117 | | - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', |
118 | | - }, |
| 99 | + {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, |
| 100 | + {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, |
| 101 | + {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, |
| 102 | + {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, |
119 | 103 | ] |
120 | 104 |
|
121 | | - |
122 | 105 | # Internationalization |
123 | | -# https://docs.djangoproject.com/en/6.0/topics/i18n/ |
124 | | - |
125 | 106 | LANGUAGE_CODE = 'en-us' |
126 | | - |
127 | 107 | TIME_ZONE = 'UTC' |
128 | | - |
129 | 108 | USE_I18N = True |
130 | | - |
131 | 109 | USE_TZ = True |
132 | 110 |
|
133 | | - |
134 | 111 | # Static files (CSS, JavaScript, Images) |
135 | | -# https://docs.djangoproject.com/en/6.0/howto/static-files/ |
136 | | - |
137 | 112 | STATIC_URL = '/static/' |
138 | 113 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') |
139 | 114 | STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' |
0 commit comments