first commit
This commit is contained in:
149
app/api/admin/settings/smtp/route.ts
Normal file
149
app/api/admin/settings/smtp/route.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { auth } from '@/lib/auth';
|
||||
import { settingsDb } from '@/lib/settings-db';
|
||||
import { emailService } from '@/lib/email-service';
|
||||
import { SMTPConfig, SMTPConfigResponse } from '@/lib/types/smtp';
|
||||
|
||||
/**
|
||||
* GET /api/admin/settings/smtp
|
||||
* Returns current SMTP configuration (password masked)
|
||||
*/
|
||||
export async function GET() {
|
||||
try {
|
||||
const session = await auth();
|
||||
|
||||
if (!session?.user || (session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
const dbConfig = settingsDb.getSMTPConfig();
|
||||
|
||||
let response: SMTPConfigResponse;
|
||||
|
||||
if (dbConfig) {
|
||||
// Mask password
|
||||
const maskedConfig = {
|
||||
...dbConfig,
|
||||
auth: {
|
||||
...dbConfig.auth,
|
||||
pass: '***',
|
||||
},
|
||||
};
|
||||
response = { config: maskedConfig, source: 'database' };
|
||||
} else {
|
||||
// Check if env config exists
|
||||
const hasEnvConfig =
|
||||
process.env.SMTP_HOST &&
|
||||
process.env.SMTP_USER &&
|
||||
process.env.SMTP_PASS;
|
||||
|
||||
if (hasEnvConfig) {
|
||||
const envConfig: SMTPConfig = {
|
||||
host: process.env.SMTP_HOST!,
|
||||
port: parseInt(process.env.SMTP_PORT || '587', 10),
|
||||
secure: process.env.SMTP_SECURE === 'true',
|
||||
auth: {
|
||||
user: process.env.SMTP_USER!,
|
||||
pass: '***',
|
||||
},
|
||||
from: {
|
||||
email: process.env.SMTP_FROM_EMAIL || '',
|
||||
name: process.env.SMTP_FROM_NAME || 'Location Tracker',
|
||||
},
|
||||
replyTo: process.env.SMTP_REPLY_TO,
|
||||
timeout: 10000,
|
||||
};
|
||||
response = { config: envConfig, source: 'env' };
|
||||
} else {
|
||||
response = { config: null, source: 'env' };
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(response);
|
||||
} catch (error) {
|
||||
console.error('[API] Failed to get SMTP config:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to get SMTP configuration' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/admin/settings/smtp
|
||||
* Save SMTP configuration to database
|
||||
*/
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const session = await auth();
|
||||
|
||||
if (!session?.user || (session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
const body = await request.json();
|
||||
const config = body.config as SMTPConfig;
|
||||
|
||||
// Trim whitespace from credentials to prevent auth errors
|
||||
if (config.host) config.host = config.host.trim();
|
||||
if (config.auth?.user) config.auth.user = config.auth.user.trim();
|
||||
if (config.auth?.pass) config.auth.pass = config.auth.pass.trim();
|
||||
if (config.from?.email) config.from.email = config.from.email.trim();
|
||||
|
||||
// Validation
|
||||
if (!config.host || !config.port || !config.auth?.user || !config.auth?.pass) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Missing required SMTP configuration fields' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
if (config.port < 1 || config.port > 65535) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Port must be between 1 and 65535' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Save to database (password will be encrypted)
|
||||
settingsDb.setSMTPConfig(config);
|
||||
|
||||
// Reset the cached transporter to use new config
|
||||
emailService.resetTransporter();
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error('[API] Failed to save SMTP config:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to save SMTP configuration' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /api/admin/settings/smtp
|
||||
* Reset to environment config
|
||||
*/
|
||||
export async function DELETE() {
|
||||
try {
|
||||
const session = await auth();
|
||||
|
||||
if (!session?.user || (session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
settingsDb.delete('smtp_config');
|
||||
|
||||
// Reset the cached transporter to use env config
|
||||
emailService.resetTransporter();
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error('[API] Failed to delete SMTP config:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to reset SMTP configuration' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
78
app/api/admin/settings/smtp/test/route.ts
Normal file
78
app/api/admin/settings/smtp/test/route.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { auth } from '@/lib/auth';
|
||||
import { emailService } from '@/lib/email-service';
|
||||
import { SMTPConfig } from '@/lib/types/smtp';
|
||||
|
||||
/**
|
||||
* POST /api/admin/settings/smtp/test
|
||||
* Test SMTP configuration by sending a test email
|
||||
*/
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const session = await auth();
|
||||
|
||||
if (!session?.user || (session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
const body = await request.json();
|
||||
const { config, testEmail } = body as { config?: SMTPConfig; testEmail: string };
|
||||
|
||||
if (!testEmail) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Test email address is required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Email validation
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(testEmail)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Invalid email address' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Test connection
|
||||
try {
|
||||
await emailService.testConnection(config);
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: error instanceof Error ? error.message : 'SMTP connection failed. Please check your settings.'
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
// Send test email
|
||||
try {
|
||||
await emailService.sendWelcomeEmail({
|
||||
email: testEmail,
|
||||
username: 'Test User',
|
||||
loginUrl: `${process.env.NEXTAUTH_URL || 'http://localhost:3000'}/login`,
|
||||
temporaryPassword: undefined,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: `Test email sent successfully to ${testEmail}`,
|
||||
});
|
||||
} catch (sendError) {
|
||||
console.error('[API] Test email send failed:', sendError);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: `Email send failed: ${sendError instanceof Error ? sendError.message : 'Unknown error'}`,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[API] SMTP test failed:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'SMTP test failed' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user