Files
OTSSignsTheme/ots-signs/views/login.twig
Matt Batchelder 8edcdedcd5 Add custom error and not found pages, and implement SAML authentication configuration
- Created a new error page (error.twig) with a user-friendly design for displaying error messages.
- Created a new not found page (not-found.twig) to handle 404 errors with appropriate messaging and actions.
- Added a SAML authentication configuration file (settings-custom.php) to support group-based admin assignment and user provisioning.
2026-04-08 12:33:52 -04:00

126 lines
6.4 KiB
Twig

<!DOCTYPE html>
<html lang="en">
<head>
<script nonce="{{ cspNonce }}">
(function() {
if (window.location.search.indexOf('/layout/designer/') !== -1) return;
var path = window.location.pathname;
var cmsIdx = path.toLowerCase().indexOf('/cms');
var portalUrl = window.location.origin + (cmsIdx > 0 ? path.substring(0, cmsIdx) : '') + '/';
window.location.replace(portalUrl);
})();
</script>
<title>{{ theme.getThemeConfig("theme_title") }}</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="token" content="{{ csrfToken }}"/>
<meta name="public-path" content="{{ theme.rootUri() }}"/>
<link rel="shortcut icon" href="{{ theme.uri("img/favicon.ico") }}" />
<!-- Import CSS bundle from dist -->
<script src="{{ theme.rootUri() }}dist/style.bundle.min.js?v={{ version }}&rev={{revision}}" nonce="{{ cspNonce }}"></script>
<!-- Minimal inline adjustments (layout only) -->
<style type="text/css">
html { font-size: 14px; }
body { padding-top: 40px !important; padding-bottom: 40px !important; font-size: 1rem; }
</style>
<!-- Import user made CSS from theme -->
<link href="{{ theme.uri("css/override.css") }}?{{ version }}" rel="stylesheet" media="screen">
<link href="{{ theme.uri("css/override-dark.css") }}?{{ version }}" rel="stylesheet" media="screen">
</head>
<body class="login-page">
<div class="container">
{% if authCASEnabled %}
<form id="cas-login-form" class="login-card text-center" action="{{ url_for("cas.login") }}" method="post">
{% for priorRoute in flash('priorRoute') %}
<input name="priorRoute" type="hidden" value="{{ priorRoute }}" />
{% endfor %}
<p class="login-brand"><img alt="Logo" class="login-logo" src="{{ theme.uri("img/xibologo.png") }}"><span class="login-brand-text">OTS Signs</span></p>
<p>{% trans %}Connect with the Central Authentication Server{% endtrans %}</p>
<div aria-live="polite">
{% for loginMessage in flash('cas_login_message') %}
<div class="alert alert-danger" role="alert">{{ loginMessage }}</div>
{% endfor %}
</div>
<p><button class="btn btn-signin" type="submit" name="logincas">{% trans %} CAS Login{% endtrans %}</button></p>
</form>
{% else %}
<form id="login-form" class="login-card text-center" action="{{ url_for("login") }}" method="post">
{% for priorRoute in flash('priorRoute') %}
<input name="priorRoute" type="hidden" value="{{ priorRoute }}" />
{% endfor %}
<input type="hidden" name="{{ csrfKey }}" value="{{ csrfToken }}" />
<p class="login-brand"><a href="{{ theme.getThemeConfig("theme_url") }}"><img class="login-logo" src="{{ theme.uri("img/xibologo.png") }}"></a><span class="login-brand-text">OTS Signs</span></p>
<p class="lead">{% trans "Please provide your credentials" %}</p>
<label for="username" class="sr-only">{% trans "User" %}</label>
<input id="username" class="form-control input-block-level" name="username" type="text" placeholder="{% trans "User" %}" autofocus autocomplete="username">
<label for="password" class="sr-only">{% trans "Password" %}</label>
<input id="password" class="form-control input-block-level" name="password" type="password" placeholder="{% trans "Password" %}" autocomplete="current-password">
<div aria-live="polite">
{% for loginMessage in flash('login_message') %}
<div class="alert alert-danger" role="alert">{{ loginMessage }}</div>
{% endfor %}
</div>
<p><button class="btn btn-signin" type="submit">{% trans "Login" %}</button></p>
{% if passwordReminderEnabled %}<p><a href="#" id="reminder-form-toggle" role="button">{% trans "Forgotten your password?" %}</a></p>{% endif %}
</form>
{% endif %}
{% if passwordReminderEnabled %}
<form id="reminder-form" class="login-card text-center d-none" action="{{ url_for("login.forgotten") }}" method="post">
<input type="hidden" name="{{ csrfKey }}" value="{{ csrfToken }}" />
<p class="login-brand"><a href="{{ theme.getThemeConfig("theme_url") }}"><img class="login-logo" src="{{ theme.uri("img/xibologo.png") }}"></a><span class="login-brand-text">OTS Signs</span></p>
<p>{% trans "Please provide your user name" %}</p>
<label for="reminder-username" class="sr-only">{% trans "User" %}</label>
<input id="reminder-username" class="form-control input-block-level" name="username" type="text" placeholder="{% trans "User" %}">
<div aria-live="polite">
{% for loginMessage in flash('login_message') %}
<div class="alert alert-danger" role="alert">{{ loginMessage }}</div>
{% endfor %}
</div>
<p><button class="btn btn-signin" type="submit">{% trans "Send Reset" %}</button></p>
<p><a href="#" id="login-form-toggle" role="button">{% trans "Login instead?" %}</a></p>
</form>
{% endif %}
</div> <!-- /container -->
<!-- Import JS bundle from dist -->
<script src="{{ theme.rootUri() }}dist/vendor.bundle.min.js?v={{ version }}&rev={{revision}}" nonce="{{ cspNonce }}"></script>
<script type="text/javascript" nonce="{{ cspNonce }}">
$(function() {
$("#reminder-form-toggle").on("click keydown", function (e) {
if (e.type === "keydown" && e.key !== "Enter" && e.key !== " ") return;
e.preventDefault();
$("#login-form").addClass("d-none");
$("#reminder-form").removeClass("d-none");
$("#reminder-form").find("input:first").focus();
});
$("#login-form-toggle").on("click keydown", function (e) {
if (e.type === "keydown" && e.key !== "Enter" && e.key !== " ") return;
e.preventDefault();
$("#login-form").removeClass("d-none");
$("#reminder-form").addClass("d-none");
$("#login-form").find("input:first").focus();
});
});
</script>
</body>
</html>