portal: request email scope and fix access rate limiting

This commit is contained in:
Brad Stein 2026-01-02 03:09:07 -03:00
parent 7dac934a81
commit 8b5a8bda3d
3 changed files with 18 additions and 6 deletions

View File

@ -28,6 +28,16 @@ def _random_request_code(username: str) -> str:
return f"{username}~{suffix}"
def _client_ip() -> str:
xff = (request.headers.get("X-Forwarded-For") or "").strip()
if xff:
return xff.split(",", 1)[0].strip() or "unknown"
x_real_ip = (request.headers.get("X-Real-IP") or "").strip()
if x_real_ip:
return x_real_ip
return request.remote_addr or "unknown"
def register(app) -> None:
@app.route("/api/access/request", methods=["POST"])
def request_access() -> Any:
@ -36,7 +46,7 @@ def register(app) -> None:
if not configured():
return jsonify({"error": "server not configured"}), 503
ip = request.remote_addr or "unknown"
ip = _client_ip()
if not rate_limit_allow(
ip,
key="access_request_submit",
@ -112,7 +122,7 @@ def register(app) -> None:
if not configured():
return jsonify({"error": "server not configured"}), 503
ip = request.remote_addr or "unknown"
ip = _client_ip()
if not rate_limit_allow(
ip,
key="access_request_status",

View File

@ -33,9 +33,11 @@ def register(app) -> None:
keycloak_email = str(full.get("email") or "")
attrs = full.get("attributes") or {}
if isinstance(attrs, dict):
values = attrs.get("mailu_app_password") or []
if isinstance(values, list) and values:
mailu_app_password = str(values[0])
raw_pw = attrs.get("mailu_app_password")
if isinstance(raw_pw, list) and raw_pw:
mailu_app_password = str(raw_pw[0])
elif isinstance(raw_pw, str):
mailu_app_password = raw_pw
except Exception:
pass

View File

@ -58,6 +58,7 @@ export async function initAuth() {
pkceMethod: "S256",
silentCheckSsoRedirectUri: `${window.location.origin}/silent-check-sso.html`,
checkLoginIframe: true,
scope: "openid profile email",
});
auth.authenticated = authenticated;
@ -103,4 +104,3 @@ export async function authFetch(url, options = {}) {
if (auth.token) headers.set("Authorization", `Bearer ${auth.token}`);
return fetch(url, { ...options, headers });
}