diff --git a/app/Http/Controllers/Admin/APIs/Customer_API/AuthController.php b/app/Http/Controllers/Admin/APIs/Customer_API/AuthController.php
index ea3f2c3..b5fb1dc 100644
--- a/app/Http/Controllers/Admin/APIs/Customer_API/AuthController.php
+++ b/app/Http/Controllers/Admin/APIs/Customer_API/AuthController.php
@@ -7,10 +7,13 @@ use App\Services\APIs\CustomerAPIs\AuthServices;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
+use App\Models\IamPrincipalOtp;
+use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Hash;
use Illuminate\Database\QueryException;
use App\Models\IamPrincipal;
use Carbon\Carbon;
+use Exception;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
@@ -87,7 +90,7 @@ class AuthController extends Controller
if ($validator->fails()) {
$validationErrors = $validator->errors()->all();
- Log::error("Registation validation error: " . implode(", ", $validationErrors));
+ Log::error("Customer validation error: " . implode(", ", $validationErrors));
return jsonResponseWithErrorMessageApi($validationErrors, 403);
}
return $this->AuthServices->register($request);
@@ -96,4 +99,157 @@ class AuthController extends Controller
return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
}
}
+
+ /**
+ * Created By : sayli Raut
+ * Created at : 24 May 2024
+ * Use : Customer login.
+ */
+ public function login(Request $request)
+ {
+
+ try {
+ $validator = Validator::make($request->all(), [
+ 'email_address' => 'required|string|email',
+ 'password' => 'required|string|min:6',
+ ]);
+
+ if ($validator->fails()) {
+ $validationErrors = $validator->errors()->all();
+ Log::error("Login validation error: " . implode(", ", $validationErrors));
+ return jsonResponseWithErrorMessageApi($validationErrors, 403);
+ }
+
+ return $this->AuthServices->login($request);
+ } catch (QueryException $e) {
+
+ Log::error('Customer Login Failed ' . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
+ }
+ }
+
+ /**
+ * Created By : sayli Raut
+ * Created at : 24 May 2024
+ * Use : forgot password.
+ */
+ public function forgotPassword(Request $request)
+ {
+ try {
+ $validator = Validator::make($request->all(), [
+ 'email_address' => [
+ 'required',
+ 'string',
+ 'email',
+ function ($attribute, $value, $fail) {
+ $existingUser = IamPrincipal::where('email_address', $value)->where('principal_type_xid', 3)->whereNull('deleted_at')->exists();
+ if (!$existingUser) {
+ $fail('The selected email address is invalid.');
+ }
+ },
+ ],
+ ]);
+
+ if ($validator->fails()) {
+ $validationErrors = $validator->errors()->all();
+ Log::error("Forgot password validation error: " . implode(", ", $validationErrors));
+ return jsonResponseWithErrorMessageApi($validationErrors, 403);
+ }
+ return $this->AuthServices->forgotPassword($request);
+
+ } catch (Exception $e) {
+ Log::error('Customer Forgot Password OTP function failed: ' . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
+ }
+ }
+
+
+ /**
+ * Created By : sayli Raut
+ * Created at : 24 May 2024
+ * Use : OTP verification.
+ */
+ public function verifyOTPForgotPassword(Request $request)
+ {
+ try {
+ $validator = Validator::make($request->all(), [
+ 'email_address' => [
+ 'required',
+ 'string',
+ 'email',
+ function ($attribute, $value, $fail) {
+ $existingUser = IamPrincipal::where('email_address', $value)->where('principal_type_xid', 3)->whereNull('deleted_at')->exists();
+ if (!$existingUser) {
+ $fail('The selected email address is invalid.');
+ }
+ },
+ ],
+ 'otp' => 'required',
+ ]);
+
+ if ($validator->fails()) {
+ $validationErrors = $validator->errors()->all();
+ Log::error("Forgot password validation error: " . implode(", ", $validationErrors));
+ return jsonResponseWithErrorMessageApi($validationErrors, 403);
+ }
+ return $this->AuthServices->verifyOTPForgotPassword($request);
+
+ } catch (Exception $e) {
+ DB::rollBack();
+ Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
+ }
+ }
+
+ /**
+ * Created By : sayli Raut
+ * Created at : 24 May 2024
+ * Use : Change Password.
+ */
+ public function changePassword(Request $request)
+ {
+ try {
+ $validator = Validator::make($request->all(), [
+ 'iam_principal_xid' => 'required|exists:iam_principal,id',
+ 'password' => 'required|confirmed',
+ ]);
+ if ($validator->fails()) {
+ $validationErrors = $validator->errors()->all();
+ Log::error("Forgot password validation error: " . implode(", ", $validationErrors));
+ return jsonResponseWithErrorMessageApi($validationErrors, 403);
+ }
+ return $this->AuthServices->changePassword($request);
+
+ } catch (Exception $e) {
+ Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage());
+ return response()->json(__('something_went_wrong'), 500);
+ }
+ }
+
+ /**
+ * Created By : sayli Raut
+ * Created at : 24 May 2024
+ * Use : Resend OTP .
+ */
+ public function resendOtp(Request $request)
+ {
+ try {
+ $validator = Validator::make($request->all(), [
+ 'iam_principal_xid' => 'required|exists:iam_principal,id',
+ 'otp_purpose' => 'required'
+ ]);
+
+ if ($validator->fails()) {
+ $validationErrors = $validator->errors()->all();
+ Log::error("Forgot password validation error: " . implode(", ", $validationErrors));
+ return jsonResponseWithErrorMessageApi($validationErrors, 403);
+ }
+ return $this->AuthServices->resendOtp($request);
+ } catch (Exception $e) {
+
+ DB::rollBack();
+ Log::error("An error occurred in " . __METHOD__ . ": " . $e->getMessage());
+ return response()->json(__('something_went_wrong'), 500);
+ }
+ }
}
diff --git a/app/Http/Helpers/Webhelper.php b/app/Http/Helpers/Webhelper.php
index 04a152f..30aa672 100644
--- a/app/Http/Helpers/Webhelper.php
+++ b/app/Http/Helpers/Webhelper.php
@@ -165,4 +165,20 @@ if (!function_exists('readRestHeaderToken')) {
return false;
}
}
+
+ if (!function_exists('generateOTP')) {
+
+ function generateOTP()
+ {
+ // Define the length of the OTP
+ $otpLength = 4;
+
+ // Generate a random OTP with $otpLength digits
+ $otp = '';
+ for ($i = 0; $i < $otpLength; $i++) {
+ $otp .= rand(0, 9);
+ }
+ return $otp;
+ }
+}
}
diff --git a/app/Models/IamPrincipal.php b/app/Models/IamPrincipal.php
index 0847fce..d7d0c83 100644
--- a/app/Models/IamPrincipal.php
+++ b/app/Models/IamPrincipal.php
@@ -14,7 +14,7 @@ use App\Models\admin\ManageModule;
use App\Models\OrderedPassport;
-class IamPrincipal extends Model
+class IamPrincipal extends Authenticatable implements JWTSubject
{
use SoftDeletes;
use HasApiTokens, HasFactory, Notifiable;
diff --git a/app/Services/APIs/CustomerAPIs/AuthServices.php b/app/Services/APIs/CustomerAPIs/AuthServices.php
index 09106d0..5cc7922 100644
--- a/app/Services/APIs/CustomerAPIs/AuthServices.php
+++ b/app/Services/APIs/CustomerAPIs/AuthServices.php
@@ -1,10 +1,14 @@
input('age');
+ $age = $request->input('age');
if ($age == 'yes') {
return jsonResponseWithSuccessMessage(__('auth.legally_21'), 200);
} else {
@@ -33,7 +37,6 @@ class AuthServices
public function register($request)
{
- dd($request);
try {
DB::beginTransaction();
$user = IamPrincipal::create([
@@ -56,7 +59,7 @@ class AuthServices
'access_token' => $token,
'token_type' => 'bearer',
];
- return jsonResponseWithSuccessMessage(__('auth.Rest_user_created'), $response, 200);
+ return jsonResponseWithSuccessMessage(__('auth.Customer_user_created'), $response, 200);
} catch (QueryException $e) {
DB::rollBack();
Log::error('Restaurant Registration Failed ' . $e->getMessage());
@@ -64,4 +67,222 @@ class AuthServices
}
}
+ public function login($request)
+ {
+ try {
+ $credentials = [
+ 'email_address' => $request->email_address,
+ 'password' => $request->password,
+ ];
+
+ $isDelete = IamPrincipal::where('email_address', $request->email_address)->where('principal_type_xid', 3)->where('deleted_by_admin', 1)->onlyTrashed()->first();
+ if ($isDelete) {
+ return jsonResponseWithErrorMessageApi(__('auth.deleted_user_by_admin'), 403);
+ }
+ $isExistEmail = IamPrincipal::where('email_address', $request->email_address)->where('principal_type_xid', 3)->whereNull('deleted_at')->first();
+ if ($isExistEmail == null) {
+ return jsonResponseWithErrorMessageApi(__('auth.incorrect_email_passport'), 403);
+ }
+ if ($isExistEmail && !(Hash::check($request->password, $isExistEmail->password))) {
+ Log::error('Entered Password is wrong.');
+ return jsonResponseWithErrorMessageApi(__('auth.incorrect_email_passport'), 403);
+ }
+
+ if (!$token = auth()->login($isExistEmail)) {
+ Log::error('Customer Login Failed');
+ return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
+ }
+
+ $isExistEmail->one_signal_player_id = $request->one_signal_player_id;
+ $isExistEmail->save();
+ $response = [
+ 'userId' => $isExistEmail->id,
+ 'access_token' => $token,
+ ];
+
+ return jsonResponseWithSuccessMessage(__('auth.data_fetched_successfully'), $response, 200);
+ } catch (QueryException $e) {
+ Log::error('Customer Login Failed ' . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
+ }
+ }
+
+
+ public function forgotPassword($request)
+ {
+ try {
+ DB::beginTransaction();
+
+ $user = IamPrincipal::where('email_address', $request->email_address)->where('principal_type_xid', 3)->whereNull('deleted_at')->first();
+ if ($user == null) {
+ Log::error('Email not exist');
+ return jsonResponseWithErrorMessageApi(__('auth.incorrect_email'), 403);
+ }
+
+ $otp = generateOTP();
+
+ IamPrincipalOTP::updateOrCreate(
+ ['principal_xid' => $user->id],
+ [
+ 'otp_code' => $otp,
+ 'otp_purpose' => 'forgot password',
+ 'valid_till' => Carbon::now()->addMinutes(2),
+ 'is_used' => 0,
+ ]
+ );
+
+ $mail = Mail::send(
+ 'frontend.Mail.customer_forgot_password_mail',
+ [
+ 'user' => $user,
+ 'otp_code' => $otp,
+ 'valid_till' => Carbon::now()->addMinutes(2)
+ ],
+ function ($message) use ($user) {
+ $message->to($user->email_address);
+ $message->subject('Forgot Password Mail Page');
+ }
+ );
+
+
+ DB::commit();
+ Log::info('Customer Forgot Password otp sent successfully');
+
+ $response = [
+ 'iam_principal_xid' => $user->id,
+ ];
+
+
+ return jsonResponseWithSuccessMessageApi(__('auth.otp_sent_successfully'), $response, 200);
+ } catch (QueryException $e) {
+ DB::rollBack();
+
+ Log::error('Customer Forgot password Failed ' . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
+ }
+ }
+
+
+ public function verifyOTPForgotPassword($request)
+ {
+ try {
+ DB::beginTransaction();
+ $User = IamPrincipal::where('email_address', $request->email_address)->where('principal_type_xid', 3)->whereNull('deleted_at')->first();
+
+ $iamPrincipal = IamPrincipalOTP::where('principal_xid', $User->id)->first();
+
+ if (!$iamPrincipal) {
+ Log::error('User not exist');
+ return jsonResponseWithErrorMessageApi(__('auth.failed_to_verify_otp'), 403);
+ }
+
+ if ($iamPrincipal->otp_code !== $request->otp) {
+ Log::error('Customer entered invalid otp');
+ return jsonResponseWithErrorMessageApi(__('auth.invalid_otp'), 403);
+ }
+
+ if (Carbon::now()->gt($iamPrincipal->valid_till)) {
+
+ Log::error('Customer otp Exipred');
+ return jsonResponseWithErrorMessageApi(__('auth.otp_expired'), 403);
+ }
+
+ if ($iamPrincipal->is_used === 1) {
+ Log::error('Customer otp Already used');
+ return jsonResponseWithErrorMessageApi(__('auth.otp_already_used'), 403);
+ }
+
+ $iamPrincipal->is_used = 1;
+ $iamPrincipal->save();
+ DB::commit();
+ $response = [
+ 'iam_principal_xid' => $User->id
+ ];
+ Log::info('Customer OTP verified successfully');
+ return jsonResponseWithSuccessMessageApi(__('auth.otp_verified'), $response, 200);
+ } catch (QueryException $e) {
+ DB::rollBack();
+ Log::error('Customer verify otp Failed ' . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
+ }
+ }
+
+
+
+ public function changePassword($request)
+ {
+ try {
+ DB::beginTransaction();
+ $User = IamPrincipal::find($request->iam_principal_xid);
+ $User->password = Hash::make($request->password);
+ $User->save();
+ DB::commit();
+ return jsonResponseWithSuccessMessageApi(__('auth.password_updated_successfully'));
+
+ } catch (QueryException $e) {
+ DB::rollBack();
+ Log::error('Customer change password Failed ' . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
+ }
+ }
+
+
+ public function resendOtp($request)
+ {
+ try {
+ DB::beginTransaction();
+ $iamPrincipal = IamPrincipalOTP::where('principal_xid', $request->iam_principal_xid)->first();
+ $user = IamPrincipal::where('id', $request->iam_principal_xid)->first();
+
+ if (!$iamPrincipal) {
+ return response()->json('OTP not found for this user.', 203);
+ }
+
+ $allowedResendInterval = Carbon::now()->subMinutes(2);
+
+ if ($iamPrincipal->updated_at >= $allowedResendInterval) {
+
+ return jsonResponseWithErrorMessageApi(__('auth.try_resend_otp'), 429);
+ }
+
+ $otp = generateOTP();
+
+ $iamPrincipal->principal_xid = $request->iam_principal_xid;
+ $iamPrincipal->otp_code = $otp;
+ $iamPrincipal->otp_purpose = $request->otp_purpose;
+ $iamPrincipal->valid_till = Carbon::now()->addMinutes(2);
+ $iamPrincipal->is_used = 0;
+ $iamPrincipal->save();
+
+
+
+ $mail = Mail::send(
+ 'frontend.Mail.customer_forgot_password_mail',
+ [
+ 'user' => $user,
+ 'otp_code' => $otp,
+ 'valid_till' => Carbon::now()->addMinutes(2)
+ ],
+ function ($message) use ($user) {
+ $message->to($user->email_address);
+ $message->subject('Forgot Password Mail Page');
+ }
+ );
+
+
+ DB::commit();
+
+ $response = [
+ 'iam_principal_xid' => $iamPrincipal->principal_xid,
+ 'email_address' => $user->email_address
+
+ ];
+
+ return jsonResponseWithSuccessMessageApi(__('auth.otp_resend_sent_successfully'), $response, 200);
+ } catch (QueryException $e) {
+ DB::rollBack();
+ Log::error('Resend otp Failed ' . $e->getMessage());
+ return jsonResponseWithErrorMessageApi(__('auth.authentication_failed'), 403);
+ }
+ }
}
diff --git a/config/app.php b/config/app.php
index f467267..3cb6d56 100644
--- a/config/app.php
+++ b/config/app.php
@@ -1,5 +1,9 @@
env('APP_URL', 'http://localhost'),
+ 'asset_url' => env('ASSET_URL'),
+
/*
|--------------------------------------------------------------------------
@@ -78,34 +84,42 @@ return [
|
*/
- 'locale' => env('APP_LOCALE', 'en'),
+ 'locale' => 'en',
- 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
- 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'),
+
+ 'fallback_locale' => 'en',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Faker Locale
+ |--------------------------------------------------------------------------
+ |
+ | This locale will be used by the Faker PHP library when generating fake
+ | data for your database seeds. For example, this will be used to get
+ | localized telephone numbers, street address information and more.
+ |
+ */
+
+
+ 'faker_locale' => 'en_US',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
- | This key is utilized by Laravel's encryption services and should be set
- | to a random, 32 character string to ensure that all encrypted values
- | are secure. You should do this prior to deploying the application.
+ | This key is used by the Illuminate encrypter service and should be set
+ | to a random, 32 character string, otherwise these encrypted strings
+ | will not be safe. Please do this before deploying an application!
|
*/
- 'cipher' => 'AES-256-CBC',
-
'key' => env('APP_KEY'),
- 'previous_keys' => [
- ...array_filter(
- explode(',', env('APP_PREVIOUS_KEYS', ''))
- ),
- ],
+ 'cipher' => 'AES-256-CBC',
- /*
+ /*
|--------------------------------------------------------------------------
| Maintenance Mode Driver
|--------------------------------------------------------------------------
@@ -119,8 +133,61 @@ return [
*/
'maintenance' => [
- 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),
- 'store' => env('APP_MAINTENANCE_STORE', 'database'),
+ 'driver' => 'file',
+ // 'store' => 'redis',
],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Autoloaded Service Providers
+ |--------------------------------------------------------------------------
+ |
+ | The service providers listed here will be automatically loaded on the
+ | request to your application. Feel free to add your own services to
+ | this array to grant expanded functionality to your applications.
+ |
+ */
+
+ 'providers' => ServiceProvider::defaultProviders()->merge([
+ /*
+ * Package Service Providers...
+ */
+
+ /*
+ * Application Service Providers...
+ */
+ App\Providers\AppServiceProvider::class,
+ // App\Providers\AuthServiceProvider::class,
+ // Barryvdh\DomPDF\ServiceProvider::class,
+ // App\Providers\BroadcastServiceProvider::class,
+ // App\Providers\EventServiceProvider::class,
+ App\Providers\RouteServiceProvider::class,
+ Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
+ // Ladumor\OneSignal\OneSignalServiceProvider::class,
+ // Maatwebsite\Excel\ExcelServiceProvider::class,
+
+ ])->toArray(),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Class Aliases
+ |--------------------------------------------------------------------------
+ |
+ | This array of class aliases will be registered when this application
+ | is started. However, feel free to register as many as you wish as
+ | the aliases are "lazy" loaded so they don't hinder performance.
+ |
+ */
+
+ 'aliases' => Facade::defaultAliases()->merge([
+ // 'Example' => App\Facades\Example::class,
+ 'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
+ 'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
+ // 'OneSignal' => \Ladumor\OneSignal\OneSignal::class,
+ // 'PDF' => Barryvdh\DomPDF\Facade::class,
+ // 'Excel' => Maatwebsite\Excel\Facades\Excel::class,
+
+ ])->toArray(),
+
];
diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php
index f60c6e6..2f88e3e 100644
--- a/resources/lang/en/auth.php
+++ b/resources/lang/en/auth.php
@@ -87,6 +87,7 @@ return [
'passport_search' => 'Passport Search successfully',
'not_found_otp' => 'OTP not found for this user',
'Rest_user_created' => 'Restaurant user created successfully',
+ 'Customer_user_created' => 'Customer user created successfully',
'User_details_fetch' => 'User details fetch successfully',
'Voucher_not_found' => 'Voucher not found',
'delete_user' => 'Customer deleted successfully',
diff --git a/resources/views/frontend/Mail/customer_forgot_password_mail.blade.php b/resources/views/frontend/Mail/customer_forgot_password_mail.blade.php
new file mode 100644
index 0000000..a86b7d8
--- /dev/null
+++ b/resources/views/frontend/Mail/customer_forgot_password_mail.blade.php
@@ -0,0 +1,217 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{--  }}) --}}
+
+ |
+
+
+
+
+
+
+ One-Time Password (OTP) for verification
+
+ {{ 'Dear ' . $user->first_name }}
+
+ Your verification code is
+ {{ $otp_code }}.
+
+ The otp is valid for 2 minutes
+
+ |
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
diff --git a/routes/customer_api.php b/routes/customer_api.php
index 681ef92..bf90acf 100644
--- a/routes/customer_api.php
+++ b/routes/customer_api.php
@@ -14,6 +14,10 @@ Route::post('/v1/register', [AuthController::class, 'register']);
Route::post('/v1/login', [AuthController::class, 'login']);
Route::post('/v1/forgot-password', [AuthController::class, 'forgotPassword']);
Route::post('/v1/password/verify-otp', [AuthController::class, 'verifyOtpForgotPassword']);
+Route::post('/v1/change-password', [AuthController::class, 'changePassword']);
+Route::post('/v1/resend-otp', [AuthController::class, 'resendOtp']);
+
+// Route::group(['middleware' => ['customer.jwt.verify']], function () {
//*******************************************************CMS********************************************************
@@ -28,3 +32,6 @@ Route::get('/v1/list-of-news-articles', [CMSApiController::class, 'getNewsArticl
// });
+
+// });
+