mirror of
https://github.com/openwrt/luci.git
synced 2026-04-15 10:51:51 +00:00
This commit introduces a generic authentication plugin mechanism
to the LuCI dispatcher, enabling multi-factor authentication
(MFA/2FA) and other custom verification methods without
modifying core files.
This implementation integrates with the new plugin UI architecture
introduced in commit 617f364 (luci-mod-system: implement plugin UI
architecture), allowing authentication plugins to be managed
through the unified System > Plugins interface.
Signed-off-by: Han Yiming <moebest@outlook.jp>
111 lines
3.3 KiB
Plaintext
111 lines
3.3 KiB
Plaintext
{#
|
|
Copyright 2008 Steven Barth <steven@midlink.org>
|
|
Copyright 2008-2012 Jo-Philipp Wich <jow@openwrt.org>
|
|
Licensed to the public under the Apache License 2.0.
|
|
-#}
|
|
|
|
{% include('header') %}
|
|
|
|
<form method="post">
|
|
{% if (fuser): %}
|
|
<div class="alert-message warning">
|
|
<p>{{ _('Invalid username and/or password! Please try again.') }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if (auth_message && !fuser): %}
|
|
<div class="alert-message">
|
|
<p>{{ auth_message }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="cbi-map">
|
|
<h2 name="content">{{ _('Authorization Required') }}</h2>
|
|
<div class="cbi-map-descr">
|
|
{{ _('Please enter your username and password.') }}
|
|
</div>
|
|
<div class="cbi-section"><div class="cbi-section-node">
|
|
<div class="cbi-value">
|
|
<label class="cbi-value-title">{{ _('Username') }}</label>
|
|
<div class="cbi-value-field">
|
|
<input class="cbi-input-text" type="text" name="luci_username" value="{{ entityencode(duser, true) }}" />
|
|
</div>
|
|
</div>
|
|
<div class="cbi-value cbi-value-last">
|
|
<label class="cbi-value-title">{{ _('Password') }}</label>
|
|
<div class="cbi-value-field">
|
|
<input class="cbi-input-text" type="password" name="luci_password" />
|
|
</div>
|
|
</div>
|
|
{% if (auth_fields): %}
|
|
{% for (let field in auth_fields): %}
|
|
<div class="cbi-value">
|
|
<label class="cbi-value-title">{{ _(field.label ?? field.name) }}</label>
|
|
<div class="cbi-value-field">
|
|
<input class="cbi-input-text"
|
|
type="{{ field.type ?? 'text' }}"
|
|
name="{{ field.name }}"
|
|
{% if (field.placeholder): %}placeholder="{{ field.placeholder }}"{% endif %}
|
|
{% if (field.inputmode): %}inputmode="{{ field.inputmode }}"{% endif %}
|
|
{% if (field.pattern): %}pattern="{{ field.pattern }}"{% endif %}
|
|
{% if (field.maxlength): %}maxlength="{{ field.maxlength }}"{% endif %}
|
|
{% if (field.autocomplete): %}autocomplete="{{ field.autocomplete }}"{% endif %}
|
|
{% if (field.required): %}required{% endif %}
|
|
/>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% if (auth_html): %}
|
|
<div class="cbi-value">
|
|
{{ auth_html }}
|
|
</div>
|
|
{% endif %}
|
|
{% if (auth_assets): %}
|
|
{% for (let asset in auth_assets): %}
|
|
{% if (asset.type == 'script'): %}
|
|
<script src="{{ asset.src }}"></script>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div></div>
|
|
</div>
|
|
|
|
<div class="cbi-page-actions">
|
|
<input type="submit" value="{{ _('Log in') }}" class="btn cbi-button cbi-button-apply" />
|
|
</div>
|
|
</form>
|
|
|
|
{%
|
|
let https_ports = uci.get('uhttpd', 'main', 'listen_https') ?? [];
|
|
|
|
https_ports = uniq(filter(
|
|
map(
|
|
(type(https_ports) == 'string') ? split(https_port, /\s+/) : https_ports,
|
|
e => +match(e, /\d+$/)?.[0]
|
|
),
|
|
p => (p >= 0 && p <= 65535)
|
|
));
|
|
%}
|
|
|
|
<script>
|
|
var input = document.getElementsByName('luci_password')[0];
|
|
|
|
if (input)
|
|
input.focus();
|
|
|
|
if (document.location.protocol != 'https:') {
|
|
{{ https_ports }}.forEach(function(port) {
|
|
var url = 'https://' + window.location.hostname + ':' + port + window.location.pathname;
|
|
var img = new Image();
|
|
|
|
img.onload = function() { window.location = url };
|
|
img.src = 'https://' + window.location.hostname + ':' + port + '{{ resource }}/icons/loading.svg?' + Math.random();
|
|
|
|
setTimeout(function() { img.src = '' }, 5000);
|
|
});
|
|
}
|
|
</script>
|
|
|
|
{% include('footer') %}
|