From b9fa2d21cdbc477a6bd13a1dced5bbc3393f4622 Mon Sep 17 00:00:00 2001 From: xrpbanks <126300068+xrpbanks@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:25:01 +0200 Subject: [PATCH 1/7] fix(wp): complete legal footer normalization --- wordpress-plugins/calorieapp-identity-bridge/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wordpress-plugins/calorieapp-identity-bridge/README.md b/wordpress-plugins/calorieapp-identity-bridge/README.md index c3c1c5d..4967313 100644 --- a/wordpress-plugins/calorieapp-identity-bridge/README.md +++ b/wordpress-plugins/calorieapp-identity-bridge/README.md @@ -25,7 +25,7 @@ The browser endpoint is intentionally not REST. XUMM Login establishes a normal Details are in SECURITY.md and CONFIGURATION.md. -Version 0.1.3 adds a narrowly scoped public-HTML compatibility layer that replaces obsolete legal footer labels left in cached Brizy output. It does not modify stored page, product, Tokenomics, payment, or authentication data. Version 0.1.2 adds a normal WordPress browser authorization handler for XUMM-authenticated sessions while retaining the REST exchange contract. Version 0.1.1 aligned state validation with the backend's signed v1 protocol +Version 0.1.4 completes the narrowly scoped public-HTML footer compatibility layer by normalizing the known legacy Brizy footer variants to the current operator, KVK, copyright, trademark, and tagline text. It does not modify stored page, product, Tokenomics, payment, or authentication data. Version 0.1.3 introduced the compatibility layer. Version 0.1.2 adds a normal WordPress browser authorization handler for XUMM-authenticated sessions while retaining the REST exchange contract. Version 0.1.1 aligned state validation with the backend's signed v1 protocol (timestamp, nonce, and HMAC-SHA256 signature) and supports an exact allowlisted external callback without requiring a separate WordPress redirect-host filter. From 60e825b605ff7b0c2a99476097cf76a9edcfa260 Mon Sep 17 00:00:00 2001 From: xrpbanks <126300068+xrpbanks@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:25:09 +0200 Subject: [PATCH 2/7] fix(wp): complete legal footer normalization --- wordpress-plugins/calorieapp-identity-bridge/TESTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wordpress-plugins/calorieapp-identity-bridge/TESTING.md b/wordpress-plugins/calorieapp-identity-bridge/TESTING.md index 49b4d97..bae285b 100644 --- a/wordpress-plugins/calorieapp-identity-bridge/TESTING.md +++ b/wordpress-plugins/calorieapp-identity-bridge/TESTING.md @@ -28,8 +28,9 @@ Covered scenarios: 20. backend state validation uses timestamp/nonce/HMAC headers 21. backend state validation does not transmit the shared secret 22. canonical WordPress REST root is documented for `/index.php/wp-json/` deployments -23. obsolete cached legal footer labels are replaced in rendered HTML -24. unrelated rendered HTML remains unchanged +23. known obsolete cached legal footer variants are normalized in rendered HTML +24. the current footer remains unchanged when the filter runs repeatedly +25. unrelated rendered HTML remains unchanged ## Files From 78c04966896b137ae24f184e6c495d04b8e9d945 Mon Sep 17 00:00:00 2001 From: xrpbanks <126300068+xrpbanks@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:25:18 +0200 Subject: [PATCH 3/7] fix(wp): complete legal footer normalization --- .../calorieapp-identity-bridge/calorieapp-identity-bridge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wordpress-plugins/calorieapp-identity-bridge/calorieapp-identity-bridge.php b/wordpress-plugins/calorieapp-identity-bridge/calorieapp-identity-bridge.php index 960dd7b..64fae77 100644 --- a/wordpress-plugins/calorieapp-identity-bridge/calorieapp-identity-bridge.php +++ b/wordpress-plugins/calorieapp-identity-bridge/calorieapp-identity-bridge.php @@ -3,7 +3,7 @@ * Plugin Name: CalorieApp Identity Bridge * Plugin URI: https://calorietoken.net * Description: Companion bridge plugin that maps authenticated WordPress/XUMM sessions to short-lived CalorieApp authorization codes. - * Version: 0.1.3 + * Version: 0.1.4 * Author: CalorieApp * License: GPL-2.0-or-later * License URI: https://www.gnu.org/licenses/gpl-2.0.html From 657c3ad2bfea9ad2aa0833d35de35f2f0ec5504a Mon Sep 17 00:00:00 2001 From: xrpbanks <126300068+xrpbanks@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:25:26 +0200 Subject: [PATCH 4/7] fix(wp): complete legal footer normalization --- ...tity-bridge-legal-footer-compatibility.php | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php b/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php index cd76a67..bb58cdc 100644 --- a/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php +++ b/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php @@ -15,10 +15,21 @@ * been rebuilt. */ class LegalFooterCompatibility { - private const LEGACY_OPERATOR_PATTERN = '/Chamber of Commerce KVK:\\s*[0-9]{8}/'; - private const CURRENT_OPERATOR = 'Operator: ICTHendrikse'; - private const LEGACY_COPYRIGHT = '© 2023 Calorie Token'; + private const FLEXIBLE_SPACE = '(?:\\s| | |\\x{00A0})*'; + private const LEGACY_OPERATOR_PATTERNS = [ + '/Chamber' . self::FLEXIBLE_SPACE . 'of' . self::FLEXIBLE_SPACE . 'Commerce' . self::FLEXIBLE_SPACE . 'KVK' . self::FLEXIBLE_SPACE . ':' . self::FLEXIBLE_SPACE . '[0-9]{8}/iu', + '/Calorie' . self::FLEXIBLE_SPACE . 'Token' . self::FLEXIBLE_SPACE . '(?:•|·|•|·)' . self::FLEXIBLE_SPACE . 'KvK' . self::FLEXIBLE_SPACE . ':?' . self::FLEXIBLE_SPACE . '[0-9]{8}/iu', + '/ICTHendrikse' . self::FLEXIBLE_SPACE . '(?:•|·|•|·)' . self::FLEXIBLE_SPACE . 'KvK' . self::FLEXIBLE_SPACE . ':?' . self::FLEXIBLE_SPACE . '73774693/iu', + '/Operator:' . self::FLEXIBLE_SPACE . 'ICTHendrikse(?!' . self::FLEXIBLE_SPACE . '(?:•|·|•|·)' . self::FLEXIBLE_SPACE . 'KVK)/iu', + ]; + private const CURRENT_OPERATOR = 'Operator: ICTHendrikse · KVK 73774693'; + private const LEGACY_COPYRIGHT_PATTERNS = [ + '/(?:©|©)' . self::FLEXIBLE_SPACE . '2023' . self::FLEXIBLE_SPACE . 'Calorie' . self::FLEXIBLE_SPACE . 'Token/iu', + '/(?:©|©)' . self::FLEXIBLE_SPACE . '2026' . self::FLEXIBLE_SPACE . 'CalorieToken(?!®)/iu', + ]; private const CURRENT_COPYRIGHT = '© 2026 ICTHendrikse (owned content only) · CalorieToken® trade mark: Pieter Hendrikse'; + private const LEGACY_TAGLINE_PATTERN = '/Calorie' . self::FLEXIBLE_SPACE . 'aims' . self::FLEXIBLE_SPACE . 'to' . self::FLEXIBLE_SPACE . 'be' . self::FLEXIBLE_SPACE . 'the' . self::FLEXIBLE_SPACE . 'World(?:\'|’|'|’|'|’)' . self::FLEXIBLE_SPACE . 's' . self::FLEXIBLE_SPACE . 'food' . self::FLEXIBLE_SPACE . 'token/iu'; + private const CURRENT_TAGLINE = 'Calorie aims to be the world’s food token'; public function register_hooks(): void { add_action('template_redirect', [$this, 'start_output_buffer'], PHP_INT_MAX); @@ -43,12 +54,18 @@ public function start_output_buffer(): void { } public static function replace_legacy_footer_html(string $html): string { - $html = preg_replace( - self::LEGACY_OPERATOR_PATTERN, - self::CURRENT_OPERATOR, + foreach (self::LEGACY_OPERATOR_PATTERNS as $pattern) { + $html = preg_replace($pattern, self::CURRENT_OPERATOR, $html) ?? $html; + } + + foreach (self::LEGACY_COPYRIGHT_PATTERNS as $pattern) { + $html = preg_replace($pattern, self::CURRENT_COPYRIGHT, $html) ?? $html; + } + + return preg_replace( + self::LEGACY_TAGLINE_PATTERN, + self::CURRENT_TAGLINE, $html ) ?? $html; - - return str_replace(self::LEGACY_COPYRIGHT, self::CURRENT_COPYRIGHT, $html); } } From 423174c70e7472d8a35172e75eaba1e38ede2904 Mon Sep 17 00:00:00 2001 From: xrpbanks <126300068+xrpbanks@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:25:34 +0200 Subject: [PATCH 5/7] fix(wp): complete legal footer normalization --- .../tests/test-legal-footer-compatibility.php | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/wordpress-plugins/calorieapp-identity-bridge/tests/test-legal-footer-compatibility.php b/wordpress-plugins/calorieapp-identity-bridge/tests/test-legal-footer-compatibility.php index 2ad937c..1ec5388 100644 --- a/wordpress-plugins/calorieapp-identity-bridge/tests/test-legal-footer-compatibility.php +++ b/wordpress-plugins/calorieapp-identity-bridge/tests/test-legal-footer-compatibility.php @@ -3,20 +3,41 @@ use CalorieApp\IdentityBridge\LegalFooterCompatibility; class Test_CalorieApp_Legal_Footer_Compatibility extends WP_UnitTestCase { - public function test_replaces_only_obsolete_legal_footer_labels(): void { - $html = '

