From a80619bd326fcc10d1cdc99ab23467fd52d06dd5 Mon Sep 17 00:00:00 2001 From: edalzell Date: Tue, 13 Oct 2026 18:48:00 -0700 Subject: [PATCH 1/2] Add a front:chat tag that renders the chat widget --- dist/build/assets/cp-CYSYRrr0.js | 1 + dist/build/assets/cp-peOtejVL.js | 1 - dist/build/manifest.json | 2 +- resources/js/cp.js | 27 ++++++-------------- src/ChatConfig.php | 2 +- src/ServiceProvider.php | 4 --- src/Tags/Front.php | 34 +++++++++++++++++++++++++ tests/ServiceProviderTest.php | 2 +- tests/Tags/FrontTest.php | 43 ++++++++++++++++++++++++++++++++ 9 files changed, 89 insertions(+), 27 deletions(-) create mode 100644 dist/build/assets/cp-CYSYRrr0.js delete mode 100644 dist/build/assets/cp-peOtejVL.js create mode 100644 src/Tags/Front.php create mode 100644 tests/Tags/FrontTest.php diff --git a/dist/build/assets/cp-CYSYRrr0.js b/dist/build/assets/cp-CYSYRrr0.js new file mode 100644 index 0000000..076b462 --- /dev/null +++ b/dist/build/assets/cp-CYSYRrr0.js @@ -0,0 +1 @@ +Statamic.booted(()=>{const e=Statamic.$config.get("front");if(!e)return;const t=document.createElement("script");t.src="https://chat-assets.frontapp.com/v1/chat.bundle.js",t.addEventListener("load",()=>window.FrontChat("init",{...e,useDefaultLauncher:!0})),document.body.appendChild(t)}); diff --git a/dist/build/assets/cp-peOtejVL.js b/dist/build/assets/cp-peOtejVL.js deleted file mode 100644 index 1e5ca3f..0000000 --- a/dist/build/assets/cp-peOtejVL.js +++ /dev/null @@ -1 +0,0 @@ -Statamic.booted(()=>{let t=Statamic.$config.get("front");if(t&&t.chatId){var a=document.createElement("script");a.src="https://chat-assets.frontapp.com/v1/chat.bundle.js",document.body.appendChild(a),a.addEventListener("load",()=>{window.FrontChat("init",{chatId:t.chatId,email:t.email,name:t.name,userHash:t.hash,useDefaultLauncher:!0})})}}); diff --git a/dist/build/manifest.json b/dist/build/manifest.json index 7d10e5e..90780cc 100644 --- a/dist/build/manifest.json +++ b/dist/build/manifest.json @@ -9,7 +9,7 @@ ] }, "resources/js/cp.js": { - "file": "assets/cp-peOtejVL.js", + "file": "assets/cp-CYSYRrr0.js", "name": "cp", "src": "resources/js/cp.js", "isEntry": true diff --git a/resources/js/cp.js b/resources/js/cp.js index 9df5641..ffd084f 100755 --- a/resources/js/cp.js +++ b/resources/js/cp.js @@ -1,23 +1,12 @@ Statamic.booted(() => { - let frontConfig = Statamic.$config.get('front'); + const frontConfig = Statamic.$config.get('front'); - if (frontConfig && frontConfig.chatId) { - var script = document.createElement("script"); - script.src = 'https://chat-assets.frontapp.com/v1/chat.bundle.js'; - - // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead) - document.body.appendChild(script); - script.addEventListener('load', () => { - window.FrontChat( - 'init', - { - chatId: frontConfig.chatId, - email: frontConfig.email, - name: frontConfig.name, - userHash: frontConfig.hash, - useDefaultLauncher: true - } - ); - }); + if (! frontConfig) { + return; } + + const script = document.createElement('script'); + script.src = 'https://chat-assets.frontapp.com/v1/chat.bundle.js'; + script.addEventListener('load', () => window.FrontChat('init', { ...frontConfig, useDefaultLauncher: true })); + document.body.appendChild(script); }); diff --git a/src/ChatConfig.php b/src/ChatConfig.php index 268044f..7ba4c7f 100644 --- a/src/ChatConfig.php +++ b/src/ChatConfig.php @@ -13,8 +13,8 @@ public static function forCurrentUser(): array return [ 'chatId' => config('front.chat.id'), 'email' => $email, - 'hash' => $email ? hash_hmac('sha256', $email, config('front.secret_key')) : null, 'name' => User::current()?->name(), + 'userHash' => $email ? hash_hmac('sha256', $email, config('front.secret_key')) : null, ]; } } diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 452ae68..ab320ab 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -8,10 +8,6 @@ class ServiceProvider extends AddonServiceProvider { - protected $routes = [ - 'actions' => __DIR__.'/../routes/actions.php', - ]; - protected $vite = [ 'input' => [ 'resources/css/cp.css', diff --git a/src/Tags/Front.php b/src/Tags/Front.php new file mode 100644 index 0000000..d572f4f --- /dev/null +++ b/src/Tags/Front.php @@ -0,0 +1,34 @@ +isConfigured()) { + return ''; + } + + $options = Js::from(Arr::removeNullValues(ChatConfig::forCurrentUser())); + + return << + + HTML; + } + + private function isConfigured(): bool + { + return config('front.chat.show_on_front_end') + && config('front.chat.id') + && config('front.secret_key'); + } +} diff --git a/tests/ServiceProviderTest.php b/tests/ServiceProviderTest.php index cef6948..abf11e1 100644 --- a/tests/ServiceProviderTest.php +++ b/tests/ServiceProviderTest.php @@ -16,8 +16,8 @@ expect(Statamic::jsonVariables(request())['front'])->toBe([ 'chatId' => 'chat-id', 'email' => 'erin@transformstudios.com', - 'hash' => hash_hmac('sha256', 'erin@transformstudios.com', 'secret'), 'name' => 'Erin', + 'userHash' => hash_hmac('sha256', 'erin@transformstudios.com', 'secret'), ]); }); diff --git a/tests/Tags/FrontTest.php b/tests/Tags/FrontTest.php new file mode 100644 index 0000000..8ef29e9 --- /dev/null +++ b/tests/Tags/FrontTest.php @@ -0,0 +1,43 @@ +set('front.secret_key', 'secret'); + config()->set('front.chat.id', 'chat-id'); + config()->set('front.chat.show_on_front_end', true); +}); + +it('renders the chat script for a guest', function () { + $html = (string) Antlers::parse('{{ front:chat }}', trusted: true); + + expect($html) + ->toContain('https://chat-assets.frontapp.com/v1/chat.bundle.js') + ->toContain('chatId') + ->toContain('chat-id') + ->not->toContain('userHash'); +}); + +it('identifies the current user', function () { + $user = tap(User::make()->email('erin@transformstudios.com')->set('name', 'Erin'))->save(); + + $this->actingAs($user); + + expect((string) Antlers::parse('{{ front:chat }}', trusted: true)) + ->toContain('erin@transformstudios.com') + ->toContain('Erin') + ->toContain(hash_hmac('sha256', 'erin@transformstudios.com', 'secret')); +}); + +it('renders nothing when hidden on the front end', function () { + config()->set('front.chat.show_on_front_end', false); + + expect((string) Antlers::parse('{{ front:chat }}', trusted: true))->toBe(''); +}); + +it('renders nothing without a chat id', function () { + config()->set('front.chat.id', null); + + expect((string) Antlers::parse('{{ front:chat }}', trusted: true))->toBe(''); +}); From adcae69599de620b9525126f678647f9c7962391 Mon Sep 17 00:00:00 2001 From: edalzell Date: Tue, 13 Oct 2026 18:48:01 -0700 Subject: [PATCH 2/2] Remove the chat config endpoint and stale head partial --- resources/views/head.antlers.html | 18 -------- routes/actions.php | 6 --- src/Http/Controllers/ConfigController.php | 24 ----------- .../Http/Controllers/ConfigControllerTest.php | 42 ------------------- 4 files changed, 90 deletions(-) delete mode 100755 resources/views/head.antlers.html delete mode 100644 routes/actions.php delete mode 100644 src/Http/Controllers/ConfigController.php delete mode 100644 tests/Http/Controllers/ConfigControllerTest.php diff --git a/resources/views/head.antlers.html b/resources/views/head.antlers.html deleted file mode 100755 index b91e0b5..0000000 --- a/resources/views/head.antlers.html +++ /dev/null @@ -1,18 +0,0 @@ - - diff --git a/routes/actions.php b/routes/actions.php deleted file mode 100644 index 73de7fd..0000000 --- a/routes/actions.php +++ /dev/null @@ -1,6 +0,0 @@ -name('front.config'); diff --git a/src/Http/Controllers/ConfigController.php b/src/Http/Controllers/ConfigController.php deleted file mode 100644 index cf9da9d..0000000 --- a/src/Http/Controllers/ConfigController.php +++ /dev/null @@ -1,24 +0,0 @@ -json([ - 'configured' => $this->isConfigured(), - ...ChatConfig::forCurrentUser(), - ]); - } - - private function isConfigured(): bool - { - return config('front.chat.show_on_front_end') && - config('front.chat.id') && - config('front.secret_key'); - } -} diff --git a/tests/Http/Controllers/ConfigControllerTest.php b/tests/Http/Controllers/ConfigControllerTest.php deleted file mode 100644 index 6b9f542..0000000 --- a/tests/Http/Controllers/ConfigControllerTest.php +++ /dev/null @@ -1,42 +0,0 @@ -set('front.secret_key', 'secret'); - config()->set('front.chat.id', 'chat-id'); - config()->set('front.chat.show_on_front_end', true); -}); - -it('returns user details when configured', function () { - $user = tap(User::make()->email('erin@transformstudios.com')->set('name', 'Erin'))->save(); - - $this->actingAs($user) - ->getJson('/!/front/config') - ->assertOk() - ->assertExactJson([ - 'configured' => true, - 'chatId' => 'chat-id', - 'email' => 'erin@transformstudios.com', - 'name' => 'Erin', - 'hash' => hash_hmac('sha256', 'erin@transformstudios.com', 'secret'), - ]); -}); - -it('falls back to first and last name', function () { - $user = tap(User::make()->email('erin@transformstudios.com')->set('first_name', 'Erin')->set('last_name', 'Dalzell'))->save(); - - $this->actingAs($user)->getJson('/!/front/config')->assertJson(['name' => 'Erin Dalzell']); -}); - -it('returns nulls for a guest', function () { - $this->getJson('/!/front/config') - ->assertOk() - ->assertJson(['configured' => true, 'email' => null, 'name' => null, 'hash' => null]); -}); - -it('is not configured when hidden on the front end', function () { - config()->set('front.chat.show_on_front_end', false); - - $this->getJson('/!/front/config')->assertOk()->assertJson(['configured' => false]); -});