Browse Source

feat(api): tambah PUT /me, POST /me/password, POST /me/test-email

master
Budi Setiawan 3 weeks ago
parent
commit
835954812c
  1. BIN
      server-connection/geonet-console-deploy.tar.gz
  2. 104
      server-connection/geonet-console/app/Http/Controllers/Api/V1/MeController.php
  3. 3
      server-connection/geonet-console/routes/api.php

BIN
server-connection/geonet-console-deploy.tar.gz

Binary file not shown.

104
server-connection/geonet-console/app/Http/Controllers/Api/V1/MeController.php

@ -6,9 +6,14 @@ use App\Http\Controllers\Api\Concerns\RespondsWithJson; @@ -6,9 +6,14 @@ use App\Http\Controllers\Api\Concerns\RespondsWithJson;
use App\Http\Controllers\Controller;
use App\Services\LdapAuthService;
use App\Services\LdapMetadataService;
use App\Services\LdapUserService;
use App\Services\MailDeliveryService;
use App\Support\ApiActor;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use InvalidArgumentException;
use RuntimeException;
use Throwable;
class MeController extends Controller
{
@ -17,6 +22,8 @@ class MeController extends Controller @@ -17,6 +22,8 @@ class MeController extends Controller
public function __construct(
private readonly LdapAuthService $ldapAuth,
private readonly LdapMetadataService $metadata,
private readonly LdapUserService $ldapUsers,
private readonly MailDeliveryService $mailDelivery,
) {
}
@ -27,7 +34,6 @@ class MeController extends Controller @@ -27,7 +34,6 @@ class MeController extends Controller
$data = $actor->toArray();
// Untuk LDAP JWT — enrich dengan data profile dari LDAP + metadata DB
if ($actor->type === 'ldap_jwt') {
$profile = $this->ldapAuth->getProfile($actor->identifier);
$meta = $this->metadata->getUserMeta($actor->identifier);
@ -42,4 +48,100 @@ class MeController extends Controller @@ -42,4 +48,100 @@ class MeController extends Controller
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 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]);
}
}

3
server-connection/geonet-console/routes/api.php

@ -22,6 +22,9 @@ Route::prefix('v1')->group(function () { @@ -22,6 +22,9 @@ Route::prefix('v1')->group(function () {
Route::middleware(['api.auth', 'api.audit'])->group(function () {
Route::get('/me', [MeController::class, 'show'])->name('api.v1.me');
Route::put('/me', [MeController::class, 'update'])->name('api.v1.me.update');
Route::post('/me/password', [MeController::class, 'changePassword'])->name('api.v1.me.password');
Route::post('/me/test-email', [MeController::class, 'testEmail'])->name('api.v1.me.test-email');
Route::get('/databases', [DatabaseController::class, 'index'])
->middleware('api.scope:databases:read')

Loading…
Cancel
Save