Chamber of Commerce KVK: 12345678

' + public function test_replaces_known_obsolete_legal_footer_variants(): void { + $html = '

Chamber of Commerce KVK: 84216352

' + . '

Calorie Token • KvK 84216352

' + . '

ICTHendrikse • KvK 73774693

' + . '

Operator: ICTHendrikse

' . '

© 2023 Calorie Token

' + . '

© 2026 CalorieToken

' + . '

Calorie aims to be the World's food token

' . '

Tokenomics content remains unchanged.

'; $result = LegalFooterCompatibility::replace_legacy_footer_html($html); - $this->assertStringContainsString('Operator: ICTHendrikse', $result); + $this->assertSame(4, substr_count($result, 'Operator: ICTHendrikse · KVK 73774693')); + $this->assertSame( + 2, + substr_count( + $result, + '© 2026 ICTHendrikse (owned content only) · CalorieToken® trade mark: Pieter Hendrikse' + ) + ); $this->assertStringContainsString( - '© 2026 ICTHendrikse (owned content only) · CalorieToken® trade mark: Pieter Hendrikse', + 'Calorie aims to be the world’s food token', $result ); $this->assertStringContainsString('Tokenomics content remains unchanged.', $result); - $this->assertStringNotContainsString('12345678', $result); + $this->assertStringNotContainsString('84216352', $result); + } + + public function test_current_footer_is_idempotent(): void { + $html = ''; + + $this->assertSame($html, LegalFooterCompatibility::replace_legacy_footer_html($html)); } public function test_leaves_unrelated_html_unchanged(): void { From 89eafb098d64bd9d19db678ae2c9eba315a30440 Mon Sep 17 00:00:00 2001 From: xrpbanks <126300068+xrpbanks@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:29:34 +0200 Subject: [PATCH 6/7] ci(wp): execute footer compatibility checks --- .github/workflows/ci.yml | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7049284..9ae0271 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,6 +54,51 @@ jobs: - name: Check out repository uses: actions/checkout@v7 + - name: Lint WordPress plugin PHP + run: find wordpress-plugins/calorieapp-identity-bridge -type f -name '*.php' -print0 | xargs -0 -n1 php -l + + - name: Test legal footer compatibility + shell: bash + run: | + php <<'PHP' + Chamber of Commerce KVK: 84216352

