133 lines
4.8 KiB
PHP
133 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\V1;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Domain;
|
|
use App\Models\MailUser;
|
|
use App\Services\WebhookService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class MailboxController extends Controller
|
|
{
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$query = MailUser::with('domain')
|
|
->where('is_system', false);
|
|
|
|
if ($request->filled('domain')) {
|
|
$query->whereHas('domain', fn($q) => $q->where('domain', $request->domain));
|
|
}
|
|
if ($request->filled('active')) {
|
|
$query->where('is_active', filter_var($request->active, FILTER_VALIDATE_BOOLEAN));
|
|
}
|
|
|
|
$mailboxes = $query->orderBy('email')->paginate(100);
|
|
|
|
return response()->json([
|
|
'data' => $mailboxes->map(fn($m) => $this->format($m)),
|
|
'meta' => ['total' => $mailboxes->total(), 'per_page' => $mailboxes->perPage(), 'current_page' => $mailboxes->currentPage()],
|
|
]);
|
|
}
|
|
|
|
public function show(int $id): JsonResponse
|
|
{
|
|
$mailbox = MailUser::with('domain')->where('is_system', false)->findOrFail($id);
|
|
return response()->json(['data' => $this->format($mailbox)]);
|
|
}
|
|
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$request->tokenCan('mailboxes:write') || abort(403, 'Scope mailboxes:write required.');
|
|
|
|
if ($request->isSandbox ?? false) {
|
|
return response()->json(['data' => array_merge(['id' => 9999], $request->only('email')), 'sandbox' => true], 201);
|
|
}
|
|
|
|
$data = $request->validate([
|
|
'email' => 'required|email|unique:mail_users,email',
|
|
'password' => 'required|string|min:8',
|
|
'display_name'=> 'nullable|string|max:120',
|
|
'quota_mb' => 'nullable|integer|min:0',
|
|
'is_active' => 'nullable|boolean',
|
|
]);
|
|
|
|
[$local, $domainName] = explode('@', $data['email']);
|
|
$domain = Domain::where('domain', $domainName)->firstOrFail();
|
|
|
|
$mailbox = MailUser::create([
|
|
'domain_id' => $domain->id,
|
|
'localpart' => $local,
|
|
'email' => $data['email'],
|
|
'display_name' => $data['display_name'] ?? null,
|
|
'password_hash'=> '{ARGON2I}' . base64_encode(password_hash($data['password'], PASSWORD_ARGON2I)),
|
|
'quota_mb' => $data['quota_mb'] ?? $domain->default_quota_mb ?? 1024,
|
|
'is_active' => $data['is_active'] ?? true,
|
|
]);
|
|
|
|
if (!($request->isSandbox ?? false)) {
|
|
app(WebhookService::class)->dispatch('mailbox.created', $this->format($mailbox->load('domain')));
|
|
}
|
|
|
|
return response()->json(['data' => $this->format($mailbox->load('domain'))], 201);
|
|
}
|
|
|
|
public function update(Request $request, int $id): JsonResponse
|
|
{
|
|
$request->tokenCan('mailboxes:write') || abort(403, 'Scope mailboxes:write required.');
|
|
|
|
$mailbox = MailUser::where('is_system', false)->findOrFail($id);
|
|
|
|
if ($request->isSandbox ?? false) {
|
|
return response()->json(['data' => $this->format($mailbox), 'sandbox' => true]);
|
|
}
|
|
|
|
$data = $request->validate([
|
|
'display_name' => 'nullable|string|max:120',
|
|
'quota_mb' => 'nullable|integer|min:0',
|
|
'is_active' => 'nullable|boolean',
|
|
'can_login' => 'nullable|boolean',
|
|
]);
|
|
|
|
$mailbox->update(array_filter($data, fn($v) => !is_null($v)));
|
|
|
|
if (!($request->isSandbox ?? false)) {
|
|
app(WebhookService::class)->dispatch('mailbox.updated', $this->format($mailbox->load('domain')));
|
|
}
|
|
|
|
return response()->json(['data' => $this->format($mailbox->load('domain'))]);
|
|
}
|
|
|
|
public function destroy(Request $request, int $id): JsonResponse
|
|
{
|
|
$request->tokenCan('mailboxes:write') || abort(403, 'Scope mailboxes:write required.');
|
|
|
|
$mailbox = MailUser::where('is_system', false)->findOrFail($id);
|
|
|
|
if ($request->isSandbox ?? false) {
|
|
return response()->json(['sandbox' => true], 204);
|
|
}
|
|
|
|
$formatted = $this->format($mailbox->load('domain'));
|
|
$mailbox->delete();
|
|
app(WebhookService::class)->dispatch('mailbox.deleted', $formatted);
|
|
return response()->json(null, 204);
|
|
}
|
|
|
|
private function format(MailUser $m): array
|
|
{
|
|
return [
|
|
'id' => $m->id,
|
|
'email' => $m->email,
|
|
'display_name' => $m->display_name,
|
|
'domain' => $m->domain?->domain,
|
|
'quota_mb' => $m->quota_mb,
|
|
'is_active' => $m->is_active,
|
|
'can_login' => $m->can_login,
|
|
'last_login_at'=> $m->last_login_at?->toIso8601String(),
|
|
'created_at' => $m->created_at->toIso8601String(),
|
|
];
|
|
}
|
|
}
|