How to test the token revocation for Laravel Passport with PestPHP?

I have followed this answer for logging out from a Laravel Passport API. I would like to test the method I have written, but I keep bumping into this SQL error when running sail pest tests/Feature/Http/Controllers/AuthenticationControllerTest.php:

SQLSTATE[HY000]: General error: 1364 Field 'id' doesn't have a default value (Connection: mysql, SQL: insert into `oauth_access_tokens` (`scopes`, `revoked`, `updated_at`, `created_at`) values (["*"], 1, 2024-03-25 09:08:38, 2024-03-25 09:08:38))

I expected to receive:

Logged out succesfully.

This is the test I have written (in Pest):

// AuthenticationControllerTest.php

it('can logout', function () {
    $this->seed();
    $this->user    = User::first();
    Passport::actingAs($this->user, ['*']);

    $response = $this->postJson('api/v1/logout');

    $response
        ->assertJson([
            'message' => 'Logged out successfully.',
        ])->assertStatus(200);
});

the api definition:

// api.php

Route::post('logout', [AuthenticationController::class, 'logout']);

and here is the controller method itself:

// AuthenticationController.php

public function logout(Request $request): ?IlluminateHttpJsonResponse
    {
        if (Auth::user() && $request->user() instanceof User && $request->user()->token() instanceof LaravelPassportToken) {
            $token = Auth::user()->token();
            $token->revoke();
            return response()->json([
                'message' => 'Logged out successfully.',
            ], 200);
        }
        return null;
    }

I suspect it has something to do with the Token class using forceFill to revoke the token, while it doesn’t exist yet in the test, and the migration hasn’t set a default id for the token. Why does it not exist in the test? It works perfectly outside of the testing environment…

Thanks for helping!

PHP SSE , data not shown properly

i tried to create my own SSE using php and js, but don’t receive data each second instead,
get all data after 1min , OR my browser create each 5 second new request :

