Browse Source

feat(api): PUT /me/avatar simpan foto profil sebagai base64 di ldap_user_meta

master
Budi Setiawan 3 weeks ago
parent
commit
d500db95b3
  1. BIN
      server-connection/geonet-console-deploy.tar.gz
  2. 31
      server-connection/geonet-console/app/Http/Controllers/Api/V1/MeController.php
  3. 2
      server-connection/geonet-console/app/Models/LdapUserMeta.php
  4. 9
      server-connection/geonet-console/app/Services/LdapMetadataService.php
  5. 22
      server-connection/geonet-console/database/migrations/2026_06_24_000001_add_avatar_to_ldap_user_meta.php
  6. 1
      server-connection/geonet-console/routes/api.php

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

Binary file not shown.

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

@ -44,6 +44,7 @@ class MeController extends Controller
$data['domain'] = $profile['domain'] ?? ''; $data['domain'] = $profile['domain'] ?? '';
$data['phone'] = $meta['phone'] ?? ''; $data['phone'] = $meta['phone'] ?? '';
$data['other_email'] = $meta['other_email'] ?? ''; $data['other_email'] = $meta['other_email'] ?? '';
$data['avatar'] = $meta['avatar'] ?? null;
} }
return $this->ok($data); return $this->ok($data);
@ -115,6 +116,36 @@ class MeController extends Controller
return $this->ok(['message' => 'Password berhasil diubah.']); 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 public function testEmail(Request $request): JsonResponse
{ {
/** @var ApiActor $actor */ /** @var ApiActor $actor */

2
server-connection/geonet-console/app/Models/LdapUserMeta.php

@ -8,5 +8,5 @@ class LdapUserMeta extends Model
{ {
protected $table = 'ldap_user_meta'; protected $table = 'ldap_user_meta';
protected $fillable = ['username', 'other_email', 'phone', 'admin_note']; protected $fillable = ['username', 'other_email', 'phone', 'admin_note', 'avatar'];
} }

9
server-connection/geonet-console/app/Services/LdapMetadataService.php

@ -15,6 +15,7 @@ class LdapMetadataService
'other_email' => $row?->other_email ?? '', 'other_email' => $row?->other_email ?? '',
'phone' => $row?->phone ?? '', 'phone' => $row?->phone ?? '',
'admin_note' => $row?->admin_note ?? '', 'admin_note' => $row?->admin_note ?? '',
'avatar' => $row?->avatar ?? null,
]; ];
} }
@ -44,6 +45,14 @@ class LdapMetadataService
); );
} }
public function saveAvatar(string $username, ?string $avatarBase64): void
{
LdapUserMeta::query()->updateOrCreate(
['username' => $username],
['avatar' => $avatarBase64],
);
}
public function getGroupMeta(string $groupKey): array public function getGroupMeta(string $groupKey): array
{ {
$row = LdapGroupMeta::query()->where('group_key', $groupKey)->first(); $row = LdapGroupMeta::query()->where('group_key', $groupKey)->first();

22
server-connection/geonet-console/database/migrations/2026_06_24_000001_add_avatar_to_ldap_user_meta.php

@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('ldap_user_meta', function (Blueprint $table) {
$table->text('avatar')->nullable()->after('phone');
});
}
public function down(): void
{
Schema::table('ldap_user_meta', function (Blueprint $table) {
$table->dropColumn('avatar');
});
}
};

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

@ -26,6 +26,7 @@ Route::prefix('v1')->group(function () {
Route::middleware(['api.auth', 'api.audit'])->group(function () { Route::middleware(['api.auth', 'api.audit'])->group(function () {
Route::get('/me', [MeController::class, 'show'])->name('api.v1.me'); Route::get('/me', [MeController::class, 'show'])->name('api.v1.me');
Route::put('/me', [MeController::class, 'update'])->name('api.v1.me.update'); Route::put('/me', [MeController::class, 'update'])->name('api.v1.me.update');
Route::put('/me/avatar', [MeController::class, 'updateAvatar'])->name('api.v1.me.avatar');
Route::post('/me/password', [MeController::class, 'changePassword'])->name('api.v1.me.password'); 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::post('/me/test-email', [MeController::class, 'testEmail'])->name('api.v1.me.test-email');

Loading…
Cancel
Save