Files
ldap-auth-service/public/auth.html
2026-08-20 11:50:00 +05:00

208 lines
8.9 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>LDAP Authentication</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 15px 35px rgba(0,0,0,0.1);
max-width: 700px;
width: 100%;
}
h2 { color: #333; margin-bottom: 8px; text-align: center; }
.subtitle { text-align: center; color: #666; margin-bottom: 25px; font-size: 14px; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 8px; color: #555; font-weight: 500; }
input[type="text"], input[type="password"] {
width: 100%;
padding: 12px 15px;
border: 2px solid #ddd;
border-radius: 6px;
font-size: 16px;
transition: border-color 0.3s;
}
input:focus { border-color: #667eea; outline: none; }
button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px 30px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
width: 100%;
transition: transform 0.2s;
margin-top: 10px;
}
button:hover { transform: translateY(-2px); }
.result {
margin-top: 25px;
padding: 20px;
border-radius: 6px;
display: none;
}
.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
.user-info { background: #f8f9fa; padding: 15px; border-radius: 6px; margin-top: 15px; }
.user-info p { margin: 8px 0; color: #333; }
.loading { display: none; text-align: center; color: #667eea; margin: 10px 0; font-size: 16px; }
.mode-selector { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin: 15px 0; }
.mode-option {
display: flex; align-items: center; gap: 8px;
padding: 10px; background: #f8f9fa; border-radius: 6px; cursor: pointer;
transition: background-color 0.2s;
}
.mode-option:hover { background: #e9ecef; }
.mode-option.active { background: #667eea; color: white; }
.mode-option input[type="radio"] { margin: 0; }
.json-preview {
background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 6px; margin-top: 10px;
font-family: 'Courier New', monospace; font-size: 12px; overflow-x: auto;
white-space: pre-wrap; max-height: 300px; overflow-y: auto;
}
.admin-link { text-align: center; margin-top: 20px; }
.admin-link a { color: #667eea; text-decoration: none; font-size: 14px; }
.admin-link a:hover { text-decoration: underline; }
</style>
</head>
<body>
<div class="container">
<h2>LDAP Authentication</h2>
<p class="subtitle">Check user credentials against Active Directory</p>
<form id="authForm">
<div class="form-group">
<label>Username:</label>
<input type="text" id="username" name="username" placeholder="user" required>
</div>
<div class="form-group">
<label>Password:</label>
<input type="password" id="password" name="password" placeholder="••••••••" required>
</div>
<div class="mode-selector">
<label class="mode-option active" id="modeBasic">
<input type="radio" name="mode" value="basic" checked>
<span>Basic Info</span>
</label>
<label class="mode-option" id="modeDescription">
<input type="radio" name="mode" value="description">
<span>Description Only</span>
</label>
<label class="mode-option" id="modeGroups">
<input type="radio" name="mode" value="groups">
<span>Groups Only</span>
</label>
</div>
<div class="mode-selector">
<label class="mode-option" id="modeAll">
<input type="radio" name="mode" value="all">
<span>All Information</span>
</label>
</div>
<button type="submit">Authenticate</button>
</form>
<div class="loading" id="loading">Authenticating with Active Directory...</div>
<div class="result" id="result"></div>
<div class="admin-link">
<a href="/admin">Administrator panel</a>
</div>
</div>
<script>
let currentMode = 'basic';
document.querySelectorAll('.mode-option').forEach(option => {
option.addEventListener('click', function () {
document.querySelectorAll('.mode-option').forEach(opt => opt.classList.remove('active'));
this.classList.add('active');
const radio = this.querySelector('input[type="radio"]');
radio.checked = true;
currentMode = radio.value;
});
});
function escapeHtml(str) {
return String(str).replace(/[&<>"']/g, c => ({
'&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;'
}[c]));
}
document.getElementById('authForm').addEventListener('submit', async function (e) {
e.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const resultDiv = document.getElementById('result');
const loadingDiv = document.getElementById('loading');
loadingDiv.style.display = 'block';
resultDiv.style.display = 'none';
try {
let url = '/api/auth';
if (currentMode === 'description') url += '?description=1';
else if (currentMode === 'groups') url += '?groups=1';
else if (currentMode === 'all') url += '?all=1';
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify({ username, password })
});
const result = await response.json();
if (result.success) {
resultDiv.className = 'result success';
let html = '<h3>Authentication Successful</h3><div class="user-info">';
if (result.username) html += `<p><strong>Username:</strong> ${escapeHtml(result.username)}</p>`;
if (result.full_name) html += `<p><strong>Full Name:</strong> ${escapeHtml(result.full_name)}</p>`;
if (result.email) html += `<p><strong>Email:</strong> ${escapeHtml(result.email)}</p>`;
if (result.description !== undefined) html += `<p><strong>Description:</strong> ${escapeHtml(result.description || 'Not set')}</p>`;
if (result.groups) {
html += `<p><strong>Groups (${result.groups.length}):</strong> ${
result.groups.length > 0 ? result.groups.map(escapeHtml).join(', ') : 'No groups'
}</p>`;
}
html += '</div>';
if (result.all_info) {
html += '<h4 style="margin-top:15px;">All LDAP Attributes:</h4>';
}
html += `<div class="json-preview">${escapeHtml(JSON.stringify(result, null, 2))}</div>`;
resultDiv.innerHTML = html;
} else {
resultDiv.className = 'result error';
resultDiv.innerHTML = `<h3>Authentication Failed</h3><p><strong>Error:</strong> ${escapeHtml(result.error || 'Unknown error')}</p>`;
}
} catch (error) {
resultDiv.className = 'result error';
resultDiv.innerHTML = `<h3>Network Error</h3><p><strong>Error:</strong> ${escapeHtml(error.message)}</p>`;
} finally {
loadingDiv.style.display = 'none';
resultDiv.style.display = 'block';
}
});
</script>
</body>
</html>