feat: add MailAccountController with CRUD + test + toggle routes
This commit is contained in:
parent
bbc06738e9
commit
8d336466f4
121
app/Http/Controllers/MailAccountController.php
Normal file
121
app/Http/Controllers/MailAccountController.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\MailAccount;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use PromoSeven\AzureMailer\Graph\TokenManager;
|
||||
|
||||
class MailAccountController extends Controller
|
||||
{
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
$accounts = MailAccount::orderBy('name')->get()->map(fn($a) => $this->accountData($a));
|
||||
return response()->json(['accounts' => $accounts]);
|
||||
}
|
||||
|
||||
public function show(MailAccount $mailAccount): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'account' => array_merge($this->accountData($mailAccount), ['config' => $mailAccount->config]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$data = $this->validated($request);
|
||||
$account = MailAccount::create($data);
|
||||
return response()->json(['success' => true, 'account' => $this->accountData($account)], 201);
|
||||
}
|
||||
|
||||
public function update(Request $request, MailAccount $mailAccount): JsonResponse
|
||||
{
|
||||
$data = $this->validated($request, $mailAccount->id);
|
||||
$mailAccount->update($data);
|
||||
return response()->json(['success' => true, 'account' => $this->accountData($mailAccount->fresh())]);
|
||||
}
|
||||
|
||||
public function destroy(MailAccount $mailAccount): JsonResponse
|
||||
{
|
||||
$mailAccount->delete();
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function testConnection(MailAccount $mailAccount): JsonResponse
|
||||
{
|
||||
try {
|
||||
if ($mailAccount->type === 'azure') {
|
||||
$config = array_merge($mailAccount->config, ['from_address' => $mailAccount->from_address]);
|
||||
(new TokenManager($config))->getToken();
|
||||
} else {
|
||||
$cfg = $mailAccount->config;
|
||||
$host = $cfg['host'] ?? '';
|
||||
$port = (int) ($cfg['port'] ?? 587);
|
||||
$socket = @fsockopen($host, $port, $errno, $errstr, 5);
|
||||
if (! $socket) {
|
||||
throw new \RuntimeException("Cannot connect to {$host}:{$port} — {$errstr}");
|
||||
}
|
||||
fclose($socket);
|
||||
}
|
||||
return response()->json(['success' => true]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function toggleEnabled(MailAccount $mailAccount): JsonResponse
|
||||
{
|
||||
$mailAccount->update(['enabled' => ! $mailAccount->enabled]);
|
||||
return response()->json(['success' => true, 'enabled' => $mailAccount->fresh()->enabled]);
|
||||
}
|
||||
|
||||
private function validated(Request $request, ?int $ignoreId = null): array
|
||||
{
|
||||
$nameUnique = 'unique:mail_accounts,name' . ($ignoreId ? ",{$ignoreId}" : '');
|
||||
$rules = [
|
||||
'name' => ['required', 'string', 'max:100', 'regex:/^[a-z0-9\-]+$/', $nameUnique],
|
||||
'label' => ['required', 'string', 'max:150'],
|
||||
'type' => ['required', 'in:azure,smtp'],
|
||||
'from_address' => ['required', 'email', 'max:255'],
|
||||
'from_name' => ['nullable', 'string', 'max:150'],
|
||||
'enabled' => ['boolean'],
|
||||
];
|
||||
|
||||
if ($request->input('type') === 'azure') {
|
||||
$rules['config.tenant_id'] = ['required', 'string', 'max:100'];
|
||||
$rules['config.client_id'] = ['required', 'string', 'max:100'];
|
||||
$rules['config.client_secret'] = ['required', 'string', 'max:500'];
|
||||
} else {
|
||||
$rules['config.host'] = ['required', 'string', 'max:255'];
|
||||
$rules['config.port'] = ['required', 'integer', 'min:1', 'max:65535'];
|
||||
$rules['config.encryption'] = ['required', 'in:tls,ssl,none'];
|
||||
$rules['config.username'] = ['nullable', 'string', 'max:255'];
|
||||
$rules['config.password'] = ['nullable', 'string', 'max:500'];
|
||||
}
|
||||
|
||||
$v = $request->validate($rules);
|
||||
return [
|
||||
'name' => $v['name'],
|
||||
'label' => $v['label'],
|
||||
'type' => $v['type'],
|
||||
'from_address' => $v['from_address'],
|
||||
'from_name' => $v['from_name'] ?? null,
|
||||
'config' => $v['config'],
|
||||
'enabled' => $v['enabled'] ?? true,
|
||||
];
|
||||
}
|
||||
|
||||
private function accountData(MailAccount $account): array
|
||||
{
|
||||
return [
|
||||
'id' => $account->id,
|
||||
'name' => $account->name,
|
||||
'label' => $account->label,
|
||||
'type' => $account->type,
|
||||
'from_address' => $account->from_address,
|
||||
'from_name' => $account->from_name,
|
||||
'enabled' => $account->enabled,
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -26,6 +26,7 @@ use App\Http\Controllers\Sales\DeliveryNoteController;
|
||||
use App\Http\Controllers\Sales\PaymentReceiptController;
|
||||
use App\Http\Controllers\Sales\SalesInvoiceController;
|
||||
use App\Http\Controllers\Sales\SalesOrderController;
|
||||
use App\Http\Controllers\MailAccountController;
|
||||
use App\Http\Controllers\SettingsController;
|
||||
use App\Http\Controllers\Settings\ProjectSettingController;
|
||||
use App\Models\Settings\Location;
|
||||
@ -123,9 +124,13 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||
Route::post('settings/integrations/whatsapp', [SettingsController::class, 'updateWhatsapp'])->name('settings.integrations.whatsapp');
|
||||
Route::post('settings/integrations/test-whatsapp', [SettingsController::class, 'testWhatsappConnection'])->name('settings.integrations.test-whatsapp');
|
||||
Route::post('settings/integrations/send-test-message', [SettingsController::class, 'sendTestMessage'])->name('settings.integrations.send-test-message');
|
||||
Route::post('settings/integrations/azure-mail', [SettingsController::class, 'updateAzureMail'])->name('settings.integrations.azure-mail');
|
||||
Route::post('settings/integrations/test-azure-mail', [SettingsController::class, 'testAzureMailConnection'])->name('settings.integrations.test-azure-mail');
|
||||
Route::post('settings/integrations/send-test-email', [SettingsController::class, 'sendTestEmail'])->name('settings.integrations.send-test-email');
|
||||
Route::get('settings/integrations/mail-accounts', [MailAccountController::class, 'index'])->name('settings.mail-accounts.index');
|
||||
Route::post('settings/integrations/mail-accounts', [MailAccountController::class, 'store'])->name('settings.mail-accounts.store');
|
||||
Route::get('settings/integrations/mail-accounts/{mailAccount}', [MailAccountController::class, 'show'])->name('settings.mail-accounts.show');
|
||||
Route::put('settings/integrations/mail-accounts/{mailAccount}', [MailAccountController::class, 'update'])->name('settings.mail-accounts.update');
|
||||
Route::delete('settings/integrations/mail-accounts/{mailAccount}', [MailAccountController::class, 'destroy'])->name('settings.mail-accounts.destroy');
|
||||
Route::post('settings/integrations/mail-accounts/{mailAccount}/test', [MailAccountController::class, 'testConnection'])->name('settings.mail-accounts.test');
|
||||
Route::patch('settings/integrations/mail-accounts/{mailAccount}/toggle', [MailAccountController::class, 'toggleEnabled'])->name('settings.mail-accounts.toggle');
|
||||
|
||||
// Projects settings
|
||||
Route::get('settings/projects', [ProjectSettingController::class, 'index'])->name('settings.projects.index');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user