attributes->get('api_actor'); $data = $actor->toArray(); if ($actor->type === 'ldap_jwt') { $profile = $this->ldapAuth->getProfile($actor->identifier); $meta = $this->metadata->getUserMeta($actor->identifier); $data['display_name'] = $profile['display_name'] ?? $actor->identifier; $data['email'] = $profile['email'] ?? ''; $data['last_logon'] = $profile['last_logon'] ?? null; $data['domain'] = $profile['domain'] ?? ''; $data['phone'] = $meta['phone'] ?? ''; $data['other_email'] = $meta['other_email'] ?? ''; $data['avatar'] = $meta['avatar'] ?? null; } return $this->ok($data); } public function update(Request $request): JsonResponse { /** @var ApiActor $actor */ $actor = $request->attributes->get('api_actor'); if ($actor->type !== 'ldap_jwt') { return $this->fail('Hanya akun LDAP yang dapat mengubah profil.', 'forbidden', 403); } $data = $request->validate([ 'display_name' => ['required', 'string', 'max:255'], 'email' => ['nullable', 'email', 'max:255'], 'other_email' => ['nullable', 'email', 'max:255'], 'phone' => ['nullable', 'string', 'max:32'], ]); try { $this->ldapUsers->updateProfile( $actor->identifier, $data['display_name'], $data['email'] ?? null ); $this->metadata->saveUserSelfMeta( $actor->identifier, $data['other_email'] ?? null, $data['phone'] ?? null ); } catch (InvalidArgumentException|RuntimeException $e) { return $this->fail($e->getMessage(), 'unprocessable', 422); } catch (Throwable) { return $this->fail('Gagal memperbarui profil.', 'server_error', 500); } return $this->ok(['message' => 'Profil berhasil diperbarui.']); } public function changePassword(Request $request): JsonResponse { /** @var ApiActor $actor */ $actor = $request->attributes->get('api_actor'); if ($actor->type !== 'ldap_jwt') { return $this->fail('Hanya akun LDAP yang dapat mengubah password.', 'forbidden', 403); } $data = $request->validate([ 'current_password' => ['required', 'string'], 'new_password' => ['required', 'string', 'min:8', 'confirmed'], ]); $verified = $this->ldapAuth->attempt($actor->identifier, $data['current_password']); if ($verified === null) { return $this->fail('Password saat ini tidak sesuai.', 'invalid_credentials', 422); } try { $this->ldapUsers->resetPassword($actor->identifier, $data['new_password']); } catch (InvalidArgumentException|RuntimeException $e) { return $this->fail($e->getMessage(), 'unprocessable', 422); } catch (Throwable) { return $this->fail('Gagal mengubah password. Pastikan password memenuhi kebijakan AD.', 'server_error', 500); } return $this->ok(['message' => 'Password berhasil diubah.']); } public function updateAvatar(Request $request): JsonResponse { /** @var ApiActor $actor */ $actor = $request->attributes->get('api_actor'); if ($actor->type !== 'ldap_jwt') { return $this->fail('Hanya akun LDAP yang dapat mengubah avatar.', 'forbidden', 403); } $data = $request->validate([ 'avatar' => ['nullable', 'string', 'max:262144'], ]); try { $avatarValue = isset($data['avatar']) && $data['avatar'] !== '' ? $data['avatar'] : null; if ($avatarValue !== null && ! preg_match('/^data:image\/(jpeg|png|webp|gif);base64,/', $avatarValue)) { return $this->fail('Format avatar tidak valid. Harus base64 image (jpeg/png/webp).', 'invalid_format', 422); } $this->metadata->saveAvatar($actor->identifier, $avatarValue); } catch (Throwable) { return $this->fail('Gagal menyimpan avatar.', 'server_error', 500); } return $this->ok(['message' => 'Avatar berhasil diperbarui.', 'avatar' => $avatarValue]); } public function testEmail(Request $request): JsonResponse { /** @var ApiActor $actor */ $actor = $request->attributes->get('api_actor'); if ($actor->type !== 'ldap_jwt') { return $this->fail('Hanya akun LDAP yang dapat mengirim test email.', 'forbidden', 403); } $profile = $this->ldapAuth->getProfile($actor->identifier); $meta = $this->metadata->getUserMeta($actor->identifier); $recipients = array_values(array_filter([ ($profile['email'] ?? '') !== '' ? $profile['email'] : null, ($meta['other_email'] ?? '') !== '' ? $meta['other_email'] : null, ])); if ($recipients === []) { return $this->fail('Tidak ada alamat email tersimpan. Tambahkan email di profil terlebih dahulu.', 'no_email', 422); } try { $sent = $this->mailDelivery->sendTestToMany($recipients); } catch (Throwable) { return $this->fail('Gagal mengirim email. Periksa konfigurasi SMTP.', 'smtp_error', 500); } return $this->ok(['message' => 'Test email terkirim ke: ' . implode(', ', $sent) . '.', 'sent_to' => $sent]); } }