diff --git a/components/PhoneInputWrapper.vue b/components/PhoneInputWrapper.vue index 9801f62..0a021d6 100644 --- a/components/PhoneInputWrapper.vue +++ b/components/PhoneInputWrapper.vue @@ -68,6 +68,7 @@ class="country-dropdown" :class="{ 'country-dropdown--mobile': isMobile }" elevation="8" + :style="isMobile ? 'display: block !important;' : ''" >
@@ -562,15 +563,21 @@ watch(() => props.modelValue, (newValue) => { right: 5% !important; width: 90vw !important; max-width: 400px !important; + min-height: 400px !important; max-height: 80vh !important; + height: auto !important; margin: 0 auto !important; border-radius: 16px !important; z-index: 2000 !important; box-shadow: 0 24px 48px rgba(0, 0, 0, 0.3) !important; overflow: hidden !important; + display: flex !important; + flex-direction: column !important; } .country-list--mobile { + flex: 1 !important; + min-height: 200px !important; max-height: calc(60vh - 120px) !important; overflow-y: auto !important; -webkit-overflow-scrolling: touch; diff --git a/pages/dashboard/admin.vue b/pages/dashboard/admin.vue index 4fb123e..0114436 100644 --- a/pages/dashboard/admin.vue +++ b/pages/dashboard/admin.vue @@ -112,136 +112,57 @@ - - - - - - mdi-shield-check - reCAPTCHA Configuration - - -

Configure reCAPTCHA settings for form security.

- - - mdi-shield-account - Configure reCAPTCHA - -
-
-
- - - - - mdi-account-plus - Membership Configuration - - -

Configure membership fees and payment details.

- - - mdi-bank - Configure Membership - -
-
-
-
- - - - - - - mdi-email-cog - Email Configuration - - -

Configure SMTP settings for email notifications and verification.

- - - mdi-email-settings - Configure Email - -
-
-
- - - - - mdi-cog-outline - All Settings - - -

Access all portal configuration settings in one place.

- - - mdi-cog - Portal Settings - -
-
-
-
- - + - mdi-database-cog - Database Configuration + mdi-cog + Portal Configuration -

Configure the NocoDB database connection for the Member Management system.

+

Configure all portal settings including database, email, reCAPTCHA, and membership fees in one centralized location.

- + - mdi-database-settings - Configure NocoDB + mdi-cog + Portal Settings - -
- - mdi-database - Ready for configuration - -
+ + + + + mdi-database + NocoDB + + + + + mdi-email + Email + + + + + mdi-shield + reCAPTCHA + + + + + mdi-bank + Membership + + +
diff --git a/server/api/admin/test-email.post.ts b/server/api/admin/test-email.post.ts index 605f410..a3f7e3d 100644 --- a/server/api/admin/test-email.post.ts +++ b/server/api/admin/test-email.post.ts @@ -51,16 +51,18 @@ export default defineEventHandler(async (event) => { const { getEmailService } = await import('~/server/utils/email'); const emailService = await getEmailService(); - // Verify connection first - const connectionOk = await emailService.verifyConnection(); - if (!connectionOk) { - throw createError({ - statusCode: 500, - statusMessage: 'SMTP connection verification failed. Please check your SMTP configuration.' - }); + // Try to verify connection but don't fail if verification doesn't work + // Some SMTP servers have issues with verify() but work fine for sending + try { + const connectionOk = await emailService.verifyConnection(); + if (connectionOk) { + console.log('[api/admin/test-email.post] SMTP connection verified successfully'); + } + } catch (verifyError: any) { + console.warn('[api/admin/test-email.post] SMTP verification failed, attempting to send anyway:', verifyError.message); } - // Send test email + // Attempt to send test email regardless of verification result await emailService.sendTestEmail(body.testEmail); console.log('[api/admin/test-email.post] ✅ Test email sent successfully'); diff --git a/server/utils/email.ts b/server/utils/email.ts index 4874f63..63417a0 100644 --- a/server/utils/email.ts +++ b/server/utils/email.ts @@ -60,20 +60,67 @@ export class EmailService { } try { - this.transporter = nodemailer.createTransport({ + // Determine security settings based on port + let useSecure = this.config.secure; + let requireTLS = false; + + // Auto-configure based on standard ports if not explicitly set + if (this.config.port === 587) { + // Port 587 typically uses STARTTLS + useSecure = false; + requireTLS = true; + } else if (this.config.port === 465) { + // Port 465 typically uses SSL/TLS + useSecure = true; + requireTLS = false; + } else if (this.config.port === 25) { + // Port 25 typically unencrypted (not recommended) + useSecure = false; + requireTLS = false; + } + + // Build transporter options + const transporterOptions: any = { host: this.config.host, port: this.config.port, - secure: this.config.secure, // true for 465, false for other ports - auth: this.config.username && this.config.password ? { + secure: useSecure, + // Connection timeout settings + connectionTimeout: 30000, // 30 seconds + greetingTimeout: 30000, + socketTimeout: 30000, + // Debug logging + logger: false, + debug: false + }; + + // Add requireTLS if needed (for STARTTLS) + if (requireTLS && !useSecure) { + transporterOptions.requireTLS = true; + } + + // Configure TLS options + transporterOptions.tls = { + rejectUnauthorized: false, // Accept self-signed certificates + // Don't specify minVersion or ciphers to allow auto-negotiation + }; + + // Add authentication only if credentials are provided + if (this.config.username && this.config.password) { + transporterOptions.auth = { user: this.config.username, pass: this.config.password - } : undefined, - tls: { - rejectUnauthorized: false // Accept self-signed certificates in development - } - }); + }; + } - console.log('[EmailService] ✅ SMTP transporter initialized'); + this.transporter = nodemailer.createTransport(transporterOptions); + + console.log('[EmailService] ✅ SMTP transporter initialized with options:', { + host: this.config.host, + port: this.config.port, + secure: transporterOptions.secure, + requireTLS: transporterOptions.requireTLS, + auth: !!transporterOptions.auth + }); } catch (error) { console.error('[EmailService] ❌ Failed to initialize SMTP transporter:', error); }