View a vault file. For safety, we allow inline rendering only for non-active content types (images/video/audio/pdf/text). HTML/SVG/XML are forced to download to prevent stored XSS on the app origin.
()
| 11960 | _mark_fail(ip, u) |
| 11961 | flash("Invalid credentials.") |
| 11962 | return redirect(url_for("two_factor")) |
| 11963 | |
| 11964 | # Session capacity (per link/session scope): max 66 users + 1 admin. |
| 11965 | try: |
| 11966 | sc = current_scope() |
| 11967 | is_admin = user_is_admin(u) |
| 11968 | if not scope_capacity_ok(u, is_admin, sc): |
| 11969 | flash("This session is full (max 66 users + 1 admin). Try again later.") |
| 11970 | session.pop("pre_2fa", None) |
| 11971 | session.pop("two_factor_idxs", None) |
| 11972 | return redirect(url_for("login")) |
| 11973 | except Exception: |
| 11974 | pass |
| 11975 | |
| 11976 | # Success: finalize login |
| 11977 | session.pop("pre_2fa", None) |
| 11978 | session.pop("two_factor_idxs", None) |
| 11979 | _clear_fail(ip, u) |
| 11980 | flash("Logged in.") |
| 11981 | return _complete_login_session(u, user_is_admin(u)) |
| 11982 | |
| 11983 | |
| 11984 | |
| 11985 | @app.route("/settings/appearance", methods=["GET"]) |
| 11986 | @login_required |
| 11987 | def settings_appearance_page(): |
| 11988 | u = current_user() |
| 11989 | prefs = dict(DEFAULT_PREFS) |
| 11990 | try: |
| 11991 | if u: |
| 11992 | prefs = get_user_prefs(u) or prefs |
| 11993 | except Exception: |
| 11994 | pass |
| 11995 | return render_template( |
| 11996 | "settings_appearance.html", |
| 11997 | title="Settings", |
| 11998 | prefs=prefs, |
| 11999 | accent_choices=ACCENT_CHOICES, |
| 12000 | font_choices=FONT_CHOICES, |
| 12001 | ui_theme_choices=UI_THEME_CHOICES, |
| 12002 | ) |
| 12003 | |
| 12004 | @app.route("/settings/appearance", methods=["POST"]) |
nothing calls this directly
no test coverage detected