2026-05-17 15:38:10 +00:00
|
|
|
{{template "base" .}}
|
|
|
|
|
{{define "content"}}
|
|
|
|
|
<div style="max-width:1400px">
|
|
|
|
|
|
|
|
|
|
<div style="margin-bottom:16px">
|
|
|
|
|
<div class="page-title">Allowlist</div>
|
|
|
|
|
<div class="page-sub">IPs and ranges exempt from CrowdSec decisions</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{{if .FetchErr}}
|
|
|
|
|
<div class="panel" style="margin-bottom:16px">
|
|
|
|
|
<div class="panel-body">
|
|
|
|
|
<div class="empty-text">Allowlist unavailable</div>
|
|
|
|
|
<div class="empty-sub">{{.FetchErr}}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{{else}}
|
|
|
|
|
|
2026-05-19 04:30:14 +00:00
|
|
|
<div style="display:grid;grid-template-columns:2fr 1fr;gap:16px;margin-bottom:16px">
|
|
|
|
|
|
|
|
|
|
<div class="panel">
|
|
|
|
|
<div class="panel-header"><span class="panel-title">Add IPs to Allowlist</span></div>
|
|
|
|
|
<div class="panel-body">
|
|
|
|
|
<form method="POST" action="/allowlist/add">
|
|
|
|
|
<input type="hidden" name="_csrf" value="{{.CSRFToken}}">
|
|
|
|
|
<div style="display:grid;gap:12px;margin-bottom:16px">
|
|
|
|
|
<div>
|
|
|
|
|
<label class="field-label">Allowlist Name</label>
|
|
|
|
|
<input class="field-input" type="text" name="list" placeholder="default" required
|
|
|
|
|
list="list-names">
|
|
|
|
|
{{if .Lists}}
|
|
|
|
|
<datalist id="list-names">
|
|
|
|
|
{{range .Lists}}<option value="{{.Name}}">{{end}}
|
|
|
|
|
</datalist>
|
|
|
|
|
{{end}}
|
|
|
|
|
<div style="font-size:11px;color:var(--muted);margin-top:4px">
|
|
|
|
|
If the list does not exist it will be created automatically.
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label class="field-label">Comment (optional)</label>
|
|
|
|
|
<input class="field-input" type="text" name="comment" placeholder="e.g. trusted office IP">
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<label class="field-label">IP Addresses / CIDR Ranges</label>
|
|
|
|
|
<textarea class="field-input" name="value" rows="5"
|
|
|
|
|
placeholder="One per line, or comma-separated: 1.2.3.4 192.168.0.0/24 8.8.8.8, 8.8.4.4"
|
|
|
|
|
required style="resize:vertical;font-family:'JetBrains Mono',monospace;font-size:12px"></textarea>
|
|
|
|
|
</div>
|
2026-05-17 15:38:10 +00:00
|
|
|
</div>
|
2026-05-19 04:30:14 +00:00
|
|
|
<div style="display:flex;justify-content:flex-end">
|
|
|
|
|
<button type="submit" class="btn-primary">Add to Allowlist</button>
|
2026-05-17 15:38:10 +00:00
|
|
|
</div>
|
2026-05-19 04:30:14 +00:00
|
|
|
</form>
|
|
|
|
|
</div>
|
2026-05-17 15:38:10 +00:00
|
|
|
</div>
|
2026-05-19 04:30:14 +00:00
|
|
|
|
|
|
|
|
<div class="panel">
|
|
|
|
|
<div class="panel-header"><span class="panel-title">Create New List</span></div>
|
|
|
|
|
<div class="panel-body">
|
|
|
|
|
<form method="POST" action="/allowlist/create">
|
|
|
|
|
<input type="hidden" name="_csrf" value="{{.CSRFToken}}">
|
|
|
|
|
<div style="margin-bottom:16px">
|
|
|
|
|
<label class="field-label">List Name</label>
|
|
|
|
|
<input class="field-input" type="text" name="name" placeholder="mylist" required>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="display:flex;justify-content:flex-end">
|
|
|
|
|
<button type="submit" class="btn-secondary">Create List</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-17 15:38:10 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{{if .Lists}}
|
|
|
|
|
{{range .Lists}}
|
|
|
|
|
<div class="panel" style="margin-bottom:16px">
|
|
|
|
|
<div class="panel-header">
|
|
|
|
|
<span class="panel-title">{{.Name}}</span>
|
|
|
|
|
{{if .Description}}<span style="font-size:12px;color:var(--muted)">{{.Description}}</span>{{end}}
|
2026-05-19 04:30:14 +00:00
|
|
|
<form method="POST" action="/allowlist/delete-list" style="margin-left:auto">
|
|
|
|
|
<input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
|
|
|
|
|
<input type="hidden" name="name" value="{{.Name}}">
|
|
|
|
|
<button type="submit" class="btn-danger-sm"
|
|
|
|
|
data-confirm="Delete entire allowlist '{{.Name}}'? This cannot be undone.">Delete List</button>
|
|
|
|
|
</form>
|
2026-05-17 15:38:10 +00:00
|
|
|
</div>
|
|
|
|
|
{{if .Items}}
|
|
|
|
|
<table class="data-table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>Value</th>
|
|
|
|
|
<th>Comment</th>
|
|
|
|
|
<th>Expiry</th>
|
|
|
|
|
<th>Action</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
{{$listName := .Name}}
|
|
|
|
|
{{range .Items}}
|
|
|
|
|
<tr>
|
|
|
|
|
<td style="font-family:'JetBrains Mono',monospace;font-size:12px">{{.Value}}</td>
|
|
|
|
|
<td style="font-size:12px;color:var(--muted)">{{.Comment}}</td>
|
|
|
|
|
<td style="font-size:12px;color:var(--muted)">{{if .Expiry}}{{.Expiry}}{{else}}permanent{{end}}</td>
|
|
|
|
|
<td>
|
|
|
|
|
<form method="POST" action="/allowlist/remove" style="display:inline">
|
|
|
|
|
<input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
|
|
|
|
|
<input type="hidden" name="list" value="{{$listName}}">
|
|
|
|
|
<input type="hidden" name="value" value="{{.Value}}">
|
|
|
|
|
<button type="submit" class="btn-danger-sm"
|
|
|
|
|
data-confirm="Remove {{.Value}} from allowlist?">Remove</button>
|
|
|
|
|
</form>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
{{end}}
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
{{else}}
|
|
|
|
|
<div class="empty-state">
|
|
|
|
|
<div class="empty-text">No entries in {{.Name}}</div>
|
|
|
|
|
</div>
|
|
|
|
|
{{end}}
|
|
|
|
|
</div>
|
|
|
|
|
{{end}}
|
|
|
|
|
{{else}}
|
|
|
|
|
<div class="panel">
|
|
|
|
|
<div class="empty-state">
|
|
|
|
|
<div class="empty-text">No allowlists found</div>
|
2026-05-19 04:30:14 +00:00
|
|
|
<div class="empty-sub">Use "Create New List" above, or type a list name in the Add form — it will be created automatically.</div>
|
2026-05-17 15:38:10 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{{end}}
|
|
|
|
|
|
|
|
|
|
{{end}}
|
|
|
|
|
</div>
|
|
|
|
|
{{end}}
|
|
|
|
|
|
|
|
|
|
{{define "scripts"}}{{end}}
|