PHP : (https://github.com/mdn/dom-examples/blob/main/server-sent-events/index.html)

        header("X-Accel-Buffering: no");
        header("Content-Type: text/event-stream");
        header("Cache-Control: no-cache");

        $counter = rand(1, 10); // a random counter
        while (1) {
            // 1 is always true, so repeat the while loop forever (aka event-loop)

            $curDate = date(DATE_ISO8601);
            echo "event: pingn",
            'data: {"time": "' . $curDate . '"}', "nn";

            // Send a simple message at random intervals.

            $counter--;

            if (!$counter) {
                echo 'data: This is a message at time ' . $curDate, "nn";
                $counter = rand(1, 10); // reset random counter
            }

            // flush the output buffer and send echoed messages to the browser

            while (ob_get_level() > 0) {
                ob_end_flush();
            }
            flush();

            // break the loop if the client aborted the connection (closed the page)

            if (connection_aborted()) break;

            // sleep for 1 second before running the loop again

            sleep(1);
        }

JS :

var source = new EventSource("sse2");
  source.onmessage = function (event) {
    console.log(event.data);
  };

2 Results :
enter image description here

enter image description here

any advise to fix that.

Hierarchical roles for a user, with child roles having different permissions on case based, Laravel Spatie

In the application I am trying to build, I have two portals one for Admins and one for Users. As in a normal case scenario, I might have different Roles for the Admin portal, i.e., Super Admin, Admin, etc. and for the User Portal, I just have a User Role for now.

Now a user can create and join many group chats, and in each chat, the user can either be the Group Admin, a Group assistant, a normal participant or a spectator. Moreover, a group chat admin can allow or prevent users with a specific role to perform a specific action. for example, a group chat admin can prevent users with a normal participant role from typing in the group chat. Also the admin can choose to prevent a specific user from performing a specific action.

So a user should have a user role in order to join or create group chats, and can obtain a different sub role per group chat and different roles horizontally across different group chats.
Is this possible with spatie/laravel-permission package?

What has been tried yet:

So far, I added few tables and logic that makes the work, but I think there are better approaches.

  1. I’ve added the possible group chat roles in the roles table, i.e., group_admin, group_assistant, group_participant, etc. along with the super_admin, admin, and user roles. I gave the group chat roles the default permissions that they usually have.

  2. I created a group_chat_users table with a group_chat_id, user_id, and role_id. here the role_id should be limited to only the group chat roles. So that we assign each a user a role by group chat

  3. I created an additional table along side to Spatie’s Permissions tables, which is, revoked_model_permission_roles that has the columns: model_type, model_id, revoked_type, revoked_id, and permission_id.
    In here, we have the corresponding model_type and model_id, in my case the group_chat and the group_chat_id. I also have have the revoked_type and revoked_id, which represents the model has been revoked which could be in this case either the whole Role (hence role as the revoked_type and role_id as the revoked_id) or the specific user (user model as revoked_type and user_id as revoked_id). And finally the permission column which states the permission that has been revoked for this User or Role.

  4. I created a group chat policy where I check if the user, with a group chat role, has the corresponding permission to perform the action, which I check from the default role_has_permissions table of spatie, and if the permission has been revoked, which I check from the other the table that I created which is revoked_model_permission_roles.

Encrypt and Decrypt File Using PHP

I want to decrypt file with extention .txt .docx .xlsx and .pdf from uploading file.

encrypt.php

<?php
  include "koneksi.php";
  function generateKeyPairFromFileName(){
    $config = array(
      "default_md" => "sha512",
      "private_key_bits" => 512,
      "private_key_type" => OPENSSL_KEYTYPE_RSA,
    );

    $keypair = openssl_pkey_new($config);

    if (!$keypair) {
      die("Failed to generate key pair");
    }

    openssl_pkey_export($keypair, $privateKey, null, $config);
    $publicKey = openssl_pkey_get_details($keypair);
    $publicKey = $publicKey['key'];

    return array(
      'publicKey' => $publicKey,
      'privateKey' => $privateKey
    );
  }

  function savePublicKeyToLocal($publicKey, $fileName) {
    $publicKeyPath = $fileName . '_public_key.pem'; // Ganti dengan lokasi penyimpanan kunci publik Anda
    file_put_contents($publicKeyPath, $publicKey);
    return $publicKeyPath;
  }

  // Fungsi untuk menyimpan kunci pribadi ke file lokal
  function savePrivateKeyToLocal($privateKey, $fileName) {
    $privateKeyPath = $fileName . '_private_key.pem'; // Ganti dengan lokasi penyimpanan kunci pribadi Anda
    file_put_contents($privateKeyPath, $privateKey);
    return $privateKeyPath;
  }

// Fungsi untuk mengenkripsi file menggunakan AES
function encryptFile($data, $key) {
  // Buat vektor inisialisasi (IV) acak
  $iv = openssl_random_pseudo_bytes(16);

  // Enkripsi data menggunakan AES-256-CBC dengan kunci dan IV yang diberikan
  $encryptedData = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);

  // Base64 encode hasil enkripsi
  $encryptedDataBase64 = base64_encode($encryptedData);

  // Simpan atau kirim data terenkripsi ke tempat penyimpanan atau penerima
  // echo "Data terenkripsi: " . $encryptedDataBase64;

  return $encryptedDataBase64;
}

  if(isset($_POST['generate'])){
    $uploadedFileName = $_FILES['file']['name'];
    $filetmp = $_FILES['file']['tmp_name'];

    // Membaca isi file
    $fileContent = file_get_contents($filetmp);

    $KeyPair = generateKeyPairFromFileName();
    
    $publicKeyPath = savePublicKeyToLocal($KeyPair['publicKey'], $uploadedFileName);
    $publicKeyPath = savePrivateKeyToLocal($KeyPair['privateKey'], $uploadedFileName);

    $encryptedFileContent = encryptFile($fileContent, $KeyPair['publicKey']);
    // echo $encryptedFileContent;

    $query = "INSERT INTO upload (nama_file, filedata) VALUES ('$uploadedFileName', '$encryptedFileContent')";
    if (mysqli_query($conn, $query)) {
        echo "File berhasil diunggah dan dienkripsi.";
    } else {
        echo "Gagal mengunggah dan menyimpan file ke database: " . mysqli_error($conn);
    }


  }
?>

<form action="" method="post" enctype="multipart/form-data">
        Pilih file untuk diunggah (PDF, DOCX, XLSX, TXT, maks 15 MB):
  <input type="file" name="file">
  <button name="generate" type="submit">Generate</button>
</form>

I save the private and public key on local. The script above is for encrypt data before save on the database.

ecnrypt.php

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include "koneksi.php";

