'Password minimal 8 karakter.']); } try { $this->client->createUserAsAdmin([ 'email' => $email, 'password' => $password, 'name' => $attributes['name'] ?? $email, ]); } catch (InsForgeException $exception) { if ($exception->getCode() === 409 || str_contains($exception->getMessage(), 'exist')) { throw ValidationException::withMessages(['email' => 'Email sudah terdaftar.']); } throw $exception; } [$authId] = $this->client->rawSql(sprintf( "SELECT id::text FROM auth.users WHERE email = '%s' LIMIT 1", str_replace("'", "''", $email), )) ?: [null]; $authId = $authId['id'] ?? null; if ($authId === null) { throw new \RuntimeException('Gagal menemukan user auth yang baru dibuat.'); } $this->client->rawSql(sprintf( "UPDATE auth.users SET email_verified = true WHERE id = '%s'", $authId, )); $this->client->insertRecord('users', [[ 'id' => $authId, 'name' => $attributes['name'] ?? $email, 'email' => $email, 'password' => Hash::make($password), 'role' => $role, 'is_active' => true, ]], asUser: false); $this->activity->log('user_created', 'users', $authId, "User {$email} dibuat dengan role {$role}.", $actor); return ['id' => $authId, 'email' => $email]; } public function setActive(string $userId, bool $active, ?User $actor = null): void { $this->client->updateRecords('users', ['id' => $userId], [ 'is_active' => $active, ], asUser: false); $this->activity->log( $active ? 'user_activated' : 'user_deactivated', 'users', $userId, sprintf('User %s.', $active ? 'diaktifkan' : 'dinonaktifkan'), $actor, ); } public function setRole(string $userId, string $role, ?User $actor = null): void { in_array($role, ['admin', 'operator'], true) || throw ValidationException::withMessages(['role' => 'Role tidak valid.']); $this->client->updateRecords('users', ['id' => $userId], [ 'role' => $role, ], asUser: false); $this->activity->log('user_role_changed', 'users', $userId, "Role diubah menjadi {$role}.", $actor); } }