pluginever / wc-serial-numbers

The best WordPress Plugin to sell license keys, redeem cards and other secret numbers!
11 stars 12 forks source link

Optionally disable encryption when saving keys #385

Open gmn42 opened 1 year ago

gmn42 commented 1 year ago

In some applications, such as tracking of true serial numbers on physical products, database encryption of the numbers provides no benefit and makes troubleshooting and other operations such as db queries more difficult. This patch provides an option to disable encryption when saving serial numbers (a.k.a. "serial keys"). Existing encrypted keys are still read correctly.

A side benefit is that sub-string searches of the numbers works correctly when they are not encrypted (issue #381 ), and numbers are sorted correctly in the list when that column is chosen.

Warning: Previously saved keys will NOT be de-crypted when the option is changed, and it is possible save un-encrypted numbers that match the existing encrypted version, EVEN IF the "no duplicates" option is enabled. Therefore, a method for en/de-crypting the entire table when the option is changed should be developed before using this in production code. Obviously, this is not a concern if starting with an empty table.

For internal use, I use the following function to change the database state after changing the option. It is VERY inefficient, and takes a minute or so to run with around 1800 keys. It takes too much time and memory to run synchronously when the option is changed, and running it asynchronously via schedule_event has been unreliable and has potential for race conditions if the option is changed more than once quickly. Therefore, I run it manually from the shell using wp eval 'wcsn_resave_keys();'. Obviously, this is not a production solution; hopefully the WCSN team knows of a better approach! (Also, make sure you don't have any keys that start with a . character before using this!)

function wcsn_resave_keys() {

    $all_keys = WooCommerceSerialNumbers\Models\Key::query(['limit' => -1]);

    foreach($all_keys as $key) {
        $serial_key = $key->get_serial_key();

        if(substr($serial_key, 0, 1) == '.') {  // Clean up any aborted changes from previous run
            $key->set_serial_key(substr($serial_key, 1));
            $key->save();
        } else {

        // Save twice to poison write cache - re-saving with the same number doesn't work
            $key->set_serial_key('.' . $serial_key, 1);
            $key->save();
            $key->set_serial_key($serial_key);
            $key->save();
        }
    }
}