// Fungsi dekripsi
function decryptFile($data, $key) {
  // Decode data terenkripsi dari base64
  $encryptedData = base64_decode($data);

  // Ambil IV dari data terenkripsi
  $iv = openssl_random_pseudo_bytes(16);

  $decryptedData = openssl_decrypt($encryptedData, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);

  // Kembalikan data yang telah didekripsi
  return $decryptedData;
}

if(isset($_GET['nama_file'])){
  // Nama file
  $fileName = $_GET['nama_file'];

  // Membaca kunci privat
  try {
    $privateKeyPath = $fileName . '_private_key.pem';
    if (!file_exists($privateKeyPath)) {
      throw new Exception("File kunci privat tidak ditemukan: " . $privateKeyPath);
    }

    $privateKey = file_get_contents($privateKeyPath);
  } catch (Exception $e) {
    echo "Gagal membaca kunci privat: " . $e->getMessage();
    exit;
  }

  // Mengambil data file terenkripsi dari database
  $query = "SELECT filedata FROM upload WHERE nama_file = '$fileName'";
  $result = mysqli_query($conn, $query);

  if ($result && mysqli_num_rows($result) > 0) {
    $row = mysqli_fetch_assoc($result);

    // Dekripsi data
    $decryptedData = decryptFile($row['filedata'], $privateKey);

    // Tampilkan data yang telah didekripsi
    echo $decryptedData;
  } else {
    echo "File tidak ditemukan!";
  }
}

The file that i want to decrypt is empty. i mean return empty on decrypted data. is anyone have same problem ?

Expecting file with decrypted data.

How to get timezone based on phone country code in php

In my project : User is register by phone number and phone country code. Once they will register then I want to store that user time zone in database.

For example : User is register using this
phone number 78548956..
phone country code +91

then I want to store user time zone (UTC +5:30) in database.

IS there any api or script or function for fetch time zone using country code (+91 etc ..)?

I have directly created new table using country code and time zone for it. and once user will register in system then I am checking country code in that new table and fetching time zone according to match in db. But I don’t want to create new table. if there have any other way then please suggest me.

push notifications with CURL on PWA application with PHP

I am working on a PWA web application.
I already completed the code on the browser side.

On the server side I use PHP and I have the following information:

$publicKey = '123456789...';
$privateKey = 'abcdefg....';

$subscription = '{"endpoint":"https://fcm.googleapis.com/fcm/send/eCCP-Bu3sXQ:APA91bFbbjw....","expirationTime":null,"keys":{"p256dh":"BIwBDcsp.....","auth":"RKGkA...."}}';

Now I would like to send a push notification to the user. I prefer to use CURL over Web Push library as I do not want to install additional packages on the server.

My php code so far is

$url = 'https://fcm.googleapis.com/fcm/send';
    
$fields = array('to' => $user, 
                'notification' => array('title' => 'My title', 
                                        'body' => $body_of_message, 
                                        'click_action' => 'https://www.website.com/', 
                                        'icon'=> 'https://www.website.com/icon.png'
                               ), 
            'priority' => 10
            );
        
$headers = array('Authorization:key = ??????',
                 'Content-Type: application/json'
        );
      
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$output = curl_exec($ch);

question: how do I generate the VAPID code ? how do I properly encrypt the message? How do I calculate the Authorization:key? Does anyone has a tutorial/code that can help me ?

Thank you 🙂

Woocommerce default Account registeration form return white screen

in default registration page in woocommerce (/my-account/?action=register) when send post method request to /my-account/?action=register without create customer return white screen.

for tracking problem i need know which functions execute by woocommerce register form submit (Account page).
by deafult woocommerce where create new customer when register form submited ?

thanks

calculate report failed redis keys empty but exists

I have a function like this using Laravel lumen framework:

// Define sample payment transactions
$transactions = [
  ['transaction_id' => 1, 'amount' => 100, 'status' => 'success', 'payment_method' => 'credit_card', 'timestamp' => time()],
  ['transaction_id' => 2, 'amount' => 150, 'status' => 'success', 'payment_method' => 'paypal', 'timestamp' => time()],
  ['transaction_id' => 3, 'amount' => 200, 'status' => 'failed', 'payment_method' => 'credit_card', 'timestamp' => time()],
  ['transaction_id' => 4, 'amount' => 200, 'status' => 'failed', 'payment_method' => 'credit_card', 'timestamp' => time()],
  ['transaction_id' => 5, 'amount' => 200, 'status' => 'failed', 'payment_method' => 'credit_card', 'timestamp' => time()],
];

