diff --git a/.env.example b/.env.example
index 696b7171..a75778c8 100644
--- a/.env.example
+++ b/.env.example
@@ -51,3 +51,5 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
UNITY_APP_URL="https://unity.izyim.com"
+EXCHANGE_URL=https://dev.exchange.cief-malaysia.com/
+MIX_EXCHANGE_URL="${EXCHANGE_URL}"
diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CrossAuthenticateUserLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CrossAuthenticateUserLogic.php
new file mode 100644
index 00000000..33bce845
--- /dev/null
+++ b/app/Classes/Modules/Accounts/ControllersLogic/CrossAuthenticateUserLogic.php
@@ -0,0 +1,44 @@
+ 'Cross Authentication',
+ 'message' => 'You have successfully logged in to your account'
+ ];
+ }
+
+ /** @var CrossAuthenticationProcessor */
+ private $crossAuthenticationProcessor;
+
+
+ /**
+ * CrossAuthenticateUserLogic constructor.
+ * @param CrossAuthenticationProcessor $authenticationProcessor
+ */
+ public function __construct(CrossAuthenticationProcessor $crossAuthenticationProcessor)
+ {
+ $this->crossAuthenticationProcessor = $crossAuthenticationProcessor;
+ }
+
+ /**
+ * @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->crossAuthenticationProcessor->execute($request));
+ }
+
+}
\ No newline at end of file
diff --git a/app/Classes/Modules/Accounts/DataTransferObjects/CrossAuthenticationCredentialsObject.php b/app/Classes/Modules/Accounts/DataTransferObjects/CrossAuthenticationCredentialsObject.php
new file mode 100644
index 00000000..67abf905
--- /dev/null
+++ b/app/Classes/Modules/Accounts/DataTransferObjects/CrossAuthenticationCredentialsObject.php
@@ -0,0 +1,43 @@
+access_token = $access_token;
+ $this->platform = $platform;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAccessToken(): string
+ {
+ return $this->access_token;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPlatform(): int
+ {
+ return $this->platform;
+ }
+}
\ No newline at end of file
diff --git a/app/Classes/Modules/Accounts/DataTransferObjects/UserSocialAccountObject.php b/app/Classes/Modules/Accounts/DataTransferObjects/UserSocialAccountObject.php
new file mode 100644
index 00000000..7740a04e
--- /dev/null
+++ b/app/Classes/Modules/Accounts/DataTransferObjects/UserSocialAccountObject.php
@@ -0,0 +1,54 @@
+app_id = $app_id;
+ $this->user = $user;
+ $this->platform = $platform;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAppId(): String
+ {
+ return $this->app_id;
+ }
+
+ /**
+ * @return User
+ */
+ public function getUser(): User
+ {
+ return $this->user;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPlatform(): int
+ {
+ return $this->platform;
+ }
+}
diff --git a/app/Classes/Modules/Accounts/Processors/CrossAuthenticationProcessor.php b/app/Classes/Modules/Accounts/Processors/CrossAuthenticationProcessor.php
new file mode 100644
index 00000000..5658f932
--- /dev/null
+++ b/app/Classes/Modules/Accounts/Processors/CrossAuthenticationProcessor.php
@@ -0,0 +1,211 @@
+canCrossAuthenticateUser = $canCrossAuthenticateUser;
+ $this->crossAuthenticatesUser = $crossAuthenticatesUser;
+ $this->generatesAuthenticationToken = $generatesAuthenticationToken;
+ $this->fetchesUser = $fetchesUser;
+ $this->authenticationRedirect = $authenticationRedirect;
+ $this->createUserProcessor = $createUserProcessor;
+ $this->createCompanyProcessor = $createCompanyProcessor;
+ $this->createContactProcessor = $createContactProcessor;
+ $this->createCompanyModuleProcessor = $createCompanyModuleProcessor;
+ $this->createsCompanyConnection = $createsCompanyConnection;
+ $this->createsCompanyConnection = $createsCompanyConnection;
+ $this->approvesCompanyConnection = $approvesCompanyConnection;
+ $this->assignEmployeeProcessor = $assignEmployeeProcessor;
+ $this->uploadIdentityDocumentProcessor = $uploadIdentityDocumentProcessor;
+ $this->createsUserSocialAccount = $createsUserSocialAccount;
+ }
+
+
+ /**
+ * @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 CrossAuthenticationCredentialsObject($request->input('access_token'), $request->input('platform'));
+
+ $this->canCrossAuthenticateUser->passes($object);
+
+ $cross = $this->crossAuthenticatesUser->execute($object);
+
+ $user_social_account = UserSocialAccount::where('app_id', $cross->token->user->id)->first();
+ if (!$user_social_account) {
+
+ $request->request->add([
+ 'name' => $cross->token->user->name,
+ 'email' => $cross->token->user->email,
+ 'password' => 'pass123',
+ 'password_confirmation' => 'pass123',
+ ]);
+
+ $user = $this->createUserProcessor->execute(
+ $request,
+ RoleTypes::USER,
+ env('APP_ENV') != 'production' ? ApprovalStatus::APPROVED : ApprovalStatus::PENDING_VERIFICATION
+ );
+
+ $company = $this->createCompanyProcessor->execute(
+ $cross->payload->data->name,
+ CompanyType::COMPANY_BUSINESS,
+ ApprovalStatus::PENDING_SUBMISSION
+ );
+
+ $contactObject = new ContactObject(
+ $cross->payload->data->contact->reference,
+ $cross->payload->data->contact->phone,
+ $cross->payload->data->contact->email,
+ $cross->payload->data->contact->wechat_id
+ );
+ $contact = $this->createContactProcessor->execute($contactObject, $company);
+
+ $companyModule = $this->createCompanyModuleProcessor->execute($company, BusinessType::IMPORTER);
+
+ $connectionObject = new CompanyConnectionObject(
+ $companyModule, 'CIEF',
+ mt_rand(1000, 9999).(new GeneratesInitials())->name($company->name)->length(3)->generate()
+ );
+ $connection = $this->createsCompanyConnection->execute($connectionObject);
+
+ $this->approvesCompanyConnection->execute($connection);
+
+ $object = new EmploymentObject($companyModule, $user);
+ $this->assignEmployeeProcessor->execute($object);
+
+ $request->request->add([
+ 'files' => [$cross->document->src],
+ 'identification_no' => $cross->payload->data->identification->reference,
+ ]);
+
+ $this->uploadIdentityDocumentProcessor->execute($request, $company);
+
+ $object = new UserSocialAccountObject(
+ $cross->token->user->id,
+ $user,
+ $request->input('platform')
+ );
+ $this->createsUserSocialAccount->execute($object);
+ }
+ else {
+ $user = $user_social_account->user()->first();
+ }
+
+ return ['access_token' => $this->generatesAuthenticationToken->execute($user), 'redirect_url' => $this->authenticationRedirect->url($user)];
+ }
+}
\ No newline at end of file
diff --git a/app/Classes/Modules/Accounts/Services/CreatesUserSocialAccount.php b/app/Classes/Modules/Accounts/Services/CreatesUserSocialAccount.php
new file mode 100644
index 00000000..a6fd8fcd
--- /dev/null
+++ b/app/Classes/Modules/Accounts/Services/CreatesUserSocialAccount.php
@@ -0,0 +1,24 @@
+user_id = $object->getUser()->id;
+ $model->app_id = $object->getAppId();
+ $model->platform = $object->getPlatform();
+ return $this->handler($model);
+
+ }
+}
\ No newline at end of file
diff --git a/app/Classes/Modules/Accounts/Services/CrossAuthenticatesUser.php b/app/Classes/Modules/Accounts/Services/CrossAuthenticatesUser.php
new file mode 100644
index 00000000..54835b17
--- /dev/null
+++ b/app/Classes/Modules/Accounts/Services/CrossAuthenticatesUser.php
@@ -0,0 +1,40 @@
+getPlatform() == PlatformType::EXCHANGE) {
+
+ $token = $object->getAccessToken();
+
+ $tokenParts = explode(".", $token);
+ $tokenPayload = base64_decode($tokenParts[1]);
+ $jwtPayload = json_decode($tokenPayload);
+
+ $response = Http::withToken($object->getAccessToken())->get(env('EXCHANGE_URL') . 'api/v1/company/' . $jwtPayload->user->company_id . '/show')->object();
+
+ $response_document = Http::withToken($object->getAccessToken())->get(env('EXCHANGE_URL') . 'api/v1/storage/' . $response->payload->data->identification->files[0]->file->file_info[0]->original->file . '/fetch')->object();
+ $response->token = $jwtPayload;
+ $response->document = $response_document->payload;
+ }
+
+ return $response;
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/Classes/Modules/Accounts/Services/FetchesUserSocialAccount.php b/app/Classes/Modules/Accounts/Services/FetchesUserSocialAccount.php
new file mode 100644
index 00000000..c2e1c676
--- /dev/null
+++ b/app/Classes/Modules/Accounts/Services/FetchesUserSocialAccount.php
@@ -0,0 +1,33 @@
+repository = $repository;
+ }
+
+
+ /**
+ * @return Builder
+ */
+ public function getRepository(): Builder
+ {
+ return $this->repository->newQuery();
+ }
+}
\ No newline at end of file
diff --git a/app/Classes/Modules/Accounts/Standards/Rules/CanCrossAuthenticateUser.php b/app/Classes/Modules/Accounts/Standards/Rules/CanCrossAuthenticateUser.php
new file mode 100644
index 00000000..115a7ea6
--- /dev/null
+++ b/app/Classes/Modules/Accounts/Standards/Rules/CanCrossAuthenticateUser.php
@@ -0,0 +1,54 @@
+userCrossAuthenticationValidation = $userCrossAuthenticationValidation;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function authorized(): bool
+ {
+ return true;
+
+ }
+
+
+ /**
+ * @param AuthenticationCredentialsObject $object
+ * @return bool
+ * @throws RequestValidationException
+ */
+ protected function validators($object): bool
+ {
+ return $this->userCrossAuthenticationValidation->validate($object);
+ }
+
+ /**
+ * @param AuthenticationCredentialsObject $object
+ * @return bool
+ */
+ protected function criteria($object): bool
+ {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/app/Classes/Modules/Accounts/Standards/Validators/UserCrossAuthenticationValidation.php b/app/Classes/Modules/Accounts/Standards/Validators/UserCrossAuthenticationValidation.php
new file mode 100644
index 00000000..ec170dc7
--- /dev/null
+++ b/app/Classes/Modules/Accounts/Standards/Validators/UserCrossAuthenticationValidation.php
@@ -0,0 +1,43 @@
+ $object->getAccesstoken(),
+ 'platform' => $object->getPlatform()
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ protected function rules(): array {
+ return [
+ 'access_token' => 'required',
+ 'platform' => 'required'
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ protected function messages(): array {
+ return [];
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/Classes/ValueObjects/Constants/PlatformType.php b/app/Classes/ValueObjects/Constants/PlatformType.php
new file mode 100644
index 00000000..d9ddd0e3
--- /dev/null
+++ b/app/Classes/ValueObjects/Constants/PlatformType.php
@@ -0,0 +1,9 @@
+execute($request);
+ }
+
+}
diff --git a/app/Models/UserSocialAccount.php b/app/Models/UserSocialAccount.php
new file mode 100644
index 00000000..71aa73d8
--- /dev/null
+++ b/app/Models/UserSocialAccount.php
@@ -0,0 +1,32 @@
+belongsTo(User::class, 'user_id', 'id');
+ }
+}
diff --git a/database/migrations/2021_09_01_212235_create_user_social_accounts_table.php b/database/migrations/2021_09_01_212235_create_user_social_accounts_table.php
new file mode 100644
index 00000000..612f47c6
--- /dev/null
+++ b/database/migrations/2021_09_01_212235_create_user_social_accounts_table.php
@@ -0,0 +1,35 @@
+id();
+ $table->foreignId('user_id');
+ $table->string('app_id')->nullable();
+ $table->integer('platform')->default(0);
+ $table->softDeletes();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('user_social_accounts');
+ }
+}
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index bba317e6..983c7aad 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -23,7 +23,7 @@ class DatabaseSeeder extends Seeder
$this->call(CountriesTableSeeder::class);
$this->call(CurrenciesTableSeeder::class);
- $this->call(CompaniesTableSeeder::class);
- $this->call(OrdersTableSeeder::class);
+ // $this->call(CompaniesTableSeeder::class);
+ // $this->call(OrdersTableSeeder::class);
}
}
\ No newline at end of file
diff --git a/resources/assets/vue/components/accounts/forms/CrossPlatformLoginFormComponent.vue b/resources/assets/vue/components/accounts/forms/CrossPlatformLoginFormComponent.vue
new file mode 100644
index 00000000..0634ddbe
--- /dev/null
+++ b/resources/assets/vue/components/accounts/forms/CrossPlatformLoginFormComponent.vue
@@ -0,0 +1,66 @@
+
+