Add password generator, duplicate AP rejection, and input sanitization

- Add Gen button to admin panel that generates 13-char alphanumeric
  passwords for Nextcloud credentials (Add Site form and Edit modal)
- Reject duplicate AP numbers within the same site (409 response)
- Fix newline injection vulnerability in admin API that allowed
  creating backdoor site entries via sites.conf corruption
- Fix colon-in-PIN bug by rejecting colons in PIN and NC User fields
- Use maxsplit=3 in sites.conf parser so NC Pass can contain colons
- Add nc_change_password() to sync password edits to Nextcloud
- Clean up corrupted sites.conf entries from prior injection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kamaji
2026-01-26 08:47:30 -06:00
parent 30fc55567c
commit a719e528ed
3 changed files with 132 additions and 94 deletions

View File

@@ -177,6 +177,12 @@
cursor: not-allowed;
}
.btn-gen {
padding: 8px 10px;
font-size: 0.8rem;
white-space: nowrap;
}
.card-actions {
margin-top: 10px;
border-top: 1px solid #2a2a4a;
@@ -298,6 +304,7 @@
<div class="form-row">
<input type="text" id="add-nc-user" placeholder="NC User (optional)">
<input type="text" id="add-nc-pass" placeholder="NC Pass (optional)">
<button type="button" class="btn btn-outline btn-gen" onclick="document.getElementById('add-nc-pass').value = generatePassword()">Gen</button>
</div>
<button class="btn btn-blue" onclick="addSite()">Add Site</button>
</div>
@@ -350,7 +357,10 @@
<label for="edit-nc-user">NC User</label>
<input type="text" id="edit-nc-user">
<label for="edit-nc-pass">NC Pass</label>
<input type="text" id="edit-nc-pass">
<div style="display:flex;gap:8px;">
<input type="text" id="edit-nc-pass" style="flex:1;">
<button type="button" class="btn btn-outline btn-gen" onclick="document.getElementById('edit-nc-pass').value = generatePassword()">Gen</button>
</div>
<div class="modal-actions">
<button class="btn btn-outline" onclick="closeEdit()">Cancel</button>
<button class="btn btn-blue" onclick="saveEdit()">Save</button>
@@ -359,6 +369,13 @@
</div>
<script>
function generatePassword() {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const arr = new Uint8Array(13);
crypto.getRandomValues(arr);
return Array.from(arr, b => chars[b % chars.length]).join('');
}
const banner = document.getElementById('status-banner');
function showBanner(msg, type) {