diff --git a/changelog.d/pinia-oauth-mfa.skip b/changelog.d/pinia-oauth-mfa.skip new file mode 100644 index 000000000..e69de29bb diff --git a/package.json b/package.json index fa4b59eba..a2f238910 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "lint-fix": "eslint --fix src test/unit/specs test/e2e/specs" }, "dependencies": { - "@babel/runtime": "7.26.10", + "@babel/runtime": "7.27.0", "@chenfengyuan/vue-qrcode": "2.0.0", "@fortawesome/fontawesome-svg-core": "6.7.2", "@fortawesome/free-regular-svg-icons": "6.7.2", @@ -55,7 +55,7 @@ }, "devDependencies": { "@babel/core": "7.26.10", - "@babel/eslint-parser": "7.26.10", + "@babel/eslint-parser": "7.27.0", "@babel/plugin-transform-runtime": "7.26.10", "@babel/preset-env": "7.26.9", "@babel/register": "7.25.9", @@ -72,11 +72,11 @@ "babel-plugin-lodash": "3.3.4", "chai": "4.5.0", "chalk": "5.4.1", - "chromedriver": "134.0.3", + "chromedriver": "134.0.5", "connect-history-api-fallback": "2.0.0", "cross-spawn": "7.0.6", "custom-event-polyfill": "1.0.7", - "eslint": "9.22.0", + "eslint": "9.23.0", "eslint-config-standard": "17.1.0", "eslint-formatter-friendly": "7.0.0", "eslint-plugin-import": "2.31.0", @@ -96,7 +96,7 @@ "postcss": "8.5.3", "postcss-html": "^1.5.0", "postcss-scss": "^4.0.6", - "sass": "1.85.1", + "sass": "1.86.0", "selenium-server": "3.141.59", "semver": "7.7.1", "serve-static": "1.16.2", diff --git a/public/static/styles/Breezy DX.iss b/public/static/styles/Breezy DX.iss index fcaa7a8eb..69cc3befe 100644 --- a/public/static/styles/Breezy DX.iss +++ b/public/static/styles/Breezy DX.iss @@ -25,7 +25,7 @@ accent: #1CA4F3; cBlue: #1CA4F3; cRed: #f41a51; - cGreen: #1af46e; + cGreen: #0b6a30; cOrange: #f4af1a; border: #d8e6f9; link: #1CA4F3; @@ -39,7 +39,7 @@ accent: #1CA4F3; cRed: #f41a51; cBlue: #1CA4F3; - cGreen: #1af46e; + cGreen: #0b6a30; cOrange: #f4af1a; } @@ -47,45 +47,46 @@ Root { --badgeNotification: color | --cRed; --buttonDefaultHoverGlow: shadow | inset 0 0 0 1 --accent / 1; --buttonDefaultFocusGlow: shadow | inset 0 0 0 1 --accent / 1; - --buttonDefaultShadow: shadow | inset 0 0 0 1 --parent--text / 0.35, 0 5 5 -5 #000000 / 0.35; + --buttonDefaultShadow: shadow | inset 0 0 0 1 --text / 0.35, 0 5 5 -5 #000000 / 0.35; --buttonDefaultBevel: shadow | inset 0 14 14 -14 #FFFFFF / 0.1; --buttonPressedBevel: shadow | inset 0 -20 20 -20 #000000 / 0.05; - --defaultInputBevel: shadow | inset 0 0 0 1 --parent--text / 0.35; + --defaultInputBevel: shadow | inset 0 0 0 1 --text / 0.35; --defaultInputHoverGlow: shadow | 0 0 0 1 --accent / 1; --defaultInputFocusGlow: shadow | 0 0 0 1 --link / 1; } +Button { + background: --parent; +} + Button:disabled { shadow: --buttonDefaultBevel, --buttonDefaultShadow } Button:hover { + background: --inheritedBackground; shadow: --buttonDefaultHoverGlow, --buttonDefaultBevel, --buttonDefaultShadow } Button:toggled { - background: $blend(--bg 0.3 --accent) + background: $blend(--inheritedBackground 0.3 --accent) } Button:pressed { - background: $blend(--bg 0.8 --accent) + background: $blend(--inheritedBackground 0.8 --accent) } Button:pressed:toggled { - background: $blend(--bg 0.2 --accent) + background: $blend(--inheritedBackground 0.2 --accent) } Button:toggled:hover { - background: $blend(--bg 0.3 --accent) -} - -Button { - background: --parent; + background: $blend(--inheritedBackground 0.3 --accent) } Input { shadow: --defaultInputBevel; - background: --parent; + background: $mod(--bg -10); } PanelHeader { @@ -97,5 +98,5 @@ Tab:hover { } Tab { - background: --parent; + background: --bg; } diff --git a/src/App.scss b/src/App.scss index 34cb590a2..521be05c6 100644 --- a/src/App.scss +++ b/src/App.scss @@ -388,6 +388,10 @@ nav { &:disabled { cursor: not-allowed; } + + &:active { + transform: translate(1px, 1px); + } } .menu-item { diff --git a/src/components/mfa_form/recovery_form.js b/src/components/mfa_form/recovery_form.js index 01a62a503..2d0f4fdff 100644 --- a/src/components/mfa_form/recovery_form.js +++ b/src/components/mfa_form/recovery_form.js @@ -1,5 +1,7 @@ import mfaApi from '../../services/new_api/mfa.js' import { mapState, mapGetters, mapActions, mapMutations } from 'vuex' +import { mapStores } from 'pinia' +import { useOAuthStore } from 'src/stores/oauth.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faTimes @@ -18,17 +20,24 @@ export default { ...mapGetters({ authSettings: 'authFlow/settings' }), + ...mapStores(useOAuthStore), ...mapState({ instance: 'instance', - oauth: 'oauth' }) }, methods: { ...mapMutations('authFlow', ['requireTOTP', 'abortMFA']), ...mapActions({ login: 'authFlow/login' }), clearError () { this.error = false }, + + focusOnCodeInput () { + const codeInput = this.$refs.codeInput + codeInput.focus() + codeInput.setSelectionRange(0, codeInput.value.length) + }, + submit () { - const { clientId, clientSecret } = this.oauth + const { clientId, clientSecret } = this.oauthStore const data = { clientId, @@ -42,6 +51,7 @@ export default { if (result.error) { this.error = result.error this.code = null + this.focusOnCodeInput() return } diff --git a/src/components/mfa_form/recovery_form.vue b/src/components/mfa_form/recovery_form.vue index f8c3e6a04..02f27ddaf 100644 --- a/src/components/mfa_form/recovery_form.vue +++ b/src/components/mfa_form/recovery_form.vue @@ -1,5 +1,5 @@ + diff --git a/src/components/mfa_form/totp_form.js b/src/components/mfa_form/totp_form.js index 6ee823ed3..857d055ff 100644 --- a/src/components/mfa_form/totp_form.js +++ b/src/components/mfa_form/totp_form.js @@ -1,5 +1,7 @@ import mfaApi from '../../services/new_api/mfa.js' import { mapState, mapGetters, mapActions, mapMutations } from 'vuex' +import { mapStores } from 'pinia' +import { useOAuthStore } from 'src/stores/oauth.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faTimes @@ -18,17 +20,24 @@ export default { ...mapGetters({ authSettings: 'authFlow/settings' }), + ...mapStores(useOAuthStore), ...mapState({ instance: 'instance', - oauth: 'oauth' }) }, methods: { ...mapMutations('authFlow', ['requireRecovery', 'abortMFA']), ...mapActions({ login: 'authFlow/login' }), clearError () { this.error = false }, + + focusOnCodeInput () { + const codeInput = this.$refs.codeInput + codeInput.focus() + codeInput.setSelectionRange(0, codeInput.value.length) + }, + submit () { - const { clientId, clientSecret } = this.oauth + const { clientId, clientSecret } = this.oauthStore const data = { clientId, @@ -42,6 +51,7 @@ export default { if (result.error) { this.error = result.error this.code = null + this.focusOnCodeInput() return } diff --git a/src/components/mfa_form/totp_form.vue b/src/components/mfa_form/totp_form.vue index 26fc1e804..b057f0413 100644 --- a/src/components/mfa_form/totp_form.vue +++ b/src/components/mfa_form/totp_form.vue @@ -1,5 +1,5 @@ + diff --git a/src/services/theme_data/theme3_slot_functions.js b/src/services/theme_data/theme3_slot_functions.js index d1441aebb..137f19bf0 100644 --- a/src/services/theme_data/theme3_slot_functions.js +++ b/src/services/theme_data/theme3_slot_functions.js @@ -112,7 +112,7 @@ export const colorFunctions = { const color = convert(findColor(colorArg, { dynamicVars, staticVars })).rgb const amount = Number(amountArg) - const effectiveBackground = dynamicVars.lowerLevelBackground + const effectiveBackground = dynamicVars.lowerLevelBackground ?? color const isLightOnDark = relativeLuminance(convert(effectiveBackground).rgb) < 0.5 const mod = isLightOnDark ? 1 : -1 return brightness(amount * mod, color).rgb diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index 320196493..b85d917de 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -78,23 +78,24 @@ export const findColor = (color, { dynamicVars, staticVars }) => { targetColor = { r, g, b } } else if (variableSlot.startsWith('parent')) { if (variableSlot === 'parent') { - const { r, g, b } = dynamicVars.lowerLevelBackground + const { r, g, b } = dynamicVars.lowerLevelBackground ?? {} targetColor = { r, g, b } } else { const virtualSlot = variableSlot.replace(/^parent/, '') targetColor = convert(dynamicVars.lowerLevelVirtualDirectivesRaw[virtualSlot]).rgb } } else { - switch (variableSlot) { - case 'inheritedBackground': - targetColor = convert(dynamicVars.inheritedBackground).rgb - break - case 'background': - targetColor = convert(dynamicVars.background).rgb - break - default: - targetColor = convert(staticVars[variableSlot]).rgb + const staticVar = staticVars[variableSlot] + const dynamicVar = dynamicVars[variableSlot] + if (!staticVar && !dynamicVar) { + console.warn(dynamicVars, variableSlot, dynamicVars[variableSlot]) + console.warn(`Couldn't find variable "${variableSlot}", falling back to magenta. Variables are: +Static: +${JSON.stringify(staticVars, null, 2)} +Dynamic: +${JSON.stringify(dynamicVars, null, 2)}`) } + targetColor = convert(staticVar ?? dynamicVar ?? '#FF00FF').rgb } if (modifier) { @@ -109,7 +110,7 @@ export const findColor = (color, { dynamicVars, staticVars }) => { try { targetColor = process(color, colorFunctions, { findColor }, { dynamicVars, staticVars }) } catch (e) { - console.error('Failure executing color function', e) + console.error('Failure executing color function', e ,'\n Function: ' + color) targetColor = '#FF00FF' } } @@ -120,7 +121,7 @@ export const findColor = (color, { dynamicVars, staticVars }) => { Static: ${JSON.stringify(staticVars, null, 2)} Dynamic: -${JSON.stringify(dynamicVars, null, 2)}`, e) +${JSON.stringify(dynamicVars, null, 2)}\nError: ${e}`) } } @@ -516,7 +517,7 @@ export const init = ({ .filter(c => virtualComponents.has(c) && !nonEditableComponents.has(c)) } else if (liteMode) { validInnerComponents = (component.validInnerComponentsLite || component.validInnerComponents || []) - } else if (component.name === 'Root' || component.states != null) { + } else if (component.name === 'Root' || component.states != null || component.background?.includes('--parent')) { validInnerComponents = component.validInnerComponents || [] } else { validInnerComponents = component diff --git a/yarn.lock b/yarn.lock index aeb777ca7..ff2554243 100644 --- a/yarn.lock +++ b/yarn.lock @@ -68,10 +68,10 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@7.26.10": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.26.10.tgz#4423cb3f84c26978439feabfe23c5aa929400737" - integrity sha512-QsfQZr4AiLpKqn7fz+j7SN+f43z2DZCgGyYbNJ2vJOqKfG4E6MZer1+jqGZqKJaxq/gdO2DC/nUu45+pOL5p2Q== +"@babel/eslint-parser@7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.27.0.tgz#d55e52a5ef3b164139a799dc522c338faba3507c" + integrity sha512-dtnzmSjXfgL/HDgMcmsLSzyGbEosi4DrGWoCNfuI+W4IkVJw6izpTe7LtOdwAXnkDqw5yweboYCTkM2rQizCng== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" @@ -865,10 +865,10 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@7.26.10": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.10.tgz#a07b4d8fa27af131a633d7b3524db803eb4764c2" - integrity sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw== +"@babel/runtime@7.27.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== dependencies: regenerator-runtime "^0.14.0" @@ -1183,10 +1183,10 @@ debug "^4.3.1" minimatch "^3.1.2" -"@eslint/config-helpers@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.1.0.tgz#62f1b7821e9d9ced1b3f512c7ea731825765d1cc" - integrity sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA== +"@eslint/config-helpers@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.2.0.tgz#12dc8d65c31c4b6c3ebf0758db6601eb7692ce59" + integrity sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ== "@eslint/core@^0.12.0": version "0.12.0" @@ -1195,10 +1195,10 @@ dependencies: "@types/json-schema" "^7.0.15" -"@eslint/eslintrc@^3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.0.tgz#96a558f45842989cca7ea1ecd785ad5491193846" - integrity sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ== +"@eslint/eslintrc@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.1.tgz#e55f7f1dd400600dd066dbba349c4c0bac916964" + integrity sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1210,10 +1210,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.22.0": - version "9.22.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.22.0.tgz#4ff53649ded7cbce90b444b494c234137fa1aa3d" - integrity sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ== +"@eslint/js@9.23.0": + version "9.23.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.23.0.tgz#c09ded4f3dc63b40b933bcaeb853fceddb64da30" + integrity sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw== "@eslint/object-schema@^2.1.6": version "2.1.6" @@ -2909,10 +2909,10 @@ chromatism@3.0.0: resolved "https://registry.yarnpkg.com/chromatism/-/chromatism-3.0.0.tgz#a7249d353c1e4f3577e444ac41171c4e2e624b12" integrity sha512-slVGC45odKFB6KzD/hpXP8XgS/Y+x72X1ckAhxU/9YZecCy8VwCJUSZsn0O4gQUwaTogun6IfrSiK3YuQaADFw== -chromedriver@134.0.3: - version "134.0.3" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-134.0.3.tgz#185a52526c193cc7ceb0a27d1266858f0f65f0fd" - integrity sha512-pRS401K3VRJMhFrK4NNceVE6xdoNOHC0P3sBylkLOb5p4MfrbXkjiCCipXoBD8jvui76t44FS5/taoVQNz9XUg== +chromedriver@134.0.5: + version "134.0.5" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-134.0.5.tgz#9432404d7da7412df4ea5ae4072b579bcc098ed7" + integrity sha512-edXbiuShAvH6Elx8Hobl4NQkgNRMIozcW7ZlEiE8TBynZHRazrepO9hfftQzZgztPvjMQiSWeWjZaDV3SecYaw== dependencies: "@testim/chrome-version" "^1.1.4" axios "^1.7.4" @@ -3932,18 +3932,18 @@ eslint-visitor-keys@^4.2.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== -eslint@9.22.0: - version "9.22.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.22.0.tgz#0760043809fbf836f582140345233984d613c552" - integrity sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ== +eslint@9.23.0: + version "9.23.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.23.0.tgz#b88f3ab6dc83bcb927fdb54407c69ffe5f2441a6" + integrity sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.12.1" "@eslint/config-array" "^0.19.2" - "@eslint/config-helpers" "^0.1.0" + "@eslint/config-helpers" "^0.2.0" "@eslint/core" "^0.12.0" - "@eslint/eslintrc" "^3.3.0" - "@eslint/js" "9.22.0" + "@eslint/eslintrc" "^3.3.1" + "@eslint/js" "9.23.0" "@eslint/plugin-kit" "^0.2.7" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" @@ -6862,10 +6862,10 @@ safe-regex-test@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass@1.85.1: - version "1.85.1" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.85.1.tgz#18ab0bb48110ae99163778f06445b406148ca0d5" - integrity sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag== +sass@1.86.0: + version "1.86.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.86.0.tgz#f49464fb6237a903a93f4e8760ef6e37a5030114" + integrity sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA== dependencies: chokidar "^4.0.0" immutable "^5.0.2"