feat: tombol Kirim Akun via WhatsApp di manajemen user (generate password baru, link+username+password via wa.me, konfirmasi, disable tanpa HP) + test
This commit is contained in:
@@ -3,10 +3,12 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Setting;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
@@ -122,4 +124,44 @@ class UserController extends Controller
|
|||||||
return redirect()->route('users.index')
|
return redirect()->route('users.index')
|
||||||
->with('success', 'Password untuk ' . $user->name . ' berhasil direset.');
|
->with('success', 'Password untuk ' . $user->name . ' berhasil direset.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kirim akun (link + username + password baru) ke nomor HP user via WhatsApp.
|
||||||
|
* Password lama tidak bisa dikirim (tersimpan hash) — jadi dibuatkan password baru.
|
||||||
|
*/
|
||||||
|
public function sendWa(User $user): RedirectResponse
|
||||||
|
{
|
||||||
|
if ($user->id === auth()->id()) {
|
||||||
|
return back()->with('error', 'Tidak perlu mengirim akun ke diri sendiri.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blank($user->phone)) {
|
||||||
|
return back()->with('error', 'Nomor HP belum diisi untuk ' . $user->name . ' — isi dulu di form edit user.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate password baru yang mudah dibaca (8 karakter, tanpa karakter ambigu)
|
||||||
|
$password = Str::upper(Str::random(4)).rand(10, 99).Str::lower(Str::random(2));
|
||||||
|
|
||||||
|
$user->update([
|
||||||
|
'password' => Hash::make($password),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$appName = Setting::getValue('app_name', 'Aplikasi');
|
||||||
|
$appUrl = Setting::getValue('app_url', config('app.url', ''));
|
||||||
|
|
||||||
|
$message = implode("\n", [
|
||||||
|
'📲 *Akun Aplikasi '.$appName.'*',
|
||||||
|
'',
|
||||||
|
'Yth. '.$user->name.',',
|
||||||
|
'Berikut akun Anda untuk masuk ke aplikasi:',
|
||||||
|
'',
|
||||||
|
'🔗 Link: '.$appUrl,
|
||||||
|
'👤 Username: '.$user->username,
|
||||||
|
'🔑 Password: '.$password,
|
||||||
|
'',
|
||||||
|
'Mohon segera login dan ganti password Anda. Terima kasih.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->away('https://wa.me/'.$user->phone.'?text='.rawurlencode($message));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,18 @@
|
|||||||
<i class="fa-solid fa-key"></i>
|
<i class="fa-solid fa-key"></i>
|
||||||
</button>
|
</button>
|
||||||
@if($user->id !== auth()->id())
|
@if($user->id !== auth()->id())
|
||||||
|
<form action="{{ route('users.send-wa', $user->id) }}" method="POST" class="inline"
|
||||||
|
x-data="sendWaData({{ $user->id }}, '{{ addslashes($user->name) }}', {{ $user->phone ? 'true' : 'false' }})"
|
||||||
|
x-on:submit.prevent="confirmAndSubmit()">
|
||||||
|
@csrf
|
||||||
|
<button type="submit"
|
||||||
|
class="p-2 rounded-lg transition {{ $user->phone ? 'text-emerald-600 hover:bg-emerald-50' : 'text-gray-300 cursor-not-allowed' }}"
|
||||||
|
title="{{ $user->phone ? 'Kirim akun via WhatsApp' : 'Isi nomor HP dulu untuk kirim WhatsApp' }}"
|
||||||
|
@if(!$user->phone) disabled @endif>
|
||||||
|
<i class="fa-brands fa-whatsapp"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
<form action="{{ route('users.destroy', $user->id) }}" method="POST" class="inline"
|
<form action="{{ route('users.destroy', $user->id) }}" method="POST" class="inline"
|
||||||
x-data x-on:submit.prevent="if(await window.confirmSwal({text:'Hapus user ini?'})) $el.submit()">
|
x-data x-on:submit.prevent="if(await window.confirmSwal({text:'Hapus user ini?'})) $el.submit()">
|
||||||
@csrf @method('DELETE')
|
@csrf @method('DELETE')
|
||||||
@@ -341,6 +353,29 @@
|
|||||||
|
|
||||||
@push('scripts')
|
@push('scripts')
|
||||||
<script>
|
<script>
|
||||||
|
function sendWaData(userId, userName, hasPhone) {
|
||||||
|
return {
|
||||||
|
confirmAndSubmit() {
|
||||||
|
if (!hasPhone) return;
|
||||||
|
const form = this.$el.closest('form');
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Kirim Akun via WhatsApp',
|
||||||
|
html: 'Kirim link aplikasi, username, dan <b>password baru</b> ke <b>' + userName + '</b>?' +
|
||||||
|
'<br><br><span style="font-size:12px;color:#6b7280">Password baru akan dibuat otomatis (password lama tidak bisa dikirim karena tersimpan ter-enkripsi).</span>',
|
||||||
|
icon: 'question',
|
||||||
|
confirmButtonText: '<i class="fa-brands fa-whatsapp"></i> Ya, Kirim',
|
||||||
|
confirmButtonColor: '#25D366',
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed && form) {
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function userManager() {
|
function userManager() {
|
||||||
return {
|
return {
|
||||||
modalOpen: false, isEditing: false, editId: null,
|
modalOpen: false, isEditing: false, editId: null,
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ Route::middleware('auth')->group(function () {
|
|||||||
Route::put('/users/{user}', [UserController::class, 'update'])->name('users.update');
|
Route::put('/users/{user}', [UserController::class, 'update'])->name('users.update');
|
||||||
Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy');
|
Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy');
|
||||||
Route::post('/users/{user}/reset-password', [UserController::class, 'resetPassword'])->name('users.reset-password');
|
Route::post('/users/{user}/reset-password', [UserController::class, 'resetPassword'])->name('users.reset-password');
|
||||||
|
Route::post('/users/{user}/send-wa', [UserController::class, 'sendWa'])->name('users.send-wa');
|
||||||
|
|
||||||
Route::get('/settings/permissions', [\App\Http\Controllers\Admin\PermissionController::class, 'index'])->name('settings.permissions');
|
Route::get('/settings/permissions', [\App\Http\Controllers\Admin\PermissionController::class, 'index'])->name('settings.permissions');
|
||||||
Route::post('/settings/permissions', [\App\Http\Controllers\Admin\PermissionController::class, 'update'])->name('settings.permissions.update');
|
Route::post('/settings/permissions', [\App\Http\Controllers\Admin\PermissionController::class, 'update'])->name('settings.permissions.update');
|
||||||
|
|||||||
@@ -67,4 +67,37 @@ class UserManagementTest extends TestCase
|
|||||||
|
|
||||||
$this->assertDatabaseMissing('users', ['username' => 'guruaneh']);
|
$this->assertDatabaseMissing('users', ['username' => 'guruaneh']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_kirim_akun_via_whatsapp(): void
|
||||||
|
{
|
||||||
|
$user = User::factory()->create([
|
||||||
|
'roles' => ['bk'],
|
||||||
|
'phone' => '081234567890',
|
||||||
|
'username' => 'guruwa',
|
||||||
|
'password' => 'passwordlama',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->actingAs($this->admin)
|
||||||
|
->post("/users/{$user->id}/send-wa");
|
||||||
|
|
||||||
|
$response->assertRedirect();
|
||||||
|
$this->assertStringStartsWith('https://wa.me/081234567890?text=', $response->headers->get('Location'));
|
||||||
|
$this->assertStringContainsString('guruwa', $response->headers->get('Location'));
|
||||||
|
$this->assertStringContainsString('password', urldecode($response->headers->get('Location')));
|
||||||
|
|
||||||
|
// Password lama tidak berlaku lagi (digenerate baru)
|
||||||
|
$this->assertFalse(\Illuminate\Support\Facades\Hash::check('passwordlama', $user->refresh()->password));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_kirim_akun_tanpa_nomor_hp_ditolak(): void
|
||||||
|
{
|
||||||
|
$user = User::factory()->create(['roles' => ['bk'], 'phone' => null]);
|
||||||
|
|
||||||
|
$this->actingAs($this->admin)
|
||||||
|
->post("/users/{$user->id}/send-wa")
|
||||||
|
->assertRedirect()
|
||||||
|
->assertSessionHas('error');
|
||||||
|
|
||||||
|
$this->assertFalse(str_contains(session('error'), 'wa.me'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user