- Correctie reset password en confirm email adress by adapting the prefixed_url_for to use config setting
- Adaptation of DPA and T&Cs - Refer to privacy statement as DPA, not a privacy statement - Startup of enforcing signed DPA and T&Cs - Adaptation of eveai_chat_client to ensure we retrieve correct DPA & T&Cs
This commit is contained in:
@@ -1,14 +1,39 @@
|
||||
from flask import request, url_for
|
||||
from flask import request, url_for, current_app
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
import re
|
||||
|
||||
VISIBLE_PREFIXES = ('/admin', '/api', '/chat-client')
|
||||
|
||||
|
||||
def _normalize_prefix(raw_prefix: str) -> str:
|
||||
"""Normalize config prefix to internal form '/admin' or '' if not set."""
|
||||
if not raw_prefix:
|
||||
return ''
|
||||
s = str(raw_prefix).strip()
|
||||
if not s:
|
||||
return ''
|
||||
# remove leading/trailing slashes, then add single leading slash
|
||||
s = s.strip('/')
|
||||
if not s:
|
||||
return ''
|
||||
return f"/{s}"
|
||||
|
||||
|
||||
def _get_config_prefix() -> str:
|
||||
"""Return normalized prefix from config EVEAI_APP_PREFIX (config-first)."""
|
||||
try:
|
||||
cfg_val = (current_app.config.get('EVEAI_APP_PREFIX') if current_app else None)
|
||||
return _normalize_prefix(cfg_val)
|
||||
except Exception:
|
||||
return ''
|
||||
|
||||
|
||||
def _derive_visible_prefix():
|
||||
# 1) Edge-provided header (beste en meest expliciete bron)
|
||||
xfp = request.headers.get('X-Forwarded-Prefix')
|
||||
if xfp and any(xfp.startswith(p) for p in VISIBLE_PREFIXES):
|
||||
return xfp.rstrip('/')
|
||||
current_app.logger.debug(f"X-Forwarded-Prefix: {xfp}")
|
||||
if xfp and any(str(xfp).startswith(p) for p in VISIBLE_PREFIXES):
|
||||
return str(xfp).rstrip('/')
|
||||
|
||||
# 2) Referer fallback: haal het top-level segment uit de Referer path
|
||||
ref = request.headers.get('Referer') or ''
|
||||
@@ -24,13 +49,31 @@ def _derive_visible_prefix():
|
||||
return ''
|
||||
|
||||
|
||||
def _visible_prefix_for_runtime() -> str:
|
||||
"""Decide which prefix to use at runtime.
|
||||
Priority: config EVEAI_APP_PREFIX; optional dynamic fallback if enabled.
|
||||
"""
|
||||
cfg_prefix = _get_config_prefix()
|
||||
if cfg_prefix:
|
||||
current_app.logger.debug(f"prefixed_url_for: using config prefix: {cfg_prefix}")
|
||||
return cfg_prefix
|
||||
# Optional dynamic fallback
|
||||
use_fallback = bool(current_app.config.get('EVEAI_USE_DYNAMIC_PREFIX_FALLBACK', False)) if current_app else False
|
||||
if use_fallback:
|
||||
dyn = _derive_visible_prefix()
|
||||
current_app.logger.debug(f"prefixed_url_for: using dynamic fallback prefix: {dyn}")
|
||||
return dyn
|
||||
current_app.logger.debug("prefixed_url_for: no prefix configured, no fallback enabled")
|
||||
return ''
|
||||
|
||||
|
||||
def prefixed_url_for(endpoint, **values):
|
||||
"""
|
||||
Gedrag:
|
||||
- Default (_external=False, for_redirect=False): retourneer relatief pad (zonder leading '/')
|
||||
voor templates/JS. De dynamische <base> zorgt voor correcte resolutie onder het zichtbare prefix.
|
||||
- _external=True: bouw absolute URL (schema/host). Als X-Forwarded-Prefix aanwezig is,
|
||||
prefixeer de path daarmee (handig voor e-mails/deeplinks).
|
||||
- _external=True: bouw absolute URL (schema/host). Pad wordt geprefixt met config prefix (indien gezet),
|
||||
of optioneel met dynamische fallback wanneer geactiveerd.
|
||||
- for_redirect=True: geef root-absoluut pad inclusief zichtbaar top-prefix, geschikt
|
||||
voor HTTP Location headers. Backwards compat: _as_location=True wordt behandeld als for_redirect.
|
||||
"""
|
||||
@@ -46,16 +89,20 @@ def prefixed_url_for(endpoint, **values):
|
||||
if external:
|
||||
scheme = request.headers.get('X-Forwarded-Proto', request.scheme)
|
||||
host = request.headers.get('Host', request.host)
|
||||
xfp = request.headers.get('X-Forwarded-Prefix', '') or ''
|
||||
new_path = (xfp.rstrip('/') + path) if (xfp and not path.startswith(xfp)) else path
|
||||
visible_prefix = _visible_prefix_for_runtime()
|
||||
new_path = (visible_prefix.rstrip('/') + path) if (visible_prefix and not path.startswith(visible_prefix)) else path
|
||||
current_app.logger.debug(f"prefixed_url_for external: {scheme}://{host}{new_path}")
|
||||
return urlunsplit((scheme, host, new_path, query, fragment))
|
||||
|
||||
if for_redirect:
|
||||
visible_prefix = _derive_visible_prefix()
|
||||
visible_prefix = _visible_prefix_for_runtime()
|
||||
if visible_prefix and not path.startswith(visible_prefix):
|
||||
return f"{visible_prefix}{path}"
|
||||
# root-absoluut pad, zonder prefix als onbekend
|
||||
composed = f"{visible_prefix}{path}"
|
||||
current_app.logger.debug(f"prefixed_url_for redirect: {composed}")
|
||||
return composed
|
||||
current_app.logger.debug(f"prefixed_url_for redirect (no prefix): {path}")
|
||||
return path
|
||||
|
||||
# Default: relatief pad
|
||||
return path[1:] if path.startswith('/') else path
|
||||
# Default: relatief pad (zonder leading '/')
|
||||
rel = path[1:] if path.startswith('/') else path
|
||||
return rel
|
||||
@@ -36,7 +36,7 @@ def send_confirmation_email(user):
|
||||
|
||||
try:
|
||||
send_email(user.email, f"{user.first_name} {user.last_name}", "Confirm your email", html)
|
||||
current_app.logger.info(f'Confirmation email sent to {user.email}')
|
||||
current_app.logger.info(f'Confirmation email sent to {user.email} with url: {confirm_url}')
|
||||
except Exception as e:
|
||||
current_app.logger.error(f'Failed to send confirmation email to {user.email}. Error: {str(e)}')
|
||||
raise
|
||||
@@ -51,7 +51,7 @@ def send_reset_email(user):
|
||||
|
||||
try:
|
||||
send_email(user.email, f"{user.first_name} {user.last_name}", subject, html)
|
||||
current_app.logger.info(f'Reset email sent to {user.email}')
|
||||
current_app.logger.info(f'Reset email sent to {user.email} with url: {reset_url}')
|
||||
except Exception as e:
|
||||
current_app.logger.error(f'Failed to send reset email to {user.email}. Error: {str(e)}')
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user