Compare commits

..

3 Commits

Author SHA1 Message Date
Remo Zaros
d805477f4e Make sure prices show 2026-06-22 12:24:03 +02:00
Remo Zaros
e5e17cbafc swap session with cookie with hash 2026-06-22 09:34:14 +02:00
Remo Zaros
ba63181e6a Tried to set cookie 2026-06-13 18:06:26 +02:00
4 changed files with 183 additions and 59 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
wp-pppr-salt.php

137
pppr_cookie.php Normal file
View File

@@ -0,0 +1,137 @@
<?php
function create_pppr_salt() {
// 1. Check permissions first (Optional but recommended)
if ( ! wp_is_writable( plugin_dir_path( __FILE__ ) ) ) {
// Log error or handle failure
return false;
}
// 2. Define path INSIDE the plugin folder
$file_path = plugin_dir_path( __FILE__ ) . 'wp-pppr-salt.php';
// 3. Get the salt
$current_salt = wp_salt( 'auth' );
if ( empty( $current_salt ) ) {
return false;
}
// 4. Prepare content
$file_content = "<?php\n";
$file_content .= "// Auto-generated salt constant\n";
$file_content .= "// Exported salt from " . date( 'Y-m-d H:i:s' ) . "\n";
$file_content .= "define( 'WP_PPPR_SALT', '{$current_salt}' );\n";
// 5. Write the file
$bytes_written = file_put_contents( $file_path, $file_content, LOCK_EX );
// 6. Verify success
if ( $bytes_written === false ) {
// Handle error (e.g., log it)
return false;
}
return true;
}
function set_pppr_cookie($is_local, $street_name, $house_number, $postcode, $city) {
$data_string = (int)$is_local . "|" . $street_name . "|" . $house_number . "|" . $postcode . "|" . $city;
$signature = hash_hmac('sha256', $data_string, WP_PPPR_SALT);
$cookie_value = $data_string . "|" . $signature;
setcookie("PPPR", $cookie_value, [
'expires' => time() + 7200,
'path' => '/',
'domain' => $_SERVER['SERVER_NAME'],
'secure' => true, // Only send over HTTPS
'httponly' => true, // Prevent JavaScript access
'samesite' => 'Lax' // Protect against CSRF
]);
}
function unset_pppr_cookie( $path = '/') {
unset($_COOKIE["PPPR"]);
if (empty($domain)) {
setcookie("PPPR", '', time() - 3600, '/');
} else {
setcookie("PPPR", '', time() - 3600, '/' , $_SERVER['SERVER_NAME']);
}
}
function verify_pppr_cookie_string() {
if (!isset($_COOKIE['PPPR'])) {
return false;
}
$cookie_value = $_COOKIE['PPPR'];
$last_delimiter = strrpos($cookie_value, '|');
if ($last_delimiter === false) {
return false;
}
$data_part = substr($cookie_value, 0, $last_delimiter);
$hash_part = substr($cookie_value, $last_delimiter + 1);
// Check if salt is defined
if (!defined('WP_PPPR_SALT')) {
return false;
}
$expected_hash = hash_hmac('sha256', $data_part, WP_PPPR_SALT);
return hash_equals($expected_hash, $hash_part);
}
function get_PPPR_data() {
// 1. Check if cookie exists
if (!isset($_COOKIE['PPPR'])) {
return false;
}
$cookie_value = $_COOKIE['PPPR'];
// 2. Split safely using the LAST delimiter (handles pipes in street names)
$last_delimiter = strrpos($cookie_value, '|');
if ($last_delimiter === false) {
return false; // Malformed cookie
}
$data_part = substr($cookie_value, 0, $last_delimiter);
$provided_hash = substr($cookie_value, $last_delimiter + 1);
// 3. CRITICAL: Verify the signature before trusting ANY data
// Ensure WP_PPPR_SALT is defined and matches the setter exactly
if (!defined('WP_PPPR_SALT')) {
return false;
}
$expected_hash = hash_hmac('sha256', $data_part, WP_PPPR_SALT);
if (!hash_equals($expected_hash, $provided_hash)) {
return false; // Tampered or invalid cookie
}
// 4. Only now is it safe to explode the verified data
$fields = explode('|', $data_part);
// Ensure we have enough fields
if (count($fields) < 5) {
return false;
}
return [
'is_local' => (bool)$fields[0],
'street' => $fields[1],
'house_number' => $fields[2],
'postcode' => $fields[3],
'city' => $fields[4],
];
}
function pppr_is_local() {
$first_char = $_COOKIE['PPPR'][0];
return $first_char === '1';
}

