From a5b02467b7f13598dd7e24b5a3cb4f3447101df5 Mon Sep 17 00:00:00 2001 From: Matej Sychra Date: Fri, 25 Sep 2026 16:15:26 +0200 Subject: [PATCH 001/192] fix(vue): give Layout the hostnames mixin so the footer links get an href Closes the phase 22 CI-03 gap found in 22-VERIFICATION. The authenticated Layout footer bound this.$hostnames.CONSOLE and .LANDING without declaring the hostnames mixin, so it read the empty Vue.prototype.$hostnames from main.js and both "THiNX Console" and "THiNX Cloud" rendered with no href. Layout now imports and declares the mixin, the same per-component pattern Login, PasswordReset, OAuthReturn and Visits already use. The template is unchanged. Adds tests/unit/footer-hostnames.cjs, a plain-node test chained into test:unit. It renders the real footers of Layout, Login and PasswordReset with each component's own mixins, checks the unset-var fallback to the serving origin, and fails if any $hostnames reader under src lacks the mixin. Claude-Session: https://claude.ai/code/session_01JdkLTubatsxPk7D9BTb4gS --- vue/package.json | 2 +- vue/src/components/Layout/Layout.vue | 2 + vue/tests/unit/footer-hostnames.cjs | 176 +++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 vue/tests/unit/footer-hostnames.cjs diff --git a/vue/package.json b/vue/package.json index 730314a..d1f4a1e 100644 --- a/vue/package.json +++ b/vue/package.json @@ -14,7 +14,7 @@ "test:csp": "node tests/security/csp.cjs", "test:csp:browser": "node tests/security/csp-browser.cjs", "test:csp:dist": "node tests/security/csp.cjs --dist", - "test:unit": "node tests/unit/env-json.cjs", + "test:unit": "node tests/unit/env-json.cjs && node tests/unit/footer-hostnames.cjs", "cy:open": "cypress open", "test": "start-server-and-test serve http://127.0.0.1:3000/ cy:test", "eslint": "ESLINT_USE_FLAT_CONFIG=false eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", diff --git a/vue/src/components/Layout/Layout.vue b/vue/src/components/Layout/Layout.vue index 99625e5..4b97a97 100644 --- a/vue/src/components/Layout/Layout.vue +++ b/vue/src/components/Layout/Layout.vue @@ -20,6 +20,7 @@ import { mapState, mapActions } from 'vuex'; import Sidebar from '@/components/Sidebar/Sidebar'; import Header from '@/components/Header/Header'; import ImpersonationBanner from '@/components/ImpersonationBanner/ImpersonationBanner'; +import hostnameMixin from '@/mixins/hostnames'; // Removed: Helper (Flatlogic template "Configuration" panel — Purchase / Go FULL / Documentation / social-sharing). // Not part of THiNX product surface; was leftover from the light-blue-vue template. @@ -28,6 +29,7 @@ import './Layout.scss'; export default { name: 'Layout', components: { Sidebar, Header, ImpersonationBanner }, + mixins: [hostnameMixin], methods: { ...mapActions( 'layout', ['switchSidebar', 'changeSidebarActive'], diff --git a/vue/tests/unit/footer-hostnames.cjs b/vue/tests/unit/footer-hostnames.cjs new file mode 100644 index 0000000..9e06f55 --- /dev/null +++ b/vue/tests/unit/footer-hostnames.cjs @@ -0,0 +1,176 @@ +// Unit test for the "THiNX Console" / "THiNX Cloud" footer links (phase 22, CI-03). +// +// The footers bind :href="this.$hostnames.CONSOLE" and .LANDING. $hostnames is an +// own property that src/mixins/hostnames.js assigns in created(); a component that +// does not declare that mixin falls through to the empty Vue.prototype.$hostnames +// object from src/main.js, and Vue drops the undefined href. The authenticated +// Layout footer shipped that way. +// +// This renders the real