• File: ApplicationController.php
  • Full Path: /var/www/imaliapi/app/Http/Controllers/ApplicationController.php
  • Date Modified: 08/23/2024 8:22 PM
  • File size: 8.58 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace App\Http\Controllers;

use App\Application;
use App\Classes\SendResponse;
use App\Store;
use App\Terminal;
use App\UserClient;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Webpatser\Uuid\Uuid;
use Spatie\Crypto\Rsa\KeyPair;
use Illuminate\Support\Facades\DB;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

class ApplicationController extends Controller
{
    //
    public function createApplication(Request $request)
    {
        // $this->validate(
        //     $request,
        //     [
        //         'name' => 'required',
        //         'description' => 'required',
        //         'dev_name' => 'required',
        //         'phone' => 'required',
        //         'email' => 'required',
        //         'route' => 'required',
        //         'technology' => 'required',
        //         'server' => 'required',
        //         'port' => 'required'
        //     ],
        //     [
        //         'name.required' => 'Campo Nome da Aplicação é obrigatorio',
        //         'description.required' => 'Campo description é obrigatorio',
        //         'dev_name.required' => 'Campo Nome do Programador é obrigatorio',
        //         'phone.required' => 'Campo Telefone é obrigatorio',
        //         'email.required' => 'Campo Email é obrigatorio',
        //         'route.required' => 'Campo Route é obrigatorio',
        //         'technology.required' => 'Campo technology é obrigatorio',
        //         'server.required' => 'Campo server é obrigatorio',
        //         'port.required' => 'Campo port é obrigatorio'
        //     ]
        // );
        [$privateKey, $publicKey] = (new KeyPair())->generate();

        try {


            DB::beginTransaction();
            //code...

            $fullUrlWithQuery = request()->fullUrl();

            $app = Application::create([
                'name' => $request->name,
                'description' => $request->description,
                'dev_name' => $request->dev_name,
                'phone' => $request->phone,
                'email' => $request->email,
                'route' => $fullUrlWithQuery,
                // 'public_key' => Str::orderedUuid(),
                'public_key' => $publicKey,
                'private_key' => $privateKey,
                'app_id' => substr(str_shuffle("0123456789"), 0, 15),
                'technology' => $request->technology,
                'server' => $request->server('SERVER_NAME'),
                'port' => $request->server('SERVER_PORT')
            ]);

            $token = $app->createToken('api_token')->plainTextToken;

            $app->update(['key' => $token]);

            DB::commit();

            // return response()->json(['message' => 'Dados criados com Sucesso', 'api_token' => $token, 'full_url' => $fullUrlWithQuery]);
            return response()->json(['message' => 'Dados criados com Sucesso']);
        } catch (\Throwable $th) {
            //throw $th;
            DB::rollBack();
            return response()->json(['message' => 'Nao foi possivel registar os dados', $th->getMessage()], 500);
        }
    }


    public function encryptString(Request $request)
    {
        // $publicKey = Storage::get('keys/public_key.pem');
        openssl_public_encrypt($request->api_key, $encryptedData, $request->publicKey);
        $base64EncodedData = base64_encode($encryptedData);
        return response()->json(['data' => $base64EncodedData]);

        // return base64_encode($encryptedData);

    }

    public function decryptString(Request $request)
    {
        // $privateKey = Storage::get('keys/private_key.pem');
        openssl_private_decrypt(base64_decode($request->encryptedData), $decryptedData, $request->privateKey);
        return $decryptedData;
    }


    //JWT METHODS
    public function encryptStringJWT(Request $request)
    {

        // Encode the array to a JWT string.
        $jwt = JWT::encode($request->all(), $request->api_key, 'HS256');
        return response()->json(['data' => $jwt]);

        // return base64_encode($encryptedData);

    }

    public function decryptStringJWT(Request $request)
    {
        $partners = UserClient::query()->select('client_key')->get();
        $decoded = $this->decryptToken($partners, $request->token);
        if (!$decoded) return SendResponse::errorResp401unauthenticated('Chave de cliente, invalida', 'Invalid Client Key');

        // return $decoded;
        return response()->json(['data' => $decoded]);
    }

    private function decryptToken($partners, $token)
    {
        $sizeOfclients = sizeof($partners);
        if ($sizeOfclients > 0) {

            foreach ($partners as $partner) {
                try {
                    return JWT::decode($token, new Key($partner->client_key, 'HS256'));
                } catch (\Throwable $th) {
                    continue;
                }
            }
        }
        return false;
    }

    // Associar a APPlication a Store
    public function applicationAssociate(Request $request)
    {
        $this->validate($request, [
            'store_account_number' => 'required',
            'application_id' => 'required',
        ], [
            'account_number.required' => 'campo store_account_number é de carácter obrigatório',
            'application_id.required' => 'Campo ID da Aplicação é de carácter obrigatório',
        ]);

        $store = Store::query()
            ->where('account_number', $request->store_account_number)
            ->first();

        if (!$store) return SendResponse::errorResp404notfound('Loja não encontrada', 'Store not found');

        $application = Application::query()
            ->where('app_id', $request->application_id)
            ->first();

        if (!$application) return SendResponse::errorResp404notfound('Aplicação não encontrada', 'Store not found');

        $checkAssociate = Application::query()
            ->where('app_id', $request->application_id)
            ->where('store_id', $store->id)
            ->first();

        if ($checkAssociate) {
            return response()->json(['message' => 'Está associação já esta associada!'], 400);
        } else {

            if ($application) {
                $application->update([
                    'store_id' => $store->id
                ]);

                return response()->json(['message' => 'Aplicação associada a loja'], 200);
            } else {
                return response()->json(['message' => 'Aplicação inválida'], 400);
            }
        }
    }

    // Get My Terminal
    public function getMyTerminals($account_number)
    {
        $store = Store::query()
            ->where('account_number', $account_number)
            ->first();

        if (!$store) return SendResponse::errorResp404notfound('Loja não encontrada', 'Store not found');

        $terminals = Terminal::query()
            ->select('name', 'description', 'status', 'created_at')
            ->where('store_id', $store->id)
            ->get();

        return response()->json(['data' => $terminals]);
    }


    public function createterminals(Request $request)
    {
        $this->validate($request, [
            'store_account_number' => 'required',
            'name' => 'required',
            'description' => 'required',
        ], [
            'account_number.required' => 'campo account_number é de carácter obrigatório',
            'name.required' => 'campo name é de carácter obrigatório',
            'description.required' => 'campo description é de carácter obrigatório',
        ]);

        $store = Store::query()
            ->where('account_number', $request->store_account_number)
            ->first();

        if (!$store) return SendResponse::errorResp404notfound('Loja não encontrada', 'Store not found');

        [$privateKey, $publicKey] = (new KeyPair())->generate();

        $app = Terminal::create([
            'name' => $request->name,
            'description' => $request->description,
            'public_key' => $publicKey,
            'private_key' => $privateKey,
            'store_id' => $store->id,
            'terminal_id' => substr(str_shuffle("0123456789"), 0, 30),
        ]);

        $token = $app->createToken('api_token')->plainTextToken;
        $app->update(['terminal_key' => $token]);

        return SendResponse::successResp200('Terminal criado com sucesso', 'Terminal successful created');
    }

    public function encryptTerminal(Request $request)
    {
        openssl_public_encrypt($request->api_key, $encryptedData, $request->publicKey);
        $base64EncodedData = base64_encode($encryptedData);
        return response()->json(['data' => $base64EncodedData]);
    }
}