fix: crash upon startup
All checks were successful
Deploy Plattform-Core (Int) / test (push) Successful in 53s
Deploy Plattform-Core (Int) / deploy (push) Successful in 9s

This commit is contained in:
Ida 2026-05-29 07:19:30 +02:00
parent 3345f65c40
commit 3b0881b0ca
6 changed files with 4 additions and 26 deletions

2
app.py
View file

@ -564,7 +564,6 @@ from modules.auth import (
# without having to thread them through every call site. # without having to thread them through every call site.
from modules.shared.i18nRegistry import setLanguage, normalizePrimaryLanguageTag from modules.shared.i18nRegistry import setLanguage, normalizePrimaryLanguageTag
from modules.shared.timeUtils import setRequestTimezone from modules.shared.timeUtils import setRequestTimezone
from modules.shared.requestFrontendUrl import resolveFrontendUrlFromRequest, setRequestFrontendUrl
@app.middleware("http") @app.middleware("http")
async def _requestContextMiddleware(request: Request, call_next): async def _requestContextMiddleware(request: Request, call_next):
@ -572,7 +571,6 @@ async def _requestContextMiddleware(request: Request, call_next):
lang = normalizePrimaryLanguageTag(acceptLang, "de") lang = normalizePrimaryLanguageTag(acceptLang, "de")
setLanguage(lang) setLanguage(lang)
setRequestTimezone(request.headers.get("X-User-Timezone", "")) setRequestTimezone(request.headers.get("X-User-Timezone", ""))
setRequestFrontendUrl(resolveFrontendUrlFromRequest(request))
return await call_next(request) return await call_next(request)
app.add_middleware(CSRFMiddleware) app.add_middleware(CSRFMiddleware)

View file

@ -4,12 +4,7 @@
APP_ENV_TYPE = dev APP_ENV_TYPE = dev
APP_ENV_LABEL = Development Instance Patrick APP_ENV_LABEL = Development Instance Patrick
APP_API_URL = http://localhost:8000 APP_API_URL = http://localhost:8000
<<<<<<< Updated upstream
APP_KEY_SYSVAR = D:/Athi/Local/Web/poweron-swiss/local/notes/key.txt APP_KEY_SYSVAR = D:/Athi/Local/Web/poweron-swiss/local/notes/key.txt
=======
APP_FRONTEND_URL = http://localhost:5176
APP_KEY_SYSVAR = D:/Athi/Local/Web/poweron/local/notes/key.txt
>>>>>>> Stashed changes
APP_INIT_PASS_ADMIN_SECRET = DEV_ENC:Z0FBQUFBQm8xSUpEeFFtRGtQeVUtcjlrU3dab1ZxUm9WSks0MlJVYUtERFlqUElHemZrOGNENk1tcmJNX3Vxc01UMDhlNU40VzZZRVBpUGNmT3podzZrOGhOeEJIUEt4eVlSWG5UYXA3d09DVXlLT21Kb1JYSUU9 APP_INIT_PASS_ADMIN_SECRET = DEV_ENC:Z0FBQUFBQm8xSUpEeFFtRGtQeVUtcjlrU3dab1ZxUm9WSks0MlJVYUtERFlqUElHemZrOGNENk1tcmJNX3Vxc01UMDhlNU40VzZZRVBpUGNmT3podzZrOGhOeEJIUEt4eVlSWG5UYXA3d09DVXlLT21Kb1JYSUU9
APP_INIT_PASS_EVENT_SECRET = DEV_ENC:Z0FBQUFBQm8xSUpERzZjNm56WGVBdjJTeG5Udjd6OGQwUVotYXUzQjJ1YVNyVXVBa3NZVml3ODU0MVNkZjhWWmJwNUFkc19BcHlHMTU1Q3BRcHU0cDBoZkFlR2l6UEZQU3d2U3MtMDh5UDZteGFoQ0EyMUE1ckE9 APP_INIT_PASS_EVENT_SECRET = DEV_ENC:Z0FBQUFBQm8xSUpERzZjNm56WGVBdjJTeG5Udjd6OGQwUVotYXUzQjJ1YVNyVXVBa3NZVml3ODU0MVNkZjhWWmJwNUFkc19BcHlHMTU1Q3BRcHU0cDBoZkFlR2l6UEZQU3d2U3MtMDh5UDZteGFoQ0EyMUE1ckE9

View file

@ -4,7 +4,6 @@
APP_ENV_TYPE = int APP_ENV_TYPE = int
APP_ENV_LABEL = Integration Instance APP_ENV_LABEL = Integration Instance
APP_API_URL = https://api-int.poweron.swiss APP_API_URL = https://api-int.poweron.swiss
APP_FRONTEND_URL = https://nyla-int.poweron.swiss
# Force SameSite=None+Secure for auth cookies (cross-site UI on poweron-center.net). Optional if APP_API_URL is https:// # Force SameSite=None+Secure for auth cookies (cross-site UI on poweron-center.net). Optional if APP_API_URL is https://
APP_COOKIE_SECURE = true APP_COOKIE_SECURE = true
APP_KEY_SYSVAR = /srv/gateway/shared/secrets/master_key.txt APP_KEY_SYSVAR = /srv/gateway/shared/secrets/master_key.txt

View file

@ -7,7 +7,6 @@ APP_KEY_SYSVAR = /srv/gateway/shared/secrets/master_key.txt
APP_INIT_PASS_ADMIN_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3UnJRV0sySFlDblpXUlREclREaW1WbUt6bGtQYkdrNkZDOXNOLXFua1hqeFF2RHJnRXJ5VlVGV3hOZm41QjZOMlNTb0duYXNxZi05dXVTc2xDVkx0SVBFLUhncVo5T0VUZHE0UTZLWWw3ck09 APP_INIT_PASS_ADMIN_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3UnJRV0sySFlDblpXUlREclREaW1WbUt6bGtQYkdrNkZDOXNOLXFua1hqeFF2RHJnRXJ5VlVGV3hOZm41QjZOMlNTb0duYXNxZi05dXVTc2xDVkx0SVBFLUhncVo5T0VUZHE0UTZLWWw3ck09
APP_INIT_PASS_EVENT_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3QVpIY19DQVZSSzJmc2F0VEZvQlU1cHBhTEgxdHdnR3g4eW01aTEzYTUxc1gxTDR1RVVpSHRXYjV6N1BLZUdCUGlfOW1qdy0xSHFVRkNBcGZvaGlSSkZycXRuUllaWnpyVGRoeFg1dGEyNUk9 APP_INIT_PASS_EVENT_SECRET = PROD_ENC:Z0FBQUFBQnBDM1Z3QVpIY19DQVZSSzJmc2F0VEZvQlU1cHBhTEgxdHdnR3g4eW01aTEzYTUxc1gxTDR1RVVpSHRXYjV6N1BLZUdCUGlfOW1qdy0xSHFVRkNBcGZvaGlSSkZycXRuUllaWnpyVGRoeFg1dGEyNUk9
APP_API_URL = https://api.poweron.swiss APP_API_URL = https://api.poweron.swiss
APP_FRONTEND_URL = https://nyla.poweron.swiss
# PostgreSQL DB Host (porta-main-db on Infomaniak Public Cloud) # PostgreSQL DB Host (porta-main-db on Infomaniak Public Cloud)
DB_HOST=db.poweron.swiss DB_HOST=db.poweron.swiss

View file

@ -39,7 +39,7 @@ def maybeEmailMandatePoolExhausted(
currentBalance: Pool balance (CHF). currentBalance: Pool balance (CHF).
requiredAmount: Minimum required (CHF). requiredAmount: Minimum required (CHF).
cooldownSec: Minimum seconds between emails for this mandate. cooldownSec: Minimum seconds between emails for this mandate.
frontendUrl: Optional frontend base URL for /billing/admin link (defaults to request Origin). frontendUrl: Optional frontend base URL for /billing/admin link (omit to send email without CTA).
""" """
if not mandateId: if not mandateId:
return return

View file

@ -166,19 +166,6 @@ def buildBillingAdminActionBlock(
return buildActionLinkHtmlBlock(admin_url, buttonText) return buildActionLinkHtmlBlock(admin_url, buttonText)
def _resolveBillingAdminFrontendUrl(frontendUrl: Optional[str]) -> str:
"""Explicit frontendUrl param, else per-request value from middleware."""
explicit = (frontendUrl or "").strip().rstrip("/")
if explicit:
return explicit
try:
from modules.shared.requestFrontendUrl import getRequestFrontendUrl
return getRequestFrontendUrl()
except Exception:
return ""
def _getOperatorInfo() -> Dict[str, str]: def _getOperatorInfo() -> Dict[str, str]:
"""Load operator company data from config.ini.""" """Load operator company data from config.ini."""
try: try:
@ -303,7 +290,7 @@ def notifyMandateAdmins(
rawHtmlBlock: Optional pre-formatted HTML block (e.g. invoice summary table). rawHtmlBlock: Optional pre-formatted HTML block (e.g. invoice summary table).
includeBillingAdminLink: When True, append button + link to {frontendUrl}/billing/admin. includeBillingAdminLink: When True, append button + link to {frontendUrl}/billing/admin.
billingAdminButtonText: Label for the billing admin CTA button. billingAdminButtonText: Label for the billing admin CTA button.
frontendUrl: Frontend base URL (like auth emails); defaults to per-request Origin / X-Frontend-Url. frontendUrl: Frontend base URL for the billing admin link (required when includeBillingAdminLink is True).
Returns: Returns:
Number of recipients that were successfully notified. Number of recipients that were successfully notified.
@ -323,11 +310,11 @@ def notifyMandateAdmins(
mandateName = resolveMandateName(mandateId) mandateName = resolveMandateName(mandateId)
actionHtmlBlock = None actionHtmlBlock = None
if includeBillingAdminLink: if includeBillingAdminLink:
resolved_frontend = _resolveBillingAdminFrontendUrl(frontendUrl) resolved_frontend = (frontendUrl or "").strip().rstrip("/")
actionHtmlBlock = buildBillingAdminActionBlock(resolved_frontend, billingAdminButtonText) or None actionHtmlBlock = buildBillingAdminActionBlock(resolved_frontend, billingAdminButtonText) or None
if not actionHtmlBlock: if not actionHtmlBlock:
logger.warning( logger.warning(
"notifyMandateAdmins: billing admin link omitted (no frontendUrl on request)" "notifyMandateAdmins: billing admin link omitted (no frontendUrl provided)"
) )
htmlMessage = renderHtmlEmail( htmlMessage = renderHtmlEmail(
headline, bodyParagraphs, mandateName, footerNote, rawHtmlBlock, actionHtmlBlock, headline, bodyParagraphs, mandateName, footerNote, rawHtmlBlock, actionHtmlBlock,