' + . '

Calorie Token • KvK 84216352

' + . '

ICTHendrikse • KvK 73774693

' + . '

Operator: ICTHendrikse

' + . '

© 2023 Calorie Token

' + . '

© 2026 CalorieToken

' + . '

Calorie aims to be the World's food token

' + . '

Unrelated content remains unchanged.

'; + $output = LegalFooterCompatibility::replace_legacy_footer_html($input); + $operator = 'Operator: ICTHendrikse · KVK 73774693'; + $copyright = '© 2026 ICTHendrikse (owned content only) · CalorieToken® trade mark: Pieter Hendrikse'; + + if (substr_count($output, $operator) !== 4) { + throw new RuntimeException('Known operator footer variants were not normalized.'); + } + if (substr_count($output, $copyright) !== 2) { + throw new RuntimeException('Known copyright footer variants were not normalized.'); + } + if (!str_contains($output, 'Calorie aims to be the world’s food token')) { + throw new RuntimeException('The legacy footer tagline was not normalized.'); + } + if (!str_contains($output, 'Unrelated content remains unchanged.')) { + throw new RuntimeException('Unrelated rendered content changed.'); + } + + $current = ''; + if (LegalFooterCompatibility::replace_legacy_footer_html($current) !== $current) { + throw new RuntimeException('The current footer is not idempotent.'); + } + PHP + - name: Set up Python uses: actions/setup-python@v7 with: From 004b389e34d89f890501f1c7bab6fb158e02a749 Mon Sep 17 00:00:00 2001 From: xrpbanks <126300068+xrpbanks@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:30:45 +0200 Subject: [PATCH 7/7] fix(wp): keep current footer normalization idempotent --- ...s-calorieapp-identity-bridge-legal-footer-compatibility.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php b/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php index bb58cdc..7c0b0db 100644 --- a/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php +++ b/wordpress-plugins/calorieapp-identity-bridge/includes/class-calorieapp-identity-bridge-legal-footer-compatibility.php @@ -19,7 +19,8 @@ class LegalFooterCompatibility { private const LEGACY_OPERATOR_PATTERNS = [ '/Chamber' . self::FLEXIBLE_SPACE . 'of' . self::FLEXIBLE_SPACE . 'Commerce' . self::FLEXIBLE_SPACE . 'KVK' . self::FLEXIBLE_SPACE . ':' . self::FLEXIBLE_SPACE . '[0-9]{8}/iu', '/Calorie' . self::FLEXIBLE_SPACE . 'Token' . self::FLEXIBLE_SPACE . '(?:•|·|•|·)' . self::FLEXIBLE_SPACE . 'KvK' . self::FLEXIBLE_SPACE . ':?' . self::FLEXIBLE_SPACE . '[0-9]{8}/iu', - '/ICTHendrikse' . self::FLEXIBLE_SPACE . '(?:•|·|•|·)' . self::FLEXIBLE_SPACE . 'KvK' . self::FLEXIBLE_SPACE . ':?' . self::FLEXIBLE_SPACE . '73774693/iu', + '/Operator:' . self::FLEXIBLE_SPACE . 'ICTHendrikse' . self::FLEXIBLE_SPACE . '(?:•|·|•|·)' . self::FLEXIBLE_SPACE . 'KvK' . self::FLEXIBLE_SPACE . ':?' . self::FLEXIBLE_SPACE . '73774693/iu', + '/(?