148 lines
5.5 KiB
PHP
148 lines
5.5 KiB
PHP
<!-- meta tags and other links -->
|
|
<!DOCTYPE html>
|
|
<html lang="en" data-theme="light">
|
|
|
|
<x-head/>
|
|
|
|
<link rel="stylesheet" href="{{ asset('assets/css/login/login.css') }}">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
|
|
|
|
|
|
<body>
|
|
<div class="container">
|
|
<div class="login-card">
|
|
<div class="login-image">
|
|
<img src="{{ asset('assets/images/auth/monas.svg')}}" alt="Monumen Nasional" style="max-width: 100%; max-height: 500px;">
|
|
</div>
|
|
|
|
<!-- Right Section with Login Form -->
|
|
<div class="login-form">
|
|
<img src="{{ asset('assets/images/auth/logo-login.svg') }}" alt="Balai Sertifikasi Elektronik" class="logo">
|
|
|
|
<h1 class="text-login">Login</h1>
|
|
<p class="subtext">Silakan masuk menggunakan email/username</p>
|
|
<form id="login-form" action="#" method="POST" style="width: 100%;">
|
|
@csrf
|
|
<div class="form-group">
|
|
<input type="text" id="identifier" name="identifier" placeholder="Email atau Username" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="password-container">
|
|
<input type="password" id="password" name="password" placeholder="Kata Sandi" required>
|
|
<span class="password-toggle">
|
|
<i class="bi bi-eye"></i>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<small id="login-error" class="text-danger" style="display:none;"></small>
|
|
</div>
|
|
|
|
|
|
<button id="btn-login" type="submit" class="login-button">Login</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
<x-script />
|
|
<script>
|
|
// Clear any leftover tokens on signin page
|
|
try {
|
|
localStorage.removeItem('auth_token');
|
|
localStorage.removeItem('auth_user');
|
|
} catch (e) {}
|
|
|
|
document.querySelector('.password-toggle').addEventListener('click', function() {
|
|
const passwordInput = document.getElementById('password');
|
|
const icon = this.querySelector('i');
|
|
if (passwordInput.type === 'password') {
|
|
passwordInput.type = 'text';
|
|
icon.className = 'bi bi-eye-slash';
|
|
} else {
|
|
passwordInput.type = 'password';
|
|
icon.className = 'bi bi-eye';
|
|
}
|
|
});
|
|
|
|
const form = document.getElementById('login-form');
|
|
const btn = document.getElementById('btn-login');
|
|
const errorBox = document.getElementById('login-error');
|
|
|
|
form.addEventListener('submit', async function (e) {
|
|
e.preventDefault();
|
|
errorBox.style.display = 'none';
|
|
errorBox.textContent = '';
|
|
|
|
const identifier = document.getElementById('identifier').value.trim();
|
|
const password = document.getElementById('password').value;
|
|
if (!identifier || !password) return;
|
|
|
|
// Validasi kompleksitas password (min 8, upper, lower, digit, special)
|
|
const strongPwd = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$/;
|
|
if (!strongPwd.test(password)) {
|
|
errorBox.textContent = 'Password minimal 8 karakter dan harus mengandung huruf besar, huruf kecil, angka, dan simbol khusus.';
|
|
errorBox.style.display = 'inline';
|
|
return;
|
|
}
|
|
|
|
const originalText = btn.textContent;
|
|
btn.disabled = true;
|
|
btn.textContent = 'Memproses...';
|
|
|
|
try {
|
|
const resp = await fetch('{{ url('/api/auth/login') }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
identifier: identifier,
|
|
password: password,
|
|
device_name: 'web-portal'
|
|
})
|
|
});
|
|
|
|
const data = await resp.json().catch(() => ({}));
|
|
|
|
if (!resp.ok || !data.success) {
|
|
throw new Error((data && (data.message || (data.errors && (data.errors.identifier?.[0] || data.errors.password?.[0])))) || 'Login gagal');
|
|
}
|
|
|
|
// Simpan token (Catatan: localStorage memiliki risiko XSS; gunakan hati-hati)
|
|
localStorage.setItem('auth_token', data.token);
|
|
localStorage.setItem('auth_user', JSON.stringify(data.user || {}));
|
|
|
|
// Start web session agar middleware permission berfungsi
|
|
const sessionResp = await fetch('{{ route('login.session') }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'X-CSRF-TOKEN': document.querySelector('input[name=_token]').value,
|
|
},
|
|
body: JSON.stringify({ identifier, password })
|
|
});
|
|
|
|
if (!sessionResp.ok) {
|
|
throw new Error('Gagal membuat sesi login web');
|
|
}
|
|
|
|
// Redirect ke dashboard
|
|
window.location.href = '{{ route('dashboard.index') }}';
|
|
} catch (err) {
|
|
errorBox.textContent = err.message || 'Login gagal';
|
|
errorBox.style.display = 'inline';
|
|
} finally {
|
|
btn.disabled = false;
|
|
btn.textContent = originalText;
|
|
}
|
|
});
|
|
</script>
|
|
|
|
</html>
|