// Store sample transactions in Redis
foreach ($transactions as $transaction) {
  try {
    Redis::hmset("transaction:{$transaction['transaction_id']}", $transaction);
  } catch (Exception $e) {
    // Log any errors or exceptions
    IlluminateSupportFacadesLog::error("Error storing transaction in Redis: " . $e->getMessage());
  }
}


// Generate report by payment method
// Define payment methods
$paymentMethods = ['credit_card', 'paypal', 'bank_transfer']; // Add more payment methods as needed

// Initialize report array
$report = [];

// Calculate total amount and count for each payment method
foreach ($paymentMethods as $method) {
  $transactions = Redis::keys("transaction:*:payment_method:{$method}"); // on this keys why show an empty 

  // Check if $transactions is an array before counting
  $totalAmount = 0;
  $totalCount = count($transactions);

  foreach ($transactions as $key) {
    $data = Redis::hgetall($key);
    $totalAmount += $data['amount'];
  }


  $report[] = [
    'payment_method' => $method,
    'total_amount' => $totalAmount,
    'total_count' => $totalCount,
  ];
}

return response()->json($report);

I need to handle much of the data and store the data to Redis so I can consume the cache data.
My goal is I just want to calculate the report by payment method but when I used Redis::keys(“transaction:*:payment_method:{$method}”) the value show an empty.

Parsing WSDL: Couldn’t load from https

I have a PHP code that allows me to connect to a webservice:

<?php

$client = new SoapClient("https://ws.chronopost.fr/shipping-cxf/ShippingServiceWS?wsdl");

?>

When I do it, I get the error
"Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://ws.chronopost.fr/shipping-cxf/ShippingServiceWS?wsdl' : failed to load external entity "https://ws.chronopost.fr/shipping-cxf/ShippingServiceWS?wsdl" in C:..."

I have an old web server running PHP 5.3.9. In the PHP.ini saop is activated:

enter image description here

If I open the page https://ws.chronopost.fr/shipping-cxf/ShippingServiceWS?wsdl on a server browser, it works correctly.

What is the cause of the error?
Thanks for your help,

How to fix non-numeric values error or find such non-numeric values in MySQL database? [duplicate]

I’m adding localisation to currencies, dates, and numbers in a project I’m continuously developing. However, when added number formatting using PHP’s NumberFormatter class, I get Warning: A non-numeric value encountered in....

This supposedly means that a non-numeric value was stored in my database. I’m not sure how this is possible since the respective column is decimal(11,20) but there’s no other explanation I can find. I must note that the quantity column used to be VARCHAR until a few years ago, when I switched it to DECIMAL, but I haven’t seen any errors or warnings before this.

Here’s the PHP code that throws the error:

$num = new NumberFormatter('en_UK', NumberFormatter::DECIMAL);
...
$units_quantity = $num->format($units_row['units_sum']);
...

if(isset($units_total[$year][$units_unit])) {
    $units_total[$year][$units_unit] += $units_quantity; /* THIS LINE */
}
else {
    $units_total[$year][$units_unit] = $units_quantity;
}

If I amend the PHP code above by casting the number as floatval like so:

 $units_total[$year][$units_unit] += floatval($units_quantity);

I still get two non-numeric value warnings – but now the calculations are incorrect. There are a total of thirteen warnings before the change.

To try and find the non-numeric value in MySQLL, I tried these queries, both returning zero rows:

SELECT projectID, projectName, quantity FROM project_data WHERE quantity REGEXP '[a-zA-Z]';

SELECT projectID, projectName, quantity FROM project_data WHERE quantity REGEXP '^[^0-9]+$';

I hope you can point me in the right direction. Let me know if I can provide any additional details.

Afrihost Database Issues

I have been trying to use a linux server with afrihost to save data from an HTML form to a database.
If anyone knows how to do this it would be much appreciated.
I have now resorted to using a text file to save user data which I know is not a good safety practice. But I still cannot even get the text file to save the data.

Preferably I would like to get the afrihost database working but if we cannot then I would like to securely save the data in a text file if possible.

https://chat.openai.com/share/efd5ad8f-ac47-4233-a26e-8b4f4f1dce41

This is my chat with chatGPT about my issues including how I tried to fix it with “Inspect” and the developer tab

https://chat.openai.com/share/efd5ad8f-ac47-4233-a26e-8b4f4f1dce41

Please refer to this to see my issues

Warm regards