From 575379adc009545652e2349a6885c3b93a25f3a0 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sun, 19 Nov 2023 17:14:39 +0800 Subject: [PATCH] centralize izyim exchange --- .../ControllersLogic/CreateCustomerLogic.php | 31 ++++++- .../LoginThroughExchangeLogic.php | 83 +++++++++++++++++++ .../RegisterOnExchangeProcessor.php | 43 ++++++++++ ...thenticationTokenWithExchangeBookingId.php | 81 ++++++++++++++++++ .../ApproveIdentificationDocumentLogic.php | 27 +++++- .../CreateIdentificationDocumentLogic.php | 24 +++++- .../LinkExchangeCompanyLogic.php | 45 ++++++++++ ...ntificationDocumentOnExchangeProcessor.php | 46 ++++++++++ ...ntificationDocumentOnExchangeProcessor.php | 46 ++++++++++ .../LinkExchangeCompanyProcessor.php | 80 ++++++++++++++++++ .../ConnectCompanyModuleToExchangeCompany.php | 25 ++++++ .../Documents/Services/ApprovesDocument.php | 14 +++- .../Documents/Services/RejectsDocument.php | 16 +++- .../ControllersLogic/CreateOrderLogic.php | 28 ++++++- ...erToExchangeBookingOnExchangeProcessor.php | 46 ++++++++++ .../ConnectOrderToExchangeBooking.php | 25 ++++++ .../LoginThroughExchangeController.php | 21 +++++ .../LinkExchangeCompanyController.php | 21 +++++ app/Http/Kernel.php | 2 + app/Http/Middleware/ValidateExchangeToken.php | 72 ++++++++++++++++ app/Models/CompanyModule.php | 9 ++ app/Models/ExchangeBookingOrder.php | 31 +++++++ app/Models/ExchangeCompanyConnection.php | 31 +++++++ ...ate_exchange_company_connections_table.php | 35 ++++++++ ...2_create_exchange_booking_orders_table.php | 34 ++++++++ .../accounts/forms/LoginFormComponent.vue | 13 +++ .../forms/RegistrationFormComponent.vue | 20 ++++- .../CustomerProfileSectionComponent.vue | 6 ++ .../orders/sections/OrderSectionComponent.vue | 4 +- .../validation/loginFormValidation.js | 6 +- .../validation/registrationFormValidation.js | 16 ++-- resources/assets/vue/general/mixins/guards.js | 23 ++++- .../assets/vue/vuex/modules/authentication.js | 8 +- routes/account.php | 1 + routes/api.php | 10 +++ 35 files changed, 991 insertions(+), 32 deletions(-) create mode 100644 app/Classes/Modules/Accounts/ControllersLogic/LoginThroughExchangeLogic.php create mode 100644 app/Classes/Modules/Accounts/Processors/RegisterOnExchangeProcessor.php create mode 100644 app/Classes/Modules/Accounts/Services/GeneratesAuthenticationTokenWithExchangeBookingId.php create mode 100644 app/Classes/Modules/Companies/ControllersLogic/LinkExchangeCompanyLogic.php create mode 100644 app/Classes/Modules/Companies/Processors/ApproveIdentificationDocumentOnExchangeProcessor.php create mode 100644 app/Classes/Modules/Companies/Processors/CreateIdentificationDocumentOnExchangeProcessor.php create mode 100644 app/Classes/Modules/Companies/Processors/LinkExchangeCompanyProcessor.php create mode 100644 app/Classes/Modules/Companies/Services/ConnectCompanyModuleToExchangeCompany.php create mode 100644 app/Classes/Modules/Orders/Processors/ConnectOrderToExchangeBookingOnExchangeProcessor.php create mode 100644 app/Classes/Modules/Orders/Services/ConnectOrderToExchangeBooking.php create mode 100644 app/Http/Controllers/Accounts/LoginThroughExchangeController.php create mode 100644 app/Http/Controllers/Companies/LinkExchangeCompanyController.php create mode 100644 app/Http/Middleware/ValidateExchangeToken.php create mode 100644 app/Models/ExchangeBookingOrder.php create mode 100644 app/Models/ExchangeCompanyConnection.php create mode 100644 database/migrations/2023_11_01_153205_create_exchange_company_connections_table.php create mode 100644 database/migrations/2023_11_17_154712_create_exchange_booking_orders_table.php diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php index 75b52ed1..3374a541 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php @@ -28,7 +28,8 @@ use App\Classes\ValueObjects\Constants\CompanyType; use App\Classes\ValueObjects\Constants\RoleTypes; use App\Classes\Jobs\CreatePerfexCRMCustomer; - +use App\Classes\Modules\Accounts\Processors\RegisterOnExchangeProcessor; +use App\Classes\Modules\Companies\Services\ConnectCompanyModuleToExchangeCompany; use App\Models\Company; use App\Models\CompanyModule; use App\Models\User; @@ -36,6 +37,7 @@ use App\Models\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; +use Illuminate\Support\Facades\Log; class CreateCustomerLogic extends AbstractControllerLogic { @@ -87,6 +89,12 @@ class CreateCustomerLogic extends AbstractControllerLogic /** @var CreatePerfexCRMLeadProcessor */ private $createPerfexCRMLeadProcessor; + /** @var RegisterOnExchangeProcessor */ + private $registerOnExchangeProcessor; + + /** @var ConnectCompanyModuleToExchangeCompany */ + private $connectCompanyModuleToExchangeCompany; + /** * CreateCustomerLogic constructor. * @param CreateUserProcessor $createUserProcessor @@ -101,8 +109,10 @@ class CreateCustomerLogic extends AbstractControllerLogic * @param GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor * @param FetchesCompanyModule $fetchesCompanyModule * @param CreatePerfexCRMLeadProcessor $createPerfexCRMLeadProcessor + * @param RegisterOnExchangeProcessor $registerOnExchangeProcessor + * @param ConnectCompanyModuleToExchangeCompany $connectCompanyModuleToExchangeCompany */ - public function __construct(CreateUserProcessor $createUserProcessor, CreateCompanyProcessor $createCompanyProcessor, CreateCompanyModuleProcessor $createCompanyModuleProcessor, CreateContactProcessor $createContactProcessor, CreatesCompanyConnection $createsCompanyConnection, ApprovesCompanyConnection $approvesCompanyConnection, AssignEmployeeProcessor $assignEmployeeProcessor, UploadIdentityDocumentProcessor $uploadIdentityDocumentProcessor, AuthenticationProcessor $authenticationProcessor, GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor, FetchesCompanyModule $fetchesCompanyModule, CreatePerfexCRMLeadProcessor $createPerfexCRMLeadProcessor) + public function __construct(CreateUserProcessor $createUserProcessor, CreateCompanyProcessor $createCompanyProcessor, CreateCompanyModuleProcessor $createCompanyModuleProcessor, CreateContactProcessor $createContactProcessor, CreatesCompanyConnection $createsCompanyConnection, ApprovesCompanyConnection $approvesCompanyConnection, AssignEmployeeProcessor $assignEmployeeProcessor, UploadIdentityDocumentProcessor $uploadIdentityDocumentProcessor, AuthenticationProcessor $authenticationProcessor, GenerateEmailVerificationAttemptProcessor $generateEmailVerificationAttemptProcessor, FetchesCompanyModule $fetchesCompanyModule, CreatePerfexCRMLeadProcessor $createPerfexCRMLeadProcessor, RegisterOnExchangeProcessor $registerOnExchangeProcessor, ConnectCompanyModuleToExchangeCompany $connectCompanyModuleToExchangeCompany) { $this->createUserProcessor = $createUserProcessor; $this->createCompanyProcessor = $createCompanyProcessor; @@ -116,6 +126,8 @@ class CreateCustomerLogic extends AbstractControllerLogic $this->generateEmailVerificationAttemptProcessor = $generateEmailVerificationAttemptProcessor; $this->fetchesCompanyModule = $fetchesCompanyModule; $this->createPerfexCRMLeadProcessor = $createPerfexCRMLeadProcessor; + $this->registerOnExchangeProcessor = $registerOnExchangeProcessor; + $this->connectCompanyModuleToExchangeCompany = $connectCompanyModuleToExchangeCompany; } /** @@ -153,7 +165,7 @@ class CreateCustomerLogic extends AbstractControllerLogic $this->assignEmployeeProcessor->execute($Object); - $this->uploadIdentityDocumentProcessor->execute($request, $company); + // $this->uploadIdentityDocumentProcessor->execute($request, $company); if(config('perfexcrm.is_enabled') == 'true'){ // $this->createPerfexCRMLeadProcessor->execute($request); @@ -169,6 +181,19 @@ class CreateCustomerLogic extends AbstractControllerLogic // $this->generateEmailVerificationAttemptProcessor->execute($user); + $exchangeCompanyId = null; + if ($request->input('exchange_company_id')) { + $exchangeCompanyId = $request->input('exchange_company_id'); + } else { + // register account on exchange portal if this registration not coming from exchange + $exchangeCompanyId = $this->registerOnExchangeProcessor->execute($request, $companyModule->id); + } + + if ($exchangeCompanyId) { + // create exchange company connection + $this->connectCompanyModuleToExchangeCompany->execute($companyModule, $exchangeCompanyId); + } + return $this->response($this->authenticationProcessor->execute($request)); } } diff --git a/app/Classes/Modules/Accounts/ControllersLogic/LoginThroughExchangeLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/LoginThroughExchangeLogic.php new file mode 100644 index 00000000..3b46deec --- /dev/null +++ b/app/Classes/Modules/Accounts/ControllersLogic/LoginThroughExchangeLogic.php @@ -0,0 +1,83 @@ + 'Authentication', + 'message' => 'You have successfully logged in to your account' + ]; + } + + /** @var AuthenticationProcessor */ + private $authenticationProcessor; + + /** @var GeneratesAuthenticationToken */ + private $generatesAuthenticationToken; + + /** @var GeneratesAuthenticationTokenWithExchangeBookingId */ + private $generatesAuthenticationTokenWithExchangeBookingId; + + + /** + * LoginThroughExchangeLogic constructor. + * @param AuthenticationProcessor $authenticationProcessor + * @param GeneratesAuthenticationToken $generatesAuthenticationToken + * @param GeneratesAuthenticationTokenWithExchangeBookingId $generatesAuthenticationTokenWithExchangeBookingId + */ + public function __construct(GeneratesAuthenticationToken $generatesAuthenticationToken, GeneratesAuthenticationTokenWithExchangeBookingId $generatesAuthenticationTokenWithExchangeBookingId) + { + $this->generatesAuthenticationToken = $generatesAuthenticationToken; + $this->generatesAuthenticationTokenWithExchangeBookingId = $generatesAuthenticationTokenWithExchangeBookingId; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\AccessUnauthorisedException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function logic(Request $request): JsonResponse { + + $token = explode('.', $request->input("exchangeToken"))[1]; + $decodedToken = base64_decode($token); + $exchangeUser = json_decode($decodedToken, true)['user']; + $exchangeCompanyId = $exchangeUser['company_id']; + $connection = ExchangeCompanyConnection::where("exchange_company_id", $exchangeCompanyId)->first(); + if (!$connection) { + throw new AccessUnauthorisedException('These credentials do not match our records.'); + } + $companyModule = $connection->companyModule; + $user = $companyModule->employees->last(); + + $exchangeBookingId = null; + if (isset($exchangeUser['booking_id']) && $exchangeUser['booking_id']) { + $exchangeBookingId = $exchangeUser['booking_id']; + $token = $this->generatesAuthenticationTokenWithExchangeBookingId->execute($user, $exchangeBookingId); + + return $this->response(['access_token' => $token, 'redirect_url' => route('dashboard') . "?createOrder=true"]); + } else { + $token = $this->generatesAuthenticationToken->execute($user); + $order = Order::where('id', $request->input("orderId"))->first(); + + return $this->response(['access_token' => $token, 'redirect_url' => route('order.show' , $order->reference)]); + } + + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Accounts/Processors/RegisterOnExchangeProcessor.php b/app/Classes/Modules/Accounts/Processors/RegisterOnExchangeProcessor.php new file mode 100644 index 00000000..edaa3e17 --- /dev/null +++ b/app/Classes/Modules/Accounts/Processors/RegisterOnExchangeProcessor.php @@ -0,0 +1,43 @@ + false]); + $formParams = $request->toArray(); + $formParams['shipping_company_module_id'] = $companyModuleId; + $response = $client->request('POST', $url, ['form_params' => $formParams]); + $body = $response->getBody(); + $contents = json_decode($body, true); + $payload = $contents['payload']; + $token = explode('.', $payload['access_token'])[1]; + $decodedToken = base64_decode($token); + $exchangeUser = json_decode($decodedToken, true)['user']; + + return $exchangeUser['company_id']; + } catch(\GuzzleHttp\Exception\RequestException $exception){ + Log::error($exception->getResponse()->getBody()->getContents()); + } + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Accounts/Services/GeneratesAuthenticationTokenWithExchangeBookingId.php b/app/Classes/Modules/Accounts/Services/GeneratesAuthenticationTokenWithExchangeBookingId.php new file mode 100644 index 00000000..6d07806c --- /dev/null +++ b/app/Classes/Modules/Accounts/Services/GeneratesAuthenticationTokenWithExchangeBookingId.php @@ -0,0 +1,81 @@ +builder = $builder; + } + + + /** + * @param User $user + * @param bool $rememberUser + * @return string + */ + public function execute(User $user, $bookingId): string { + + $this->builder->manager()->setBlacklistEnabled(false); + + // generate token for the customer + $this->builder->factory()->setTTL(Carbon::now()->addDay()->timestamp); + + // set the claim based on the object + $this->setTokenClaims($user, $bookingId); + + return $this->builder->fromUser($user); + } + + + /** + * @param User $user + */ + private function setTokenClaims(User $user, $bookingId): void { + + $claims = [ + 'id' => $user->id, + 'name' => $user->name, + 'email' => $user->email, + 'type' => $user->type, + 'status' => $user->status + ]; + + if($user->type === RoleTypes::USER) { + + /** @var Company $companyModule */ + $companyModule = $user->companyModule()->first(); + + $claims = array_merge($claims, [ + 'company_id' => $companyModule->company_id, + 'company_module_id' => $companyModule->id, + 'company_module_type' => $companyModule->type, + 'company_name' => $companyModule->name, + 'company_marking' => $companyModule->type !== 8 ? $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference : 'HWT', + 'exchange_booking_id' => $bookingId + ]); + } + + $this->builder->factory()->customClaims(['user' => $claims]); + + + $this->builder->factory()->buildClaimsCollection(); + } +} diff --git a/app/Classes/Modules/Companies/ControllersLogic/ApproveIdentificationDocumentLogic.php b/app/Classes/Modules/Companies/ControllersLogic/ApproveIdentificationDocumentLogic.php index 928a9c01..a094fee5 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/ApproveIdentificationDocumentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/ApproveIdentificationDocumentLogic.php @@ -10,16 +10,18 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Http\Resources\DocumentResource; use App\Classes\General\Abstracts\AbstractControllerLogic; - +use App\Classes\Modules\Companies\Processors\ApproveIdentificationDocumentOnExchangeProcessor; use App\Classes\Modules\Documents\Services\FetchesDocument; use App\Classes\Modules\Documents\Services\ApprovesDocument; use App\Classes\Modules\Notifications\DataTransferObjects\NotificationObject; Use App\Classes\Modules\Notifications\Processors\CreateNotificationProcessor; - +use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Document; +use App\Models\ExchangeCompanyConnection; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; class ApproveIdentificationDocumentLogic extends AbstractControllerLogic { @@ -55,6 +57,9 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic /** @var CreateNotificationProcessor */ private $createNotificationProcessor; + /** @var ApproveIdentificationDocumentOnExchangeProcessor */ + private $approveIdentificationDocumentOnExchangeProcessor; + /** * ApproveIdentificationDocumentLogic constructor. * @param CanApproveDocument $canApproveDocument @@ -64,8 +69,9 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic * @param UpdatesCompanyStatus $updatesCompanyStatus * @param UpdatesOrdersStatus $updatesOrdersStatus * @param CreateNotificationProcessor $createNotificationProcessor + * @param ApproveIdentificationDocumentOnExchangeProcessor $approveIdentificationDocumentOnExchangeProcessor */ - public function __construct(CanApproveDocument $canApproveDocument, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, FetchesDocument $fetchesDocument, UpdatesCompanyStatus $updatesCompanyStatus, UpdatesOrdersStatus $updatesOrdersStatus, CreateNotificationProcessor $createNotificationProcessor) + public function __construct(CanApproveDocument $canApproveDocument, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, FetchesDocument $fetchesDocument, UpdatesCompanyStatus $updatesCompanyStatus, UpdatesOrdersStatus $updatesOrdersStatus, CreateNotificationProcessor $createNotificationProcessor, ApproveIdentificationDocumentOnExchangeProcessor $approveIdentificationDocumentOnExchangeProcessor) { $this->canApproveDocument = $canApproveDocument; $this->approvesDocument = $approvesDocument; @@ -74,6 +80,7 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic $this->updatesCompanyStatus = $updatesCompanyStatus; $this->updatesOrdersStatus = $updatesOrdersStatus; $this->createNotificationProcessor = $createNotificationProcessor; + $this->approveIdentificationDocumentOnExchangeProcessor = $approveIdentificationDocumentOnExchangeProcessor; } /** @@ -85,11 +92,18 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { + $documentId = $request->route('document_id'); + + if ($request->route('exchange_company_id')) { + $companyModule = ExchangeCompanyConnection::where('exchange_company_id', $request->route('exchange_company_id'))->first()->companyModule; + $company = $companyModule->company; + $documentId = $company->documents()->whereIn('document_type', DocumentType::IDENTIFICATION_DOCUMENTS)->where('status', ApprovalStatus::PENDING_VERIFICATION)->first()->id; + } $status = $request->route('status'); /** @var Document $document */ - $document = $this->fetchesDocument->execute(['id' => $request->route('document_id')]); + $document = $this->fetchesDocument->execute(['id' => $documentId]); $this->canApproveDocument->passes(); @@ -111,6 +125,11 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic $orders = $this->updatesOrdersStatus->execute($document->owner, ApprovalStatus::APPROVED); } + // if this request is not calling from exchange portal, then approve the document on exchange portal for this user + $companyModule = $document->owner->companyModules()->first(); + if (!$request->route('exchange_company_id') && $companyModule->exchangeCompanyConnection()->first()) { + $this->approveIdentificationDocumentOnExchangeProcessor->execute($request, $companyModule->id, $status); + } return $this->resourceResponse(new DocumentResource($document)); diff --git a/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php b/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php index bbf91ea7..c691d032 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php @@ -4,6 +4,7 @@ namespace App\Classes\Modules\Companies\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\Modules\Companies\Processors\CreateIdentificationDocumentOnExchangeProcessor; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Companies\Services\UpdatesCompanyStatus; use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; @@ -14,6 +15,7 @@ use App\Classes\ValueObjects\Constants\CompanyType; use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Company; use App\Models\Document; +use App\Models\ExchangeCompanyConnection; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -42,6 +44,9 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic /** @var UpdatesCompanyStatus */ private $updatesCompanyStatus; + /** @var CreateIdentificationDocumentOnExchangeProcessor */ + private $createIdentificationDocumentOnExchangeProcessor; + /** * CreateIdentificationDocumentLogic constructor. @@ -49,13 +54,15 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic * @param CreatesDocument $createsDocument * @param CreatesFiles $createsFile * @param UpdatesCompanyStatus $updatesCompanyStatus + * @param CreateIdentificationDocumentOnExchangeProcessor $createIdentificationDocumentOnExchangeProcessor */ - public function __construct(FetchesCompany $fetchesCompany, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesCompanyStatus $updatesCompanyStatus) + public function __construct(FetchesCompany $fetchesCompany, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesCompanyStatus $updatesCompanyStatus, CreateIdentificationDocumentOnExchangeProcessor $createIdentificationDocumentOnExchangeProcessor) { $this->fetchesCompany = $fetchesCompany; $this->createsDocument = $createsDocument; $this->createsFile = $createsFile; $this->updatesCompanyStatus = $updatesCompanyStatus; + $this->createIdentificationDocumentOnExchangeProcessor = $createIdentificationDocumentOnExchangeProcessor; } /** @@ -66,8 +73,15 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic public function logic(Request $request) : JsonResponse { + if ($request->route('exchange_company_id')) { + $companyModule = ExchangeCompanyConnection::where('exchange_company_id', $request->route('exchange_company_id'))->first()->companyModule; + $companyId = $companyModule->company_id; + } else { + $companyId = $request->route('id'); + } + /** @var Company $company */ - $company = $this->fetchesCompany->execute(['id' => $request->route('id')]); + $company = $this->fetchesCompany->execute(['id' => $companyId]); $object = new DocumentObject($company->type === CompanyType::COMPANY_BUSINESS ? DocumentType::SSM_REGISTRATION : DocumentType::IDENTITY_CARD, $request->input('files'), $request->input('identification_no'), ApprovalStatus::PENDING_VERIFICATION, 'identifications'); @@ -78,6 +92,12 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic $this->updatesCompanyStatus->execute($company, ApprovalStatus::PENDING_VERIFICATION); + // create identification on exchange if this request not coming from exchange + $companyModule = $company->companyModules()->first(); + if (!$request->route('exchange_company_id') && $companyModule->exchangeCompanyConnection()->first()) { + $this->createIdentificationDocumentOnExchangeProcessor->execute($request, $companyModule->id); + } + return $this->response([]); } diff --git a/app/Classes/Modules/Companies/ControllersLogic/LinkExchangeCompanyLogic.php b/app/Classes/Modules/Companies/ControllersLogic/LinkExchangeCompanyLogic.php new file mode 100644 index 00000000..535244b0 --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/LinkExchangeCompanyLogic.php @@ -0,0 +1,45 @@ + 'Connect Exchange with Izyim Account', + 'message' => 'You have successfully connect your exchange account to Izyim Account' + ]; + } + + /** @var LinkExchangeCompanyProcessor */ + private $linkExchangeCompanyProcessor; + + + /** + * LinkExchangeCompanyLogic constructor. + * @param LinkExchangeCompanyProcessor $linkExchangeCompanyProcessor + */ + public function __construct(LinkExchangeCompanyProcessor $linkExchangeCompanyProcessor) + { + $this->linkExchangeCompanyProcessor = $linkExchangeCompanyProcessor; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\AccessUnauthorisedException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function logic(Request $request): JsonResponse { + + return $this->response($this->linkExchangeCompanyProcessor->execute($request)); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Companies/Processors/ApproveIdentificationDocumentOnExchangeProcessor.php b/app/Classes/Modules/Companies/Processors/ApproveIdentificationDocumentOnExchangeProcessor.php new file mode 100644 index 00000000..b8126c34 --- /dev/null +++ b/app/Classes/Modules/Companies/Processors/ApproveIdentificationDocumentOnExchangeProcessor.php @@ -0,0 +1,46 @@ + false]); + $token = $request->bearerToken(); + $headers = [ + 'Authorization' => 'Bearer ' . $token, + 'Accept' => 'application/json', + ]; + $formParams = $request->toArray(); + $response = $client->request('PUT', $url, [ + 'headers' => $headers, + 'form_params' => $formParams + ]); + $body = $response->getBody(); + $contents = json_decode($body, true); + + return $contents; + } catch(\GuzzleHttp\Exception\RequestException $exception){ + Log::error($exception->getResponse()->getBody()->getContents()); + } + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Companies/Processors/CreateIdentificationDocumentOnExchangeProcessor.php b/app/Classes/Modules/Companies/Processors/CreateIdentificationDocumentOnExchangeProcessor.php new file mode 100644 index 00000000..aa0ebffe --- /dev/null +++ b/app/Classes/Modules/Companies/Processors/CreateIdentificationDocumentOnExchangeProcessor.php @@ -0,0 +1,46 @@ + false]); + $token = $request->bearerToken(); + $headers = [ + 'Authorization' => 'Bearer ' . $token, + 'Accept' => 'application/json', + ]; + $formParams = $request->toArray(); + $response = $client->request('POST', $url, [ + 'headers' => $headers, + 'form_params' => $formParams + ]); + $body = $response->getBody(); + $contents = json_decode($body, true); + + return $contents; + } catch(\GuzzleHttp\Exception\RequestException $exception){ + Log::error($exception->getResponse()->getBody()->getContents()); + } + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Companies/Processors/LinkExchangeCompanyProcessor.php b/app/Classes/Modules/Companies/Processors/LinkExchangeCompanyProcessor.php new file mode 100644 index 00000000..d3bda7bf --- /dev/null +++ b/app/Classes/Modules/Companies/Processors/LinkExchangeCompanyProcessor.php @@ -0,0 +1,80 @@ +canAuthenticateUser = $canAuthenticateUser; + $this->authenticatesUser = $authenticatesUser; + $this->generatesAuthenticationToken = $generatesAuthenticationToken; + $this->fetchesUser = $fetchesUser; + $this->authenticationRedirect = $authenticationRedirect; + $this->connectCompanyModuleToExchangeCompany = $connectCompanyModuleToExchangeCompany; + } + + + /** + * @param Request $request + * @return array + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\AccessUnauthorisedException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function execute(Request $request): array { + + $object = new AuthenticationCredentialsObject($request->input('email'), $request->input('password')); + + $this->canAuthenticateUser->passes($object); + + $this->authenticatesUser->execute($object); + + $user = $this->fetchesUser->execute(['email' => $object->getEmail()]); + + $companyModule = $user->companyModule()->first(); + + $this->connectCompanyModuleToExchangeCompany->execute($companyModule, $request->route('exchange_company_id')); + + return ['shipping_company_module_id' => $companyModule->id]; + + } + +} diff --git a/app/Classes/Modules/Companies/Services/ConnectCompanyModuleToExchangeCompany.php b/app/Classes/Modules/Companies/Services/ConnectCompanyModuleToExchangeCompany.php new file mode 100644 index 00000000..cd548b36 --- /dev/null +++ b/app/Classes/Modules/Companies/Services/ConnectCompanyModuleToExchangeCompany.php @@ -0,0 +1,25 @@ +company_module_id = $companyModule->id; + $model->exchange_company_id = $exchangeCompanyId; + + return $this->handler($model); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Documents/Services/ApprovesDocument.php b/app/Classes/Modules/Documents/Services/ApprovesDocument.php index 9458774e..d9e32d3d 100644 --- a/app/Classes/Modules/Documents/Services/ApprovesDocument.php +++ b/app/Classes/Modules/Documents/Services/ApprovesDocument.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\Documents\Services; use App\Classes\General\Eloquent\AbstractUpdateRecord; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Models\Document; +use App\Models\User; use Carbon\Carbon; class ApprovesDocument extends AbstractUpdateRecord @@ -17,8 +18,19 @@ class ApprovesDocument extends AbstractUpdateRecord */ public function execute(Document $model) { + $user = Auth()->user(); + // if auth user is null, then this services is calling from exchange + if (!$user) { + $token = explode('.', request()->bearerToken())[1]; + $decodedToken = base64_decode($token); + $exchangeUser = json_decode($decodedToken, true)['user']; + $user = User::where('email', $exchangeUser['email'])->first(); + if (!$user) { + $user = User::find(1); + } + } $model->status = ApprovalStatus::APPROVED; - $model->approver = Auth()->user()->id; + $model->approver = $user->id; $model->approval_date = Carbon::now(); return $this->handler($model); diff --git a/app/Classes/Modules/Documents/Services/RejectsDocument.php b/app/Classes/Modules/Documents/Services/RejectsDocument.php index 4a7c7bfa..20d6c98a 100644 --- a/app/Classes/Modules/Documents/Services/RejectsDocument.php +++ b/app/Classes/Modules/Documents/Services/RejectsDocument.php @@ -5,7 +5,10 @@ namespace App\Classes\Modules\Documents\Services; use App\Classes\General\Eloquent\AbstractUpdateRecord; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Models\Document; +use App\Models\User; use Carbon\Carbon; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; class RejectsDocument extends AbstractUpdateRecord { @@ -17,8 +20,19 @@ class RejectsDocument extends AbstractUpdateRecord */ public function execute(Document $model) { + $user = Auth()->user(); + // if auth user is null, then this services is calling from exchange + if (!$user) { + $token = explode('.', request()->bearerToken())[1]; + $decodedToken = base64_decode($token); + $exchangeUser = json_decode($decodedToken, true)['user']; + $user = User::where('email', $exchangeUser['email'])->first(); + if (!$user) { + $user = User::find(1); + } + } $model->status = ApprovalStatus::REJECTED; - $model->approver = Auth()->user()->id; + $model->approver = $user->id; $model->approval_date = Carbon::now(); return $this->handler($model); diff --git a/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php index bd43006f..1c3ce29d 100644 --- a/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php +++ b/app/Classes/Modules/Orders/ControllersLogic/CreateOrderLogic.php @@ -7,8 +7,10 @@ use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Addresses\Services\FetchesAddress; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Companies\Services\FetchesCompanyModule; +use App\Classes\Modules\Orders\Processors\ConnectOrderToExchangeBookingOnExchangeProcessor; use App\Classes\Modules\PerfexCRM\Processors\NewLeadTaskToPerfexCRMProcessor; use App\Classes\Modules\Orders\Processors\CreateOrderProcessor; +use App\Classes\Modules\Orders\Services\ConnectOrderToExchangeBooking; use App\Classes\Modules\Orders\Services\GeneratesOrderNumber; use App\Classes\ValueObjects\Constants\WarehouseReferences; use App\Http\Resources\OrderResource; @@ -43,6 +45,13 @@ class CreateOrderLogic extends AbstractControllerLogic /** @var NewLeadTaskToPerfexCRMProcessor */ private $newLeadTaskToPerfexCRMProcessor; + + /** @var ConnectOrderToExchangeBooking */ + private $connectOrderToExchangeBooking; + + /** @var ConnectOrderToExchangeBookingOnExchangeProcessor */ + private $connectOrderToExchangeBookingOnExchangeProcessor; + /** * CreateOrderLogic constructor. * @param FetchesCompany $fetchesCompany @@ -51,8 +60,10 @@ class CreateOrderLogic extends AbstractControllerLogic * @param FetchesCompanyModule $fetchesCompanyModule * @param GeneratesOrderNumber $generatesOrderNumber * @param NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor + * @param ConnectOrderToExchangeBooking $connectOrderToExchangeBooking + * @param ConnectOrderToExchangeBookingOnExchangeProcessor $connectOrderToExchangeBookingOnExchangeProcessor */ - public function __construct(FetchesCompany $fetchesCompany, FetchesAddress $fetchesAddress, CreateOrderProcessor $createOrderProcessor, FetchesCompanyModule $fetchesCompanyModule, GeneratesOrderNumber $generatesOrderNumber, NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor) + public function __construct(FetchesCompany $fetchesCompany, FetchesAddress $fetchesAddress, CreateOrderProcessor $createOrderProcessor, FetchesCompanyModule $fetchesCompanyModule, GeneratesOrderNumber $generatesOrderNumber, NewLeadTaskToPerfexCRMProcessor $newLeadTaskToPerfexCRMProcessor, ConnectOrderToExchangeBooking $connectOrderToExchangeBooking, ConnectOrderToExchangeBookingOnExchangeProcessor $connectOrderToExchangeBookingOnExchangeProcessor) { $this->fetchesCompany = $fetchesCompany; $this->fetchesAddress = $fetchesAddress; @@ -60,6 +71,8 @@ class CreateOrderLogic extends AbstractControllerLogic $this->fetchesCompanyModule = $fetchesCompanyModule; $this->generatesOrderNumber = $generatesOrderNumber; $this->newLeadTaskToPerfexCRMProcessor = $newLeadTaskToPerfexCRMProcessor; + $this->connectOrderToExchangeBooking = $connectOrderToExchangeBooking; + $this->connectOrderToExchangeBookingOnExchangeProcessor = $connectOrderToExchangeBookingOnExchangeProcessor; } @@ -97,6 +110,19 @@ class CreateOrderLogic extends AbstractControllerLogic $this->newLeadTaskToPerfexCRMProcessor->execute($company); } + $token = explode('.', $request->bearerToken())[1]; + $decodedToken = base64_decode($token); + $exchangeUser = json_decode($decodedToken, true)['user']; + $exchangeBookingId = null; + if (isset($exchangeUser['exchange_booking_id']) && $exchangeUser['exchange_booking_id']) { + $exchangeBookingId = $exchangeUser['exchange_booking_id']; + } + + if ($exchangeBookingId) { + $this->connectOrderToExchangeBooking->execute($order, $exchangeBookingId); + $this->connectOrderToExchangeBookingOnExchangeProcessor->execute($request, $order->id, $exchangeBookingId); + } + return $this->resourceResponse(new OrderResource($order)); } } diff --git a/app/Classes/Modules/Orders/Processors/ConnectOrderToExchangeBookingOnExchangeProcessor.php b/app/Classes/Modules/Orders/Processors/ConnectOrderToExchangeBookingOnExchangeProcessor.php new file mode 100644 index 00000000..63e81c58 --- /dev/null +++ b/app/Classes/Modules/Orders/Processors/ConnectOrderToExchangeBookingOnExchangeProcessor.php @@ -0,0 +1,46 @@ + false]); + $token = $request->bearerToken(); + $headers = [ + 'Authorization' => 'Bearer ' . $token, + 'Accept' => 'application/json', + ]; + $formParams = $request->toArray(); + $response = $client->request('POST', $url, [ + 'headers' => $headers, + 'form_params' => $formParams + ]); + $body = $response->getBody(); + $contents = json_decode($body, true); + + return $contents; + } catch(\GuzzleHttp\Exception\RequestException $exception){ + Log::error($exception->getResponse()->getBody()->getContents()); + } + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Orders/Services/ConnectOrderToExchangeBooking.php b/app/Classes/Modules/Orders/Services/ConnectOrderToExchangeBooking.php new file mode 100644 index 00000000..15a09c24 --- /dev/null +++ b/app/Classes/Modules/Orders/Services/ConnectOrderToExchangeBooking.php @@ -0,0 +1,25 @@ +order_id = $order->id; + $model->exchange_booking_id = $exchangeBookingId; + + return $this->handler($model); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Accounts/LoginThroughExchangeController.php b/app/Http/Controllers/Accounts/LoginThroughExchangeController.php new file mode 100644 index 00000000..c187d215 --- /dev/null +++ b/app/Http/Controllers/Accounts/LoginThroughExchangeController.php @@ -0,0 +1,21 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Companies/LinkExchangeCompanyController.php b/app/Http/Controllers/Companies/LinkExchangeCompanyController.php new file mode 100644 index 00000000..ea1af68d --- /dev/null +++ b/app/Http/Controllers/Companies/LinkExchangeCompanyController.php @@ -0,0 +1,21 @@ +execute($request); + } + +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index dc3bc265..c55ba9e3 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -2,6 +2,7 @@ namespace App\Http; +use App\Http\Middleware\ValidateExchangeToken; use App\Http\Middleware\ValidateToken; use Illuminate\Foundation\Http\Kernel as HttpKernel; @@ -69,6 +70,7 @@ class Kernel extends HttpKernel 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'valid.token' => ValidateToken::class, + 'valid.exchange.token' => ValidateExchangeToken::class, 'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class, ]; } diff --git a/app/Http/Middleware/ValidateExchangeToken.php b/app/Http/Middleware/ValidateExchangeToken.php new file mode 100644 index 00000000..31c0114a --- /dev/null +++ b/app/Http/Middleware/ValidateExchangeToken.php @@ -0,0 +1,72 @@ +manager = $manager; + $this->generatesAuthenticationToken = $generatesAuthenticationToken; + } + + + /** + * Checks if jwt token is valid. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + try { + + $token = explode('.', $this->manager->getToken())[1]; + $decodedToken = base64_decode($token); + $exchangeUser = json_decode($decodedToken, true)['user']; + if ($exchangeUser['type'] === 3) { + $exchangeCompanyId = $exchangeUser['company_id']; + $connection = ExchangeCompanyConnection::where("exchange_company_id", $exchangeCompanyId)->first(); + + Log::info($request->url()); + Log::info(route('api.exchange.company.connect' , $request->route('exchange_company_id'))); + + if(!$connection && $request->url() !== route('api.exchange.company.connect' , $request->route('exchange_company_id'))){ + throw new AccessUnauthorisedException(); + } + } + + } catch (Exception $exception) { + + return (new ApiResponseObject('Authentication', 'To keep your account secure we need to re-validate your account', HttpStatus::ACCESS_UNAUTHORISED))->handler(); + + } + + return $next($request); + } +} diff --git a/app/Models/CompanyModule.php b/app/Models/CompanyModule.php index 65e0a259..124fb6cb 100644 --- a/app/Models/CompanyModule.php +++ b/app/Models/CompanyModule.php @@ -24,6 +24,7 @@ use PhpParser\Node\Expr\AssignOp\Mod; use Staudenmeir\EloquentHasManyDeep\HasManyDeep; use Staudenmeir\EloquentHasManyDeep\HasRelationships; use App\Classes\General\Interfaces\Remarkable; +use Illuminate\Database\Eloquent\Relations\HasOne; /** * Class CompanyModule @@ -207,4 +208,12 @@ class CompanyModule extends AbstractModel implements Addressable, Documentable, { return $this->morphMany(Wallet::class, 'owner'); } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne + **/ + public function exchangeCompanyConnection(): HasOne + { + return $this->hasOne(ExchangeCompanyConnection::class, 'company_module_id', 'id'); + } } diff --git a/app/Models/ExchangeBookingOrder.php b/app/Models/ExchangeBookingOrder.php new file mode 100644 index 00000000..57eab09d --- /dev/null +++ b/app/Models/ExchangeBookingOrder.php @@ -0,0 +1,31 @@ +BelongsTo(Order::class, 'order_id', 'id'); + } + +} diff --git a/app/Models/ExchangeCompanyConnection.php b/app/Models/ExchangeCompanyConnection.php new file mode 100644 index 00000000..da8ddad8 --- /dev/null +++ b/app/Models/ExchangeCompanyConnection.php @@ -0,0 +1,31 @@ +BelongsTo(CompanyModule::class, 'company_module_id', 'id'); + } + +} diff --git a/database/migrations/2023_11_01_153205_create_exchange_company_connections_table.php b/database/migrations/2023_11_01_153205_create_exchange_company_connections_table.php new file mode 100644 index 00000000..a46f227a --- /dev/null +++ b/database/migrations/2023_11_01_153205_create_exchange_company_connections_table.php @@ -0,0 +1,35 @@ +id(); + $table->foreignId('company_module_id'); + $table->bigInteger('exchange_company_id')->unsigned()->index(); + $table->timestamps(); + $table->softDeletes(); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('exchange_company_connections'); + } +} diff --git a/database/migrations/2023_11_17_154712_create_exchange_booking_orders_table.php b/database/migrations/2023_11_17_154712_create_exchange_booking_orders_table.php new file mode 100644 index 00000000..35246c3a --- /dev/null +++ b/database/migrations/2023_11_17_154712_create_exchange_booking_orders_table.php @@ -0,0 +1,34 @@ +id(); + $table->foreignId('order_id'); + $table->bigInteger('exchange_booking_id')->unsigned()->index(); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('exchange_booking_orders'); + } +} diff --git a/resources/assets/vue/components/accounts/forms/LoginFormComponent.vue b/resources/assets/vue/components/accounts/forms/LoginFormComponent.vue index 153cf90f..d11853bb 100644 --- a/resources/assets/vue/components/accounts/forms/LoginFormComponent.vue +++ b/resources/assets/vue/components/accounts/forms/LoginFormComponent.vue @@ -59,6 +59,19 @@ currentUrl: window.location.href, }; }, + + created(){ + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const exchangeToken = urlParams.get('exchangeToken') + const orderId = urlParams.get('orderId'); + + if (exchangeToken) { + this.parameters.exchangeToken = exchangeToken; + this.parameters.orderId = orderId; + this.submit(this.route('api.account.authentication.authenticate.login_through_exchange'), 'post', this.section, false, false) + } + }, methods: { submitForm(){ this.submit(this.route('api.account.authentication.authenticate.attempt'), 'post', this.section, false, false) diff --git a/resources/assets/vue/components/accounts/forms/RegistrationFormComponent.vue b/resources/assets/vue/components/accounts/forms/RegistrationFormComponent.vue index 926af6de..d7ae04ac 100644 --- a/resources/assets/vue/components/accounts/forms/RegistrationFormComponent.vue +++ b/resources/assets/vue/components/accounts/forms/RegistrationFormComponent.vue @@ -60,7 +60,7 @@ -
+ +
+
+ + + + +
+
+ + + + +
@@ -187,7 +201,7 @@

Personal Information

-
+
diff --git a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue index 9f9dc3e0..892a577d 100644 --- a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue @@ -111,6 +111,12 @@ }, created(){ this.$store.dispatch('updateListQueue', {'name': this.section}); + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const createOrder = urlParams.get('createOrder'); + if (createOrder) { + this.$store.dispatch('toggleSection', {name: 'createOrderForm', status: true}) + } }, methods: { fetchCompany(){ diff --git a/resources/assets/vue/components/orders/sections/OrderSectionComponent.vue b/resources/assets/vue/components/orders/sections/OrderSectionComponent.vue index 23297089..d7423651 100644 --- a/resources/assets/vue/components/orders/sections/OrderSectionComponent.vue +++ b/resources/assets/vue/components/orders/sections/OrderSectionComponent.vue @@ -128,7 +128,7 @@
Identification Verification
-
+
@@ -146,7 +146,7 @@
- +
diff --git a/resources/assets/vue/general/mixins/accounts/validation/loginFormValidation.js b/resources/assets/vue/general/mixins/accounts/validation/loginFormValidation.js index 1cbc6fff..e533a59d 100644 --- a/resources/assets/vue/general/mixins/accounts/validation/loginFormValidation.js +++ b/resources/assets/vue/general/mixins/accounts/validation/loginFormValidation.js @@ -1,10 +1,10 @@ -import { required, email } from "vuelidate/lib/validators"; +import { required, email, requiredIf } from "vuelidate/lib/validators"; import authenticationHandler from '../authenticationHandler' export default { validations: { parameters: { - email: { required, email }, - password: { required } + email: { required: requiredIf(function () { return !window.location.search }), email }, + password: { required: requiredIf(function () { return !window.location.search }) } } }, mixins: [authenticationHandler] diff --git a/resources/assets/vue/general/mixins/accounts/validation/registrationFormValidation.js b/resources/assets/vue/general/mixins/accounts/validation/registrationFormValidation.js index 6f9b85f6..7866fe6c 100644 --- a/resources/assets/vue/general/mixins/accounts/validation/registrationFormValidation.js +++ b/resources/assets/vue/general/mixins/accounts/validation/registrationFormValidation.js @@ -4,7 +4,7 @@ export default { validations: { parameters: { name: { - required: requiredIf(function () { return this.step === 2 }) + required: requiredIf(function () { return this.step === 1 }) }, email: { required: requiredIf(function () { return this.step === 2 }), @@ -14,7 +14,7 @@ export default { required: requiredIf(function () { return this.parameters.type === 1 }) }, phone: { - required: requiredIf(function () { return this.step === 2 }), + required: requiredIf(function () { return this.step === 1 }), numeric }, // wechat_id: { @@ -27,12 +27,12 @@ export default { required: requiredIf(function () { return this.step === 2 }), sameAs: sameAs('password') }, - identification_no:{ - required - }, - files:{ - required - }, + // identification_no:{ + // required + // }, + // files:{ + // required + // }, } }, mixins: [authenticationHandler] diff --git a/resources/assets/vue/general/mixins/guards.js b/resources/assets/vue/general/mixins/guards.js index 9c9245e3..1794bc1d 100644 --- a/resources/assets/vue/general/mixins/guards.js +++ b/resources/assets/vue/general/mixins/guards.js @@ -1,6 +1,27 @@ export default { methods: { routesGuard(){ + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const exchangeToken = urlParams.get('exchangeToken'); + const orderId = urlParams.get('orderId'); + + // if login through exchange is true, we log the user out + if (localStorage.getItem('login-through-exchange') == 'true' && window.location.href == this.route('login')) { + localStorage.setItem('login-through-exchange', false); + this.$store.dispatch('userAuthentication', {access_token: '', redirect_url: '' }); + } + + // if exchange token presented, we log the user in and redirect to create order if order id is not presented + if (window.location.href.split('?')[0] == this.route('login') && exchangeToken) { + localStorage.setItem('login-through-exchange', true); + if (orderId) { + this.$store.dispatch('userAuthentication', {access_token: '', redirect_url: null }); + } else { + this.$store.dispatch('userAuthentication', {access_token: '', redirect_url: null }); + } + } + if(!this.$store.getters.isAuthenticated && this.isProtectedRoute()&& this.isWithTokenRoute()){ if(window.location.href.indexOf(this.route('feedback.customer')) !== 0){ window.location.href = window.location.href.indexOf(this.route('last_mile_delivery.login')) === 0 ? this.route('last_mile_delivery.login') : this.route('login') @@ -13,7 +34,7 @@ export default { if(window.location.href.indexOf(this.route('company.claim')) === 0) { return false; } - return !unprotectedRoutes.includes(window.location.href); + return !unprotectedRoutes.includes(window.location.href.split('?')[0]); }, isWithTokenRoute(){ const unprotectedRoutesWithToken = [this.route('account.password.reset')]; diff --git a/resources/assets/vue/vuex/modules/authentication.js b/resources/assets/vue/vuex/modules/authentication.js index d224bc0d..fadf98ea 100644 --- a/resources/assets/vue/vuex/modules/authentication.js +++ b/resources/assets/vue/vuex/modules/authentication.js @@ -77,9 +77,11 @@ export default { store.dispatch('toggleLoading', {name: 'loginSection', status: true}); - setTimeout(function(){ - window.location.href = redirect_url; - }, 2000); + if (redirect_url != null) { + setTimeout(function(){ + window.location.href = redirect_url; + }, 2000); + } }, updateToken(store, {access_token}){ diff --git a/routes/account.php b/routes/account.php index 20d9cf4f..86c374e3 100644 --- a/routes/account.php +++ b/routes/account.php @@ -12,6 +12,7 @@ Route::group(['prefix' => 'account', 'namespace' => 'Accounts', 'as' => 'account Route::group(['prefix' => 'authentication', 'as' => 'authentication.'], function () { Route::group(['prefix' => 'login', 'as' => 'authenticate.'], function () { Route::post('/attempt', 'UserAuthenticationController@authenticate')->name('attempt'); + Route::post('/login_through_exchange', 'LoginThroughExchangeController@authenticate')->name('login_through_exchange'); Route::post('/cross-attempt', 'UserCrossAuthenticationController@authenticate')->name('cross.attempt'); diff --git a/routes/api.php b/routes/api.php index 873d648c..4e9566f3 100644 --- a/routes/api.php +++ b/routes/api.php @@ -26,6 +26,16 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/feedback.php'; + Route::group(['middleware' => 'valid.exchange.token'], function () { + Route::group(['prefix' => 'exchange/company', 'as' => 'exchange.company.', 'namespace' => 'Companies'], function () { + Route::post('/{exchange_company_id}/connect', 'LinkExchangeCompanyController@authenticate')->name('connect'); + Route::group(['prefix' => '{exchange_company_id}/identification', 'as' => 'identification.'], function () { + Route::post('/create', 'CreateIdentificationDocumentController@create')->name('create'); + Route::put('/approval/{status}', 'ApproveIdentificationDocumentController@approve')->where('status', 'approve|reject')->name('approval'); + }); + }); + }); + Route::group(['middleware' => 'valid.token'], function () { Route::get('/storage/{fileName}/fetch', 'Documents\RenderDocumentController@fileStorageServe')->where(['fileName' => '.*'])->name('storage.document.file');