attributes->get('service_caller') !== 'webmail') { return response()->json(['message' => 'Forbidden.'], 403); } $maxBytes = (int) config('transfer.max_file_bytes', 0); $maxFiles = (int) config('transfer.max_files_per_transfer', 20); $fileRules = ['required', 'file']; if ($maxBytes > 0) { $fileRules[] = 'max:'.(int) ceil($maxBytes / 1024); } $data = $request->validate([ 'mailbox' => ['required', 'email', 'max:255'], 'title' => ['nullable', 'string', 'max:120'], 'message' => ['nullable', 'string', 'max:2000'], 'retention_days' => ['nullable', 'integer', 'min:1', 'max:365'], 'files' => ['required', 'array', 'min:1', 'max:'.$maxFiles], 'files.*' => $fileRules, ]); try { $user = $this->users->resolve((string) $data['mailbox']); } catch (RuntimeException $e) { return response()->json(['message' => $e->getMessage()], 422); } $title = trim((string) ($data['title'] ?? '')); if ($title === '') { $title = 'Email attachment'; } $retentionDays = (int) ($data['retention_days'] ?? config('transfer.mail_retention_days', config('transfer.default_retention_days', 30))); try { $transfer = $this->transfers->create($user, [ 'title' => $title, 'message' => $data['message'] ?? null, 'retention_days' => $retentionDays, ], $request->file('files', [])); } catch (RuntimeException $e) { return response()->json(['message' => $e->getMessage()], 422); } $transfer->load(['files', 'qrCode']); return response()->json([ 'data' => [ 'id' => $transfer->id, 'title' => $transfer->title, 'public_url' => $transfer->qrCode?->publicUrl(), 'paid_until' => $transfer->paid_until?->toIso8601String(), 'expires_at' => $transfer->paid_until?->toIso8601String(), 'files' => $transfer->files->map(fn ($file) => [ 'name' => $file->original_name, 'size_bytes' => $file->size_bytes, ])->values(), ], ], 201); } }