validate([ 'nama' => 'required|string|max:255', 'email' => 'required|email|unique:pengguna', 'kata_sandi' => 'required|min:6', ]); $pengguna = Pengguna::create([ 'nama' => $request->nama, 'email' => $request->email, 'kata_sandi' => Hash::make($request->kata_sandi), ]); return response()->json(['message' => 'Registrasi berhasil'], 201); } public function login(Request $request) { $request->validate([ 'email' => 'required|email', 'kata_sandi' => 'required' ]); $pengguna = Pengguna::where('email', $request->email)->first(); if (!$pengguna || !Hash::check($request->kata_sandi, $pengguna->kata_sandi)) { return response()->json(['message' => 'Email atau kata sandi salah'], 401); } $token = $pengguna->createToken('API token')->plainTextToken; return response()->json([ 'message' => 'Login berhasil', 'token' => $token ]); } public function logout(Request $request) { $request->user()->tokens()->delete(); return response()->json(['message' => 'Logout berhasil']); } public function profile(Request $request) { $pengguna = $request->user(); return response()->json([ 'nama' => $pengguna->nama, 'email' => $pengguna->email ]); } public function updateProfile(Request $request) { $pengguna = $request->user(); $request->validate([ 'nama' => 'required|string|max:255', 'email' => [ 'required', 'email', Rule::unique('pengguna')->ignore($pengguna->id) ], 'kata_sandi' => 'nullable|min:8', ]); $pengguna->nama = $request->nama; $pengguna->email = $request->email; if ($request->filled('kata_sandi')) { $pengguna->kata_sandi = Hash::make($request->kata_sandi); } $pengguna->save(); return response()->json([ 'message' => 'Profil berhasil diperbarui', 'pengguna' => [ 'nama' => $pengguna->nama, 'email' => $pengguna->email ] ]); } public function forgotPassword(Request $request) { $request->validate([ 'email' => 'required|email|exists:pengguna,email', ]); // Generate plain text token for API $plainToken = Str::random(60); // Store hashed token in database DB::table('password_resets')->updateOrInsert( ['email' => $request->email], [ 'email' => $request->email, 'token' => Hash::make($plainToken), 'created_at' => Carbon::now(), ] ); // Buat URL untuk web $resetLink = url('/reset-password') . '?token=' . $plainToken . '&email=' . urlencode($request->email); // Kirim email dengan URL web dan mobile deep link Mail::to($request->email)->send(new ForgotPasswordMail($resetLink, $plainToken, $request->email)); // Return token dalam API response untuk mobile app return response()->json([ 'status' => true, 'message' => 'Kami telah mengirim email reset password.', 'token' => $plainToken, // Return plain token untuk mobile app ]); } public function resetPassword(Request $request) { $request->validate([ 'token' => 'required|string', 'email' => 'required|email|exists:pengguna,email', 'password' => 'required|string|min:8', 'password_confirmation' => 'required|same:password', ]); // Cek token di database $passwordReset = DB::table('password_resets') ->where('email', $request->email) ->first(); if (!$passwordReset) { return response()->json([ 'status' => false, 'message' => 'Token tidak valid atau sudah kadaluarsa.' ], 400); } // Verifikasi token if (!Hash::check($request->token, $passwordReset->token)) { return response()->json([ 'status' => false, 'message' => 'Token tidak valid.' ], 400); } // Periksa apakah token sudah kadaluarsa (60 menit) $expiresAt = Carbon::parse($passwordReset->created_at)->addMinutes(60); if (Carbon::now()->isAfter($expiresAt)) { return response()->json([ 'status' => false, 'message' => 'Token sudah kadaluarsa.' ], 400); } // Reset password $pengguna = Pengguna::where('email', $request->email)->first(); $pengguna->kata_sandi = Hash::make($request->password); $pengguna->save(); // Hapus token setelah digunakan DB::table('password_resets')->where('email', $request->email)->delete(); return response()->json([ 'status' => true, 'message' => 'Password berhasil direset.' ]); } }