-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
113 lines (102 loc) · 3.17 KB
/
config.py
File metadata and controls
113 lines (102 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import os
import secrets
from dotenv import load_dotenv
load_dotenv()
class Config:
# Security settings
SECRET_KEY = os.getenv("SECRET_KEY")
REQUIRE_LOGIN = os.getenv("REQUIRE_LOGIN", "True").lower() == "true"
# Generate random secret key for development if not set
if SECRET_KEY is None:
if os.environ.get("FLASK_ENV") == "production":
raise ValueError(
"SECRET_KEY must be set in production environment. "
"Generate one with: python -c 'import secrets; print(secrets.token_hex(32))'"
)
else:
# Auto-generate for development (will change on restart)
SECRET_KEY = secrets.token_hex(32)
print(
"WARNING: Using auto-generated SECRET_KEY for development. Set SECRET_KEY in .env for persistence."
)
# Database settings
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL")
SQLALCHEMY_TRACK_MODIFICATIONS = False
# Session cookie settings (security)
SESSION_COOKIE_HTTPONLY = True # Prevent JavaScript access to session cookie
SESSION_COOKIE_SAMESITE = "Lax" # CSRF protection
SESSION_COOKIE_SECURE = os.getenv("FLASK_ENV") == "production"
REMEMBER_COOKIE_SECURE = os.getenv("FLASK_ENV") == "production"
# File upload configuration
UPLOAD_FOLDER = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "app", "static", "uploads"
)
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16 MB max file size
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "webp"}
IMAGE_MAX_WIDTH = 1200 # Automatically resize images to this width
IMAGE_QUALITY = 85 # WebP quality (1-100)
# Rate limiting configuration
COMMENT_RATE_LIMIT = "10 per minute"
LOGIN_RATE_LIMIT = "5 per minute"
# Markdown rendering configuration
MARKDOWN_ALLOWED_TAGS = [
"a",
"abbr",
"acronym",
"b",
"blockquote",
"br",
"code",
"div",
"em",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"hr",
"i",
"img",
"li",
"ol",
"p",
"pre",
"span",
"strong",
"table",
"tbody",
"td",
"th",
"thead",
"tr",
"ul",
"del",
"ins",
"sup",
"sub",
]
MARKDOWN_ALLOWED_ATTRIBUTES = {
"a": ["href", "title", "rel"],
"abbr": ["title"],
"acronym": ["title"],
"img": ["src", "alt", "title", "width", "height", "class"],
"div": ["class", "style"], # Pygments wrapper
"span": [
"class",
"style",
"data-lang",
], # Pygments syntax tokens and language markers
"code": ["class", "style"], # Code elements
"pre": ["class", "style"], # Code blocks
"td": ["align"],
"th": ["align"],
"h1": ["id"], # For header anchors
"h2": ["id"],
"h3": ["id"],
"h4": ["id"],
"h5": ["id"],
"h6": ["id"],
}
MARKDOWN_ALLOWED_PROTOCOLS = ["http", "https", "mailto", "vless"]