Spaces:
Running
Running
<html> | |
<head> | |
<title>LibreChat Admin</title> | |
<style> | |
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; } | |
.container { max-width: 1000px; margin: 0 auto; } | |
table { width: 100%; border-collapse: collapse; margin-top: 20px; } | |
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; } | |
button { padding: 6px 12px; cursor: pointer; } | |
.login-form { max-width: 400px; margin: 50px auto; } | |
</style> | |
</head> | |
<body> | |
<div id="login" class="login-form" style="display: block;"> | |
<h2>Admin Login</h2> | |
<input type="password" id="password" placeholder="Admin Password"> | |
<button onclick="login()">Login</button> | |
</div> | |
<div id="admin-panel" class="container" style="display: none;"> | |
<h1>User Management</h1> | |
<div> | |
<input type="text" id="new-username" placeholder="Username"> | |
<input type="password" id="new-password" placeholder="Password"> | |
<button onclick="addUser()">Add User</button> | |
</div> | |
<table id="users-table"> | |
<thead> | |
<tr> | |
<th>Username</th> | |
<th>Actions</th> | |
</tr> | |
</thead> | |
<tbody></tbody> | |
</table> | |
</div> | |
<script> | |
let authToken = ''; | |
async function login() { | |
const password = document.getElementById('password').value; | |
const response = await fetch('/sudo/login', { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify({ password }) | |
}); | |
if (response.ok) { | |
const data = await response.json(); | |
authToken = data.token; | |
document.getElementById('login').style.display = 'none'; | |
document.getElementById('admin-panel').style.display = 'block'; | |
loadUsers(); | |
} else { | |
alert('Login failed!'); | |
} | |
} | |
async function loadUsers() { | |
const response = await fetch('/sudo/users', { | |
headers: { 'X-Auth-Token': authToken } | |
}); | |
const users = await response.json(); | |
const tbody = document.querySelector('#users-table tbody'); | |
tbody.innerHTML = users.map(user => ` | |
<tr> | |
<td>${user.username}</td> | |
<td> | |
<button onclick="deleteUser('${user.username}')">Delete</button> | |
</td> | |
</tr> | |
`).join(''); | |
} | |
async function addUser() { | |
const username = document.getElementById('new-username').value; | |
const password = document.getElementById('new-password').value; | |
const response = await fetch('/sudo/users', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'X-Auth-Token': authToken | |
}, | |
body: JSON.stringify({ username, password }) | |
}); | |
if (response.ok) { | |
loadUsers(); | |
document.getElementById('new-username').value = ''; | |
document.getElementById('new-password').value = ''; | |
} | |
} | |
async function deleteUser(username) { | |
if (confirm(`Delete ${username}?`)) { | |
await fetch(`/sudo/users/${username}`, { | |
method: 'DELETE', | |
headers: { 'X-Auth-Token': authToken } | |
}); | |
loadUsers(); | |
} | |
} | |
</script> | |
</body> | |
</html> |