50c125e0db
All-in-one installer za Apache Guacamole s Nginx reverse proxy, fail2ban, SSL (Let's Encrypt / Self-signed), GeoIP blokiranjem i Flask web GUI za upravljanje. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
160 lines
5.6 KiB
HTML
160 lines
5.6 KiB
HTML
{% extends 'base.html' %}
|
||
{% block title %}GeoIP – Guacamole Manager{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h4 class="mb-0"><i class="bi bi-globe me-2"></i>GeoIP blokiranje</h4>
|
||
{% if enabled %}
|
||
<span class="badge bg-success fs-6">Aktivno</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary fs-6">Neaktivno</span>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% if enabled %}
|
||
<!-- GeoIP je aktivan -->
|
||
<div class="row g-4">
|
||
<div class="col-md-6">
|
||
<div class="card">
|
||
<div class="card-header fw-semibold">Dozvoljene države</div>
|
||
<div class="card-body">
|
||
<div id="country-badges" class="mb-3">
|
||
{% for cc in countries.split() %}
|
||
<span class="badge-country">{{ cc }}</span>
|
||
{% endfor %}
|
||
</div>
|
||
<div class="input-group input-group-sm">
|
||
<input id="countries-input" type="text" class="form-control"
|
||
placeholder="HR BA SI RS AT" value="{{ countries }}">
|
||
<button class="btn btn-primary" onclick="updateCountries()">
|
||
<i class="bi bi-check-lg"></i> Spremi
|
||
</button>
|
||
</div>
|
||
<small class="text-muted">ISO-2 kodovi zemalja, razdvojeni razmakom</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="card">
|
||
<div class="card-header fw-semibold">Akcije</div>
|
||
<div class="card-body d-flex flex-column gap-2">
|
||
<button class="btn btn-outline-info" onclick="refreshDB()">
|
||
<i class="bi bi-cloud-download"></i> Ažuriraj GeoIP bazu
|
||
</button>
|
||
<button class="btn btn-outline-danger" onclick="disableGeoIP()">
|
||
<i class="bi bi-x-circle"></i> Onemogući GeoIP
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{% else %}
|
||
<!-- GeoIP nije aktivan -->
|
||
<div class="card">
|
||
<div class="card-header fw-semibold">
|
||
<i class="bi bi-globe me-1"></i> Konfiguracija GeoIP blokiranja
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="alert alert-info small mb-4">
|
||
<i class="bi bi-info-circle me-1"></i>
|
||
Potreban je besplatni MaxMind račun:
|
||
<a href="https://www.maxmind.com/en/geolite2/signup" target="_blank" class="alert-link">
|
||
maxmind.com/en/geolite2/signup
|
||
</a>
|
||
</div>
|
||
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label small text-muted">MaxMind Account ID</label>
|
||
<input id="mm-id" type="text" class="form-control" value="{{ mm_id }}"
|
||
placeholder="123456">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label small text-muted">MaxMind License Key</label>
|
||
<input id="mm-key" type="password" class="form-control"
|
||
placeholder="••••••••••••••••">
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label small text-muted">Dozvoljene države (ISO-2 kodovi)</label>
|
||
<input id="countries-input" type="text" class="form-control"
|
||
placeholder="HR BA SI RS AT DE">
|
||
<small class="text-muted">Sve ostale države bit će blokirane</small>
|
||
</div>
|
||
<div class="col-12">
|
||
<button class="btn btn-success" onclick="enableGeoIP()">
|
||
<i class="bi bi-globe-americas"></i> Aktiviraj GeoIP blokiranje
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Referenca ISO kodova -->
|
||
<div class="card mt-3">
|
||
<div class="card-header small text-muted">Česti ISO-2 kodovi</div>
|
||
<div class="card-body">
|
||
{% for cc, name in [('HR','Hrvatska'),('BA','Bosna i Hercegovina'),('SI','Slovenija'),
|
||
('RS','Srbija'),('ME','Crna Gora'),('MK','Sjeverna Makedonija'),
|
||
('AT','Austrija'),('DE','Njemačka'),('CH','Švicarska')] %}
|
||
<span class="badge-country" style="cursor:pointer"
|
||
onclick="addCountry('{{ cc }}')" title="{{ name }}">
|
||
{{ cc }} <small class="text-muted">{{ name }}</small>
|
||
</span>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script>
|
||
async function enableGeoIP() {
|
||
const btn = event.target;
|
||
btn.disabled = true;
|
||
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Aktivacija...';
|
||
const r = await api('/api/geoip/enable', {
|
||
mm_id: document.getElementById('mm-id').value.trim(),
|
||
mm_key: document.getElementById('mm-key').value.trim(),
|
||
countries: document.getElementById('countries-input').value.trim()
|
||
});
|
||
showToast(r.msg, r.ok);
|
||
if (r.ok) setTimeout(() => location.reload(), 1500);
|
||
else { btn.disabled = false; btn.innerHTML = '<i class="bi bi-globe-americas"></i> Aktiviraj GeoIP blokiranje'; }
|
||
}
|
||
|
||
async function updateCountries() {
|
||
const r = await api('/api/geoip/update', {
|
||
countries: document.getElementById('countries-input').value.trim()
|
||
});
|
||
showToast(r.msg, r.ok);
|
||
if (r.ok) setTimeout(() => location.reload(), 1000);
|
||
}
|
||
|
||
async function disableGeoIP() {
|
||
if (!confirm('Sigurno onemogućiti GeoIP?')) return;
|
||
const r = await api('/api/geoip/disable');
|
||
showToast(r.msg, r.ok);
|
||
if (r.ok) setTimeout(() => location.reload(), 1000);
|
||
}
|
||
|
||
async function refreshDB() {
|
||
const btn = event.target;
|
||
btn.disabled = true;
|
||
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Ažuriranje...';
|
||
const r = await api('/api/geoip/refresh');
|
||
showToast(r.ok ? 'GeoIP baza ažurirana' : r.msg, r.ok);
|
||
btn.disabled = false;
|
||
btn.innerHTML = '<i class="bi bi-cloud-download"></i> Ažuriraj GeoIP bazu';
|
||
}
|
||
|
||
function addCountry(cc) {
|
||
const inp = document.getElementById('countries-input');
|
||
const existing = inp.value.split(' ').filter(x => x);
|
||
if (!existing.includes(cc)) {
|
||
inp.value = [...existing, cc].join(' ');
|
||
}
|
||
}
|
||
</script>
|
||
{% endblock %}
|