View File

@@ -1,7 +1,5 @@
<?php
require_once plugin_dir_path(__FILE__) . "session_dialog.php";
require_once plugin_dir_path(__FILE__) . "admin.php";
/*
* Plugin Name: Prijzen per poscodeereeks.
* Description: Producten worden gefiltered aan de hand van opgegegeven postcodereksen.Klanten met een postcode Die in de opgegegeven postcode reeks vallen zullen een lokale prijs zien. Waar iedereen die niet in de reeks vallen de overige regios prijs te zien krijgt.
@@ -10,11 +8,23 @@ require_once plugin_dir_path(__FILE__) . "admin.php";
* Text Domeain: prijs-per-postcode
*/
require_once plugin_dir_path(__FILE__) . "session_dialog.php";
require_once plugin_dir_path(__FILE__) . "admin.php";
require_once plugin_dir_path(__FILE__) . "pppr_cookie.php";
if (!defined("ABSPATH")) {
echo "big bag of potatoes";
exit();
}
register_activation_hook( __FILE__, 'create_pppr_salt' );
if ( ! defined( 'WP_PPPR_SALT' ) ) {
$salt_file = ABSPATH . 'wp-pppr-salt.php';
if ( file_exists( $salt_file ) ) {
require_once $salt_file;
}
}
class PrijsPerPostcode
{
public function __construct()
@@ -25,17 +35,13 @@ class PrijsPerPostcode
public function init()
{
if (session_status() == PHP_SESSION_NONE) {
ob_start();
@session_start();
}
$uri = $_SERVER["REQUEST_URI"];
init_postcode_handlers($uri);
init_postode_admin();
add_filter("woocommerce_sale_flash", "__return_null");
//add_action("template_redirect", [$this, "redirect_if_missing_tag"]);
add_filter('woocommerce_show_variation_price', '__return_true');
add_action(
"woocommerce_variation_options_pricing",
[$this, "add_local_price_field"],
@@ -61,7 +67,7 @@ class PrijsPerPostcode
);
add_action("template_redirect", [
$this,
"controleer_postcode_op_woocommerce_paginas",
"check_postcode_on_every_woocommerce_page",
]);
add_filter(
"woocommerce_variation_is_visible",
@@ -75,6 +81,7 @@ class PrijsPerPostcode
99,
3,
);
}
public function add_local_price_field($loop, $variation_data, $variation)
@@ -118,8 +125,8 @@ class PrijsPerPostcode
if (
$variation_id &&
isset($_SESSION["postcode_is_local"]) &&
$_SESSION["postcode_is_local"]
isset($_COOKIE["PPPR"]) &&
pppr_is_local()
) {
$local_price = get_post_meta(
$variation_id,
@@ -133,7 +140,7 @@ class PrijsPerPostcode
}
}
public function controleer_postcode_op_woocommerce_paginas()
public function check_postcode_on_every_woocommerce_page()
{
if (is_admin() || defined("DOING_AJAX")) {
return;
@@ -141,14 +148,14 @@ class PrijsPerPostcode
if (
(is_product() ||
is_product_category() ||
is_product_tag() ||
is_cart() ||
is_checkout() ||
is_account_page()) &&
is_product_category() ||
is_product_tag() ||
is_cart() ||
is_checkout() ||
is_account_page()) &&
!is_shop()
) {
if (!isset($_SESSION["postcode_is_local"])) {
if (!verify_pppr_cookie_string()) {
wp_redirect(home_url("/winkel/"));
exit();
}
@@ -159,8 +166,8 @@ class PrijsPerPostcode
{
if (
$product->is_type("variation") &&
isset($_SESSION["postcode_is_local"]) &&
$_SESSION["postcode_is_local"] === true
isset($_COOKIE["PPPR"]) &&
pppr_is_local()
) {
$local_price = get_post_meta(
$product->get_id(),
@@ -189,10 +196,7 @@ class PrijsPerPostcode
return false;
}
$is_local = isset($_SESSION["postcode_is_local"])
? $_SESSION["postcode_is_local"]
: false;
$price = $is_local
$price = pppr_is_local()
? $variation->get_meta("_local_price", true)
: $variation->get_regular_price();

View File

@@ -5,7 +5,7 @@ function init_postcode_handlers($uri)
if (strpos($uri, "/winkel/") !== false) {
add_action("wp_enqueue_scripts", "modal_styles");
add_action("wp_footer", "send_postcode_data");
if (!has_postcode()) {
if (!verify_pppr_cookie_string()) {
if (!is_admin()) {
WC()->cart->empty_cart();
}
@@ -33,9 +33,9 @@ function show_modal()
{
echo <<<'HTML'
<script id="postcode_modal_open">
const postcodeModal = document.querySelector("#postcode_modal");
postcodeModal.showModal();
</script>
const postcodeModal = document.querySelector("#postcode_modal");
postcodeModal.showModal();
</script>
HTML;
}
@@ -185,14 +185,6 @@ function render_dialog_html()
HTML;
}
function has_postcode()
{
if (isset($_SESSION["postcode"])) {
return true;
}
return false;
}
function handle_postcode_modal($data)
{
$params = $data->get_params();
@@ -276,20 +268,17 @@ function handle_postcode_modal($data)
]);
exit();
}
// 6. Succes: Sessie opslaan & response
$_SESSION["postcode"] = $params["postcode"];
$_SESSION["huisnummer"] = $params["huisnummer"];
$_SESSION["straatnaam"] = $straatnaam;
$_SESSION["woonplaats"] = $woonplaats;
$_SESSION["postcode_is_local"] = postcode_in_range($params["postcode"]);
set_pppr_cookie(
postcode_in_range($params["postcode"]),
$straatnaam,
$params["huisnummer"],
$params["postcode"],
$woonplaats
);
echo json_encode([
"status" => "success",
"message" => "all good",
"straatnaam" => $straatnaam,
"woonplaats" => $woonplaats,
"lokaal_tarief" => postcode_in_range($params["postcode"]),
]);
exit();
}
@@ -396,15 +385,16 @@ function modify_checkout_with_js()
) {
return;
}
$data = get_PPPR_data();
$woonplaats = $_SESSION["woonplaats"];
$city = $data["city"];
$postcode = $formatted_postcode = preg_replace(
"/(\d+)([A-Z]+)/",
'$1 $2',
strtoupper($_SESSION["postcode"]),
strtoupper($data["postcode"]),
);
$address =
$_SESSION["straatnaam"] . " " . strtoupper($_SESSION["huisnummer"]);
$data["street"] . " " . strtoupper($data["house_number"]);
echo <<<HTML
<script type="text/javascript" id="fill_address_fields">
@@ -422,7 +412,7 @@ function modify_checkout_with_js()
last_name: '',
address_1: '{$address}',
address_2: '',
city: '{$woonplaats}',
city: '{$city}',
state: '',
postcode: '{$postcode}',
country: 'NL',
@@ -458,10 +448,6 @@ function modify_checkout_with_js()
HTML;
}
function load_assets_reset_postcode_on_checkout()
{
if (is_checkout() && !is_wc_endpoint_url()) {
@@ -494,11 +480,7 @@ function handle_unset_session_fetch()
if (!wp_verify_nonce($_POST["nonce"], "reset_postcode_nonce")) {
wp_die("Security check failed.");
}
// Unset the specific session variable
if (isset($_SESSION["postcode"])) {
$_SESSION = [];
}
unset_pppr_cookie();
// Send a JSON response
wp_send_json_success();