feat: enforce SMTP configuration validation and show warning notices before enabling Email 2FA
This commit is contained in:
@@ -22,6 +22,7 @@ interface SettingsProps extends PageProps {
|
||||
qr_code: string | null;
|
||||
secret: string | null;
|
||||
email_enabled: boolean;
|
||||
smtp_configured: boolean;
|
||||
recovery_codes: string[];
|
||||
};
|
||||
}
|
||||
@@ -30,7 +31,7 @@ interface SettingsProps extends PageProps {
|
||||
|
||||
function SectionCard({ title, description, children, delay = '0s', variant = 'default' }: { title: string; description: string; children: React.ReactNode; delay?: string; variant?: 'default' | 'danger' }) {
|
||||
const isDanger = variant === 'danger';
|
||||
|
||||
|
||||
return (
|
||||
<div className={`bg-white rounded-2xl border ${isDanger ? 'border-red-200 shadow-none' : 'border-gray-100 shadow-sm'} overflow-hidden h-full flex flex-col anim-up`} style={{ animationDelay: delay }}>
|
||||
<div className={`px-6 py-4 border-b ${isDanger ? 'border-red-100 bg-red-50' : 'border-gray-50 bg-gray-50/30'}`}>
|
||||
@@ -198,6 +199,16 @@ export default function SettingsIndex({ twoFactor }: SettingsProps) {
|
||||
};
|
||||
|
||||
const handleToggleEmail2FA = async (enable: boolean) => {
|
||||
if (enable && !twoFactor.smtp_configured) {
|
||||
Swal.fire({
|
||||
icon: 'warning',
|
||||
title: 'SMTP Mail Server Not Set Up',
|
||||
text: 'Two-Factor Authentication via Email cannot be enabled because the system SMTP configurations are not set up yet. Please configure the SMTP settings under System Settings (or contact your Administrator) first.',
|
||||
confirmButtonColor: '#3D4E4B',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable && twoFactor.enabled) {
|
||||
const warning = await swal.confirm(
|
||||
'Switch to Email 2FA?',
|
||||
@@ -305,7 +316,7 @@ export default function SettingsIndex({ twoFactor }: SettingsProps) {
|
||||
</form>
|
||||
</SectionCard>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="lg:col-span-1">
|
||||
<SectionCard title="Profile Photo" description="Update your avatar" delay="0.15s">
|
||||
<div className="flex flex-col items-center gap-6">
|
||||
@@ -356,7 +367,7 @@ export default function SettingsIndex({ twoFactor }: SettingsProps) {
|
||||
)}
|
||||
|
||||
{activeTab === '2fa' && (
|
||||
<div className="max-w-3xl space-y-6 anim-fade">
|
||||
<div className="max-w-4xl space-y-8 anim-fade">
|
||||
<div className="p-5 bg-amber-50 border border-amber-200 rounded-2xl flex items-start gap-3">
|
||||
<svg className="w-5 h-5 text-amber-500 mt-0.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
|
||||
@@ -476,10 +487,16 @@ export default function SettingsIndex({ twoFactor }: SettingsProps) {
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-bold text-[#3D4E4B]">Two-Factor Authentication via Email</div>
|
||||
<div className="text-xs text-gray-400 font-medium mt-0.5">
|
||||
{twoFactor.email_enabled
|
||||
? 'Email 2FA is active. Every login attempt will require an OTP code sent to your email.'
|
||||
{twoFactor.email_enabled
|
||||
? 'Email 2FA is active. Every login attempt will require an OTP code sent to your email.'
|
||||
: 'Receive a 6-digit OTP code in your email to secure your login sessions.'}
|
||||
</div>
|
||||
{!twoFactor.smtp_configured && (
|
||||
<div className="flex items-center gap-1.5 mt-2 text-[11px] font-bold text-amber-600 bg-amber-50 px-2.5 py-1 rounded-lg w-fit border border-amber-200">
|
||||
<span className="text-sm">⚠</span>
|
||||
<span>SMTP Mail Server is not configured. Setup required.</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{twoFactor.email_enabled ? (
|
||||
<button onClick={() => handleToggleEmail2FA(false)} type="button"
|
||||
|
||||
Reference in New Issue
Block a user