Fix admin organization proof image preview path and implement forgot password feature with rate limiting and check email warning
This commit is contained in:
+63
-24
@@ -530,11 +530,27 @@ function openAuthModal(mode){
|
||||
'<div style="font-size:12px;color:#64748b;margin-top:8px">Akun akan berstatus menunggu persetujuan admin setelah pendaftaran berhasil.</div>';
|
||||
if(switchArea){ switchArea.innerHTML = '<span>Sudah punya akun? <button type="button" id="auth-switch-to-login" class="data-link" style="background:transparent;border:0;padding:0;cursor:pointer;margin-left:4px">Masuk</button></span>'; }
|
||||
if(submitBtn) submitBtn.textContent = 'Daftar';
|
||||
} else {
|
||||
} else if(mode === 'login'){
|
||||
title.textContent = 'Masuk';
|
||||
fields.innerHTML = '<div class="auth-field"><label>Email<input name="email" type="email" required></label></div><div class="auth-field"><label>Password<input name="password" type="password" required></label></div>';
|
||||
fields.innerHTML = '<div class="auth-field"><label><span class="label-title">Email</span><input name="email" type="email" required></label></div>' +
|
||||
'<div class="auth-field"><label><span class="label-title">Password</span><input name="password" type="password" required></label></div>' +
|
||||
'<div style="text-align:right;margin-top:-6px;margin-bottom:12px">' +
|
||||
'<button type="button" id="auth-forgot-password-link" style="background:transparent;border:0;padding:0;color:#3b82f6;cursor:pointer;font-size:13px">Lupa Password?</button>' +
|
||||
'</div>';
|
||||
if(switchArea){ switchArea.innerHTML = '<span>Ingin daftar pengelola? <button type="button" id="auth-switch-to-register" class="data-link" style="background:transparent;border:0;padding:0;cursor:pointer;margin-left:4px">Daftar di sini</button></span>'; }
|
||||
if(submitBtn) submitBtn.textContent = 'Masuk';
|
||||
} else if(mode === 'forgot_password'){
|
||||
title.textContent = 'Lupa Password';
|
||||
fields.innerHTML =
|
||||
'<div class="auth-field"><label><span class="label-title">Email <span class="required-star">*</span></span><input name="email" type="email" required></label></div>'+
|
||||
'<div style="display:flex;gap:8px;margin-top:12px;margin-bottom:12px">' +
|
||||
'<button type="button" id="auth-send-forgot-code-btn" class="btn" style="flex:1;padding:10px;background:#3b82f6;color:white;border:none;border-radius:4px;cursor:pointer;font-size:14px">Kirim Kode Verifikasi</button>' +
|
||||
'</div>' +
|
||||
'<div class="auth-field"><label><span class="label-title">Kode Verifikasi <span class="required-star">*</span></span><input name="verify_code" type="text" placeholder="Masukkan 6 digit" maxlength="6" pattern="[0-9]{6}" required></label></div>'+
|
||||
'<div class="auth-field"><label><span class="label-title">Password Baru <span class="required-star">*</span></span><input name="password" type="password" required></label></div>'+
|
||||
'<div class="auth-field"><label><span class="label-title">Konfirmasi Password Baru <span class="required-star">*</span></span><input name="password_confirm" type="password" required></label></div>';
|
||||
if(switchArea){ switchArea.innerHTML = '<span>Kembali ke <button type="button" id="auth-switch-to-login" class="data-link" style="background:transparent;border:0;padding:0;cursor:pointer;margin-left:4px">Masuk</button></span>'; }
|
||||
if(submitBtn) submitBtn.textContent = 'Reset Password';
|
||||
}
|
||||
modal.classList.remove('hidden');
|
||||
modal.setAttribute('aria-hidden','false');
|
||||
@@ -542,8 +558,10 @@ function openAuthModal(mode){
|
||||
try{
|
||||
const switchToRegister = document.getElementById('auth-switch-to-register');
|
||||
const switchToLogin = document.getElementById('auth-switch-to-login');
|
||||
const forgotPasswordLink = document.getElementById('auth-forgot-password-link');
|
||||
if(switchToRegister) switchToRegister.onclick = function(){ openAuthModal('register'); };
|
||||
if(switchToLogin) switchToLogin.onclick = function(){ openAuthModal('login'); };
|
||||
if(forgotPasswordLink) forgotPasswordLink.onclick = function(){ openAuthModal('forgot_password'); };
|
||||
}catch(e){}
|
||||
if(mode === 'register'){
|
||||
const orgProof = document.getElementById('org_proof_input');
|
||||
@@ -567,15 +585,16 @@ function openAuthModal(mode){
|
||||
});
|
||||
}
|
||||
}
|
||||
const form = document.getElementById('auth-modal-form');
|
||||
form.onsubmit = async function(ev){
|
||||
ev.preventDefault();
|
||||
|
||||
// Regular form submission (register or login)
|
||||
const endpoint = mode === 'register' ? 'src/api/auth/register.php' : 'src/api/auth/login.php';
|
||||
let endpoint = 'src/api/auth/login.php';
|
||||
if(mode === 'register') endpoint = 'src/api/auth/register.php';
|
||||
if(mode === 'forgot_password') endpoint = 'src/api/auth/reset_password.php';
|
||||
|
||||
try{
|
||||
let resp, jr;
|
||||
if(mode === 'register'){
|
||||
if(mode === 'register' || mode === 'forgot_password'){
|
||||
// Validate password length and match
|
||||
const passwordInput = form.querySelector('input[name="password"]');
|
||||
const password = passwordInput ? passwordInput.value : '';
|
||||
@@ -591,16 +610,18 @@ function openAuthModal(mode){
|
||||
return;
|
||||
}
|
||||
|
||||
// client-side validation for org_proof: size <=5MB and allowed extensions
|
||||
const fileInput = form.querySelector('input[name="org_proof"]') || document.getElementById('org_proof_input');
|
||||
if(!fileInput){ showToast('Input bukti organisasi tidak ditemukan', 'error', 4000); return; }
|
||||
if(!(fileInput.files && fileInput.files.length > 0)){ showToast('Mohon unggah bukti organisasi (foto/pdf).', 'error', 5000); return; }
|
||||
const f = fileInput.files[0];
|
||||
const maxSize = 5 * 1024 * 1024;
|
||||
const allowed = ['jpg','jpeg','png','svg','pdf'];
|
||||
const ext = (f.name || '').split('.').pop().toLowerCase();
|
||||
if(f.size > maxSize){ showToast('Ukuran file bukti organisasi maksimal 5MB', 'error', 5000); return; }
|
||||
if(!allowed.includes(ext)){ showToast('Jenis file tidak diperbolehkan. Hanya .png, .jpg, .jpeg, .svg, atau .pdf.', 'error', 5000); return; }
|
||||
if(mode === 'register'){
|
||||
// client-side validation for org_proof: size <=5MB and allowed extensions
|
||||
const fileInput = form.querySelector('input[name="org_proof"]') || document.getElementById('org_proof_input');
|
||||
if(!fileInput){ showToast('Input bukti organisasi tidak ditemukan', 'error', 4000); return; }
|
||||
if(!(fileInput.files && fileInput.files.length > 0)){ showToast('Mohon unggah bukti organisasi (foto/pdf).', 'error', 5000); return; }
|
||||
const f = fileInput.files[0];
|
||||
const maxSize = 5 * 1024 * 1024;
|
||||
const allowed = ['jpg','jpeg','png','svg','pdf'];
|
||||
const ext = (f.name || '').split('.').pop().toLowerCase();
|
||||
if(f.size > maxSize){ showToast('Ukuran file bukti organisasi maksimal 5MB', 'error', 5000); return; }
|
||||
if(!allowed.includes(ext)){ showToast('Jenis file tidak diperbolehkan. Hanya .png, .jpg, .jpeg, .svg, atau .pdf.', 'error', 5000); return; }
|
||||
}
|
||||
|
||||
// Check verify code
|
||||
const codeInput = form.querySelector('input[name="verify_code"]');
|
||||
@@ -610,9 +631,17 @@ function openAuthModal(mode){
|
||||
return;
|
||||
}
|
||||
|
||||
const fd = new FormData(form);
|
||||
resp = await fetch(endpoint, { method: 'POST', headers: buildHeaders(null), body: fd, credentials: 'same-origin' });
|
||||
jr = await resp.json().catch(()=>null);
|
||||
if(mode === 'register'){
|
||||
const fd = new FormData(form);
|
||||
resp = await fetch(endpoint, { method: 'POST', headers: buildHeaders(null), body: fd, credentials: 'same-origin' });
|
||||
jr = await resp.json().catch(()=>null);
|
||||
} else {
|
||||
const fd = new FormData(form);
|
||||
const payload = {};
|
||||
for(const [k,v] of fd.entries()) payload[k] = v;
|
||||
resp = await fetch(endpoint, { method: 'POST', headers: buildHeaders(), body: JSON.stringify(payload), credentials: 'same-origin' });
|
||||
jr = await resp.json().catch(()=>null);
|
||||
}
|
||||
} else {
|
||||
const fd = new FormData(form);
|
||||
const payload = {};
|
||||
@@ -621,13 +650,17 @@ function openAuthModal(mode){
|
||||
jr = await resp.json().catch(()=>null);
|
||||
}
|
||||
if(!resp.ok || !jr || jr.success === false){
|
||||
showToast((jr && (jr.error || jr.status)) ? (jr.error || jr.status) : 'Gagal memproses respons dari server', 'error', 5000);
|
||||
showToast((jr && (jr.error || jr.status || jr.message)) ? (jr.error || jr.status || jr.message) : 'Gagal memproses respons dari server', 'error', 5000);
|
||||
return;
|
||||
}
|
||||
if(mode === 'register'){
|
||||
authRegisterState = { code_sent: false, code: null, email: null };
|
||||
closeAuthModal();
|
||||
showToast('Pendaftaran berhasil! Akun menunggu persetujuan admin.', 'success', 5000);
|
||||
} else if(mode === 'forgot_password'){
|
||||
authRegisterState = { code_sent: false, code: null, email: null };
|
||||
closeAuthModal();
|
||||
showToast('Reset password berhasil! Silakan masuk kembali.', 'success', 5000);
|
||||
} else {
|
||||
if(jr && jr.token){ syncAuthToken(jr.token); }
|
||||
if(jr && jr.user){ syncCurrentUser(jr.user); }
|
||||
@@ -639,9 +672,9 @@ function openAuthModal(mode){
|
||||
}catch(e){ console.error(e); showToast('Gagal memproses autentikasi', 'error', 5000); }
|
||||
};
|
||||
|
||||
// Setup event listeners for registration "Send Verification Code" button
|
||||
if(mode === 'register'){
|
||||
const sendCodeBtn = document.getElementById('auth-send-code-btn');
|
||||
// Setup event listeners for registration and forgot password "Send Verification Code" buttons
|
||||
const wireVerificationBtn = function(btnId) {
|
||||
const sendCodeBtn = document.getElementById(btnId);
|
||||
if(sendCodeBtn){
|
||||
sendCodeBtn.onclick = async function(ev){
|
||||
ev.preventDefault();
|
||||
@@ -724,7 +757,7 @@ function openAuthModal(mode){
|
||||
}
|
||||
}
|
||||
|
||||
showToast('Kode verifikasi dikirim ke email Anda!', 'success', 4000);
|
||||
showToast('Kode verifikasi terkirim ke email Anda! Silakan cek email Anda.', 'success', 6000);
|
||||
|
||||
// Cooldown countdown timer
|
||||
let cooldown = 30;
|
||||
@@ -749,6 +782,12 @@ function openAuthModal(mode){
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if(mode === 'register'){
|
||||
wireVerificationBtn('auth-send-code-btn');
|
||||
} else if(mode === 'forgot_password'){
|
||||
wireVerificationBtn('auth-send-forgot-code-btn');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user