From 9ae1bd8e1ca914b34047880ca0c9f847c3bd3b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Wed, 23 Jul 2025 08:54:28 +0200 Subject: [PATCH 01/11] fix tsc checks, replace eslint with biomejs --- .github/workflows/lint-web.yml | 2 +- Dockerfile | 2 +- web/.nvmrc | 2 +- web/.typesafe-i18n.json | 6 +- web/biome.json | 75 + web/package.json | 22 +- web/pnpm-lock.yaml | 734 +---- web/src/components/LogoContainer/style.scss | 2 - web/src/i18n/formatters.ts | 15 +- web/src/i18n/i18n-react.tsx | 29 +- web/src/i18n/i18n-types.ts | 2487 +++++++++-------- web/src/i18n/i18n-util.async.ts | 29 +- web/src/i18n/i18n-util.sync.ts | 25 +- web/src/i18n/i18n-util.ts | 87 +- web/src/pages/enrollment/EnrollmentPage.tsx | 6 +- .../components/AdminInfo/style.scss | 2 - .../EnrollmentSideBar/EnrollmentSideBar.tsx | 4 +- .../components/EnrollmentSideBar/style.scss | 3 +- .../EnrollmentStepControls.tsx | 2 +- .../EnrollmentStepControls/style.scss | 6 +- .../EnrollmentStepIndicator/style.scss | 3 +- .../enrollment/components/TimeLeft/style.scss | 2 - .../hooks/store/useEnrollmentStore.tsx | 2 +- .../DataVerificationStep.tsx | 2 +- .../steps/DataVerificationStep/style.scss | 3 +- .../steps/DeviceStep/DeviceStep.tsx | 4 +- .../components/CreateDevice.tsx | 4 +- .../DeviceConfiguration.tsx | 11 +- .../components/DeviceConfiguration/style.scss | 2 - .../components/ConfigureDeviceCard/style.scss | 2 - .../components/QuickGuideCard/style.scss | 2 - .../enrollment/steps/DeviceStep/style.scss | 4 +- .../enrollment/steps/FinishStep/style.scss | 2 - .../steps/PasswordStep/PasswordStep.tsx | 6 +- .../enrollment/steps/PasswordStep/style.scss | 2 - .../steps/WelcomeStep/WelcomeStep.tsx | 22 +- .../enrollment/steps/WelcomeStep/style.scss | 5 +- web/src/pages/enrollment/style.scss | 2 - .../DeviceSetupMethodCard.tsx | 2 +- .../main/DeviceSetupMethodCard/style.scss | 2 - web/src/pages/main/MainPage.tsx | 4 +- web/src/pages/main/style.scss | 2 - web/src/pages/mfa/OpenIDCallback.tsx | 2 +- web/src/pages/mfa/style.scss | 2 - .../components/OpenIDCallbackCard.tsx | 104 +- .../openidCallback/components/style.scss | 3 +- web/src/pages/openidCallback/style.scss | 3 +- .../pages/passwordReset/PasswordResetPage.tsx | 6 +- .../hooks/usePasswordResetStore.tsx | 2 +- .../passwordReset/steps/CodeStep/CodeStep.tsx | 2 +- .../steps/EmailStep/EmailStep.tsx | 4 +- .../steps/PasswordStep/PasswordStep.tsx | 4 +- web/src/pages/passwordReset/style.scss | 8 +- web/src/pages/sessionTimeout/style.scss | 2 - web/src/pages/token/components/TokenCard.tsx | 110 +- web/src/pages/token/components/style.scss | 2 - web/src/pages/token/style.scss | 5 +- .../Form/FormDevTools/FormDevTools.tsx | 21 - .../components/Form/FormDevTools/style.scss | 23 - .../components/Form/FormInput/FormInput.tsx | 12 +- .../components/Form/FormSelect/FormSelect.tsx | 30 +- .../components/Form/FormToggle/FormToggle.tsx | 8 +- .../layout/ActionButton/ActionButton.tsx | 2 +- .../layout/BigInfoBox/BigInfoBox.tsx | 2 +- .../components/layout/Button/Button.tsx | 7 +- .../shared/components/layout/Card/Card.tsx | 4 +- .../shared/components/layout/Card/style.scss | 2 - .../components/layout/Checkbox/CheckBox.tsx | 4 +- .../components/layout/Divider/Divider.tsx | 2 +- .../layout/FloatingArrow/FloatingArrow.tsx | 2 +- .../layout/FloatingBox/FloatingBox.tsx | 2 +- .../shared/components/layout/Input/Input.tsx | 17 +- .../shared/components/layout/Input/types.ts | 4 +- .../layout/MessageBox/MessageBox.tsx | 12 +- .../layout/PageContainer/PageContainer.tsx | 2 +- .../layout/PageContainer/style.scss | 2 - .../components/layout/Select/Select.tsx | 12 +- .../SelectOptionRow/SelectOptionRow.tsx | 2 +- .../shared/components/layout/Select/types.ts | 4 +- web/src/shared/components/layout/Tag/Tag.tsx | 2 +- .../components/layout/Toggle/Toggle.tsx | 4 +- .../components/ToggleOption/ToggleOption.tsx | 4 +- .../layout/hooks/theme/useTheme.tsx | 2 +- .../components/layout/hooks/theme/utils.ts | 2 +- .../components/svg/DefguardLogoText.tsx | 1 + .../svg/EnrollmentSelectGraphic.tsx | 1 + .../components/svg/IconArrowSingleLarge.tsx | 1 + .../components/svg/IconArrowSingleSmall.tsx | 1 + web/src/shared/components/svg/IconAsterix.tsx | 1 + web/src/shared/components/svg/IconCancel.tsx | 1 + web/src/shared/components/svg/IconCopy.tsx | 1 + .../shared/components/svg/IconDownload.tsx | 1 + .../shared/components/svg/IconHamburger.tsx | 1 + web/src/shared/components/svg/IconInfo.tsx | 1 + .../shared/components/svg/IconInfoSuccess.tsx | 1 + web/src/shared/components/svg/IconQr.tsx | 1 + web/src/shared/components/svg/IconWarning.tsx | 1 + web/src/shared/components/svg/IconX.tsx | 1 + .../svg/PasswordResetSelectGraphic.tsx | 1 + web/src/shared/components/svg/TeoniteLogo.tsx | 1 + web/src/shared/hooks/api/useApi.tsx | 4 +- web/src/shared/hooks/api/utils.ts | 2 +- web/src/shared/patterns.ts | 2 +- web/src/shared/validators/password.ts | 2 +- web/tsconfig.app.json | 40 + web/tsconfig.json | 41 +- web/vite.config.ts | 8 +- 107 files changed, 1863 insertions(+), 2331 deletions(-) create mode 100644 web/biome.json delete mode 100644 web/src/shared/components/Form/FormDevTools/FormDevTools.tsx delete mode 100644 web/src/shared/components/Form/FormDevTools/style.scss create mode 100644 web/tsconfig.app.json diff --git a/.github/workflows/lint-web.yml b/.github/workflows/lint-web.yml index a34f7c8a..c5d05731 100644 --- a/.github/workflows/lint-web.yml +++ b/.github/workflows/lint-web.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - name: install deps working-directory: ./web run: | diff --git a/Dockerfile b/Dockerfile index f99b078f..43765a60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22-alpine AS web +FROM node:24-alpine AS web WORKDIR /app COPY web/package.json . diff --git a/web/.nvmrc b/web/.nvmrc index 05952415..19f23bce 100644 --- a/web/.nvmrc +++ b/web/.nvmrc @@ -1 +1 @@ -v20.4 \ No newline at end of file +v24.4 diff --git a/web/.typesafe-i18n.json b/web/.typesafe-i18n.json index b3224e1e..dd9526ae 100644 --- a/web/.typesafe-i18n.json +++ b/web/.typesafe-i18n.json @@ -1,4 +1,4 @@ { - "adapter": "react", - "$schema": "https://unpkg.com/typesafe-i18n@5.26.2/schema/typesafe-i18n.json" -} \ No newline at end of file + "adapter": "react", + "$schema": "https://unpkg.com/typesafe-i18n@5.26.2/schema/typesafe-i18n.json" +} diff --git a/web/biome.json b/web/biome.json new file mode 100644 index 00000000..8853a47e --- /dev/null +++ b/web/biome.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.1.2/schema.json", + "vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false }, + "files": { "ignoreUnknown": false }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 90, + "attributePosition": "auto", + "bracketSameLine": false, + "bracketSpacing": true, + "expand": "auto", + "useEditorconfig": true, + "includes": ["./src/**", "!./src/i18n/*.ts", "!./src/i18n/*.tsx"] + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "a11y": "off", + "complexity": { + "noBannedTypes": "error", + "noUselessTypeConstraint": "error" + }, + "correctness": { + "noChildrenProp": "error", + "noPrecisionLoss": "error", + "noUnusedVariables": "error", + "useExhaustiveDependencies": "error", + "useHookAtTopLevel": "error", + "useJsxKeyInIterable": "error" + }, + "security": { "noDangerouslySetInnerHtmlWithChildren": "error" }, + "style": { + "noNamespace": "error", + "noNonNullAssertion": "error", + "useArrayLiterals": "error", + "useAsConstAssertion": "error", + "useBlockStatements": "off" + }, + "suspicious": { + "noCommentText": "error", + "noDuplicateJsxProps": "error", + "noExplicitAny": "error", + "noExtraNonNullAssertion": "error", + "noMisleadingInstantiator": "error", + "noUnsafeDeclarationMerging": "error", + "noArrayIndexKey": "off" + } + }, + "includes": ["src/**", "!**/dist/", "!src/shared/components/svg/*", "!src/i18n/**"] + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto", + "bracketSpacing": true + } + }, + "html": { "formatter": { "selfCloseVoidElements": "always" } }, + "overrides": [{ "includes": ["**/*.js"] }], + "assist": { + "enabled": true, + "actions": { "source": { "organizeImports": "on" } } + } +} diff --git a/web/package.json b/web/package.json index 4d3d096e..15fe53d5 100644 --- a/web/package.json +++ b/web/package.json @@ -5,14 +5,15 @@ "type": "module", "scripts": { "dev": "npm-run-all --parallel vite typesafe-i18n", - "build": "vite build", + "typecheck": "tsc --project ./tsconfig.app.json", + "build": "pnpm run typecheck && vite build", "preview": "vite preview", "typesafe-i18n": "typesafe-i18n", "generate-translation-types": "typesafe-i18n --no-watch", - "lint": "eslint --config ./.eslintrc.cjs src && prettier --check 'src/**/*.ts' 'src/**/*.tsx' 'src/**/*.scss'", - "fix": "prettier -w src/**/*.{ts,tsx,scss} && eslint --fix --config ./.eslintrc.cjs src", + "fix": "biome check --fix && prettier src/**/*.scss -w --log-level silent", + "lint": "biome lint && pnpm run typecheck && prettier src/**/*.scss --check --log-level error", + "lint-ci": "biome ci && pnpm run typecheck && prettier src/**/*.scss --check --log-level error", "vite": "vite", - "eslint": "eslint", "prettier": "prettier", "parse-svgs": "svgr --no-index --jsx-runtime 'automatic' --svgo-config ./svgo.config.json --prettier-config ./.prettierrc --out-dir ./src/shared/components/svg/ --typescript ./src/shared/images/svg/", "svgr": "svgr" @@ -65,6 +66,7 @@ "zustand": "^4.5.7" }, "devDependencies": { + "@biomejs/biome": "2.1.2", "@svgr/cli": "^8.1.0", "@tanstack/react-query": "^4.40.1", "@tanstack/react-query-devtools": "^4.40.1", @@ -73,27 +75,15 @@ "@types/node": "^20.19.9", "@types/react": "^18.3.23", "@types/react-dom": "^18.3.7", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-react": "^4.7.0", "@vitejs/plugin-react-swc": "^3.11.0", "autoprefixer": "^10.4.21", - "eslint": "^8.57.1", - "eslint-config-prettier": "^8.10.2", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-prettier": "^5.5.3", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.20", - "eslint-plugin-simple-import-sort": "^10.0.0", "npm-run-all": "^4.1.5", "postcss": "^8.5.6", "prettier": "^3.6.2", "sass": "~1.70.0", - "typedoc": "^0.24.8", "typesafe-i18n": "^5.26.2", "typescript": "^5.8.3", - "typescript-eslint-language-service": "^5.0.5", "vite": "^4.5.14" } } diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 9be0cfc1..5fb5541b 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -87,6 +87,9 @@ importers: specifier: ^4.5.7 version: 4.5.7(@types/react@18.3.23)(react@18.3.1) devDependencies: + '@biomejs/biome': + specifier: 2.1.2 + version: 2.1.2 '@svgr/cli': specifier: ^8.1.0 version: 8.1.0(typescript@5.8.3) @@ -111,12 +114,6 @@ importers: '@types/react-dom': specifier: ^18.3.7 version: 18.3.7(@types/react@18.3.23) - '@typescript-eslint/eslint-plugin': - specifier: ^6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/parser': - specifier: ^6.21.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.8.3) '@vitejs/plugin-react': specifier: ^4.7.0 version: 4.7.0(vite@4.5.14(@types/node@20.19.9)(sass@1.70.0)) @@ -126,30 +123,6 @@ importers: autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.6) - eslint: - specifier: ^8.57.1 - version: 8.57.1 - eslint-config-prettier: - specifier: ^8.10.2 - version: 8.10.2(eslint@8.57.1) - eslint-plugin-import: - specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1) - eslint-plugin-prettier: - specifier: ^5.5.3 - version: 5.5.3(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2) - eslint-plugin-react: - specifier: ^7.37.5 - version: 7.37.5(eslint@8.57.1) - eslint-plugin-react-hooks: - specifier: ^4.6.2 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.20 - version: 0.4.20(eslint@8.57.1) - eslint-plugin-simple-import-sort: - specifier: ^10.0.0 - version: 10.0.0(eslint@8.57.1) npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -162,9 +135,6 @@ importers: sass: specifier: ~1.70.0 version: 1.70.0 - typedoc: - specifier: ^0.24.8 - version: 0.24.8(typescript@5.8.3) typesafe-i18n: specifier: ^5.26.2 version: 5.26.2(typescript@5.8.3) @@ -267,6 +237,59 @@ packages: resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} engines: {node: '>=6.9.0'} + '@biomejs/biome@2.1.2': + resolution: {integrity: sha512-yq8ZZuKuBVDgAS76LWCfFKHSYIAgqkxVB3mGVVpOe2vSkUTs7xG46zXZeNPRNVjiJuw0SZ3+J2rXiYx0RUpfGg==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.1.2': + resolution: {integrity: sha512-leFAks64PEIjc7MY/cLjE8u5OcfBKkcDB0szxsWUB4aDfemBep1WVKt0qrEyqZBOW8LPHzrFMyDl3FhuuA0E7g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.1.2': + resolution: {integrity: sha512-Nmmv7wRX5Nj7lGmz0FjnWdflJg4zii8Ivruas6PBKzw5SJX/q+Zh2RfnO+bBnuKLXpj8kiI2x2X12otpH6a32A==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.1.2': + resolution: {integrity: sha512-qgHvafhjH7Oca114FdOScmIKf1DlXT1LqbOrrbR30kQDLFPEOpBG0uzx6MhmsrmhGiCFCr2obDamu+czk+X0HQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.1.2': + resolution: {integrity: sha512-NWNy2Diocav61HZiv2enTQykbPP/KrA/baS7JsLSojC7Xxh2nl9IczuvE5UID7+ksRy2e7yH7klm/WkA72G1dw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.1.2': + resolution: {integrity: sha512-xlB3mU14ZUa3wzLtXfmk2IMOGL+S0aHFhSix/nssWS/2XlD27q+S6f0dlQ8WOCbYoXcuz8BCM7rCn2lxdTrlQA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.1.2': + resolution: {integrity: sha512-Km/UYeVowygTjpX6sGBzlizjakLoMQkxWbruVZSNE6osuSI63i4uCeIL+6q2AJlD3dxoiBJX70dn1enjQnQqwA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.1.2': + resolution: {integrity: sha512-G8KWZli5ASOXA3yUQgx+M4pZRv3ND16h77UsdunUL17uYpcL/UC7RkWTdkfvMQvogVsAuz5JUcBDjgZHXxlKoA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.1.2': + resolution: {integrity: sha512-9zajnk59PMpjBkty3bK2IrjUsUHvqe9HWwyAWQBjGLE7MIBjbX2vwv1XPEhmO2RRuGoTkVx3WCanHrjAytICLA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@emotion/is-prop-valid@0.8.8': resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} @@ -490,10 +513,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@pkgr/core@0.2.9': - resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@remix-run/router@1.23.0': resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} engines: {node: '>=14.0.0'} @@ -501,9 +520,6 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@stablelib/base64@1.0.1': resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} @@ -739,12 +755,6 @@ packages: '@types/hast@2.3.10': resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} @@ -771,23 +781,9 @@ packages: '@types/react@18.3.23': resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} - '@types/semver@7.7.0': - resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} - '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - '@typescript-eslint/eslint-plugin@6.21.0': - resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/parser@6.21.0': resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -802,16 +798,6 @@ packages: resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} - '@typescript-eslint/type-utils@6.21.0': - resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/types@6.21.0': resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -825,12 +811,6 @@ packages: typescript: optional: true - '@typescript-eslint/utils@6.21.0': - resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - '@typescript-eslint/visitor-keys@6.21.0': resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} @@ -866,9 +846,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-sequence-parser@1.1.3: - resolution: {integrity: sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw==} - ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -891,34 +868,10 @@ packages: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.4: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} @@ -1113,14 +1066,6 @@ packages: dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} @@ -1164,10 +1109,6 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -1214,10 +1155,6 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} - es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -1226,10 +1163,6 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - es-to-primitive@1.3.0: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} @@ -1251,82 +1184,6 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@8.10.2: - resolution: {integrity: sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-prettier@5.5.3: - resolution: {integrity: sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-plugin-react-hooks@4.6.2: - resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - - eslint-plugin-react-refresh@0.4.20: - resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} - peerDependencies: - eslint: '>=8.40' - - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - - eslint-plugin-simple-import-sort@10.0.0: - resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} - peerDependencies: - eslint: '>=5.0.0' - eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1371,9 +1228,6 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -1746,10 +1600,6 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1777,22 +1627,11 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1831,14 +1670,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lunr@2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - - marked@4.3.0: - resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} - engines: {node: '>= 12'} - hasBin: true - math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -1962,13 +1793,6 @@ packages: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -2032,22 +1856,6 @@ packages: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2141,10 +1949,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} @@ -2269,10 +2073,6 @@ packages: engines: {node: '>= 0.4'} hasBin: true - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2362,9 +2162,6 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} - shiki@0.14.7: - resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -2414,17 +2211,10 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} - string.prototype.padend@3.1.6: resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} engines: {node: '>= 0.4'} - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - string.prototype.trim@1.2.10: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} @@ -2486,10 +2276,6 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - synckit@0.11.11: - resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} - engines: {node: ^14.18.0 || >=16.0.0} - tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} @@ -2512,9 +2298,6 @@ packages: peerDependencies: typescript: '>=4.2.0' - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -2542,13 +2325,6 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typedoc@0.24.8: - resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==} - engines: {node: '>= 14.14'} - hasBin: true - peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x - typesafe-i18n@5.26.2: resolution: {integrity: sha512-2QAriFmiY5JwUAJtG7yufoE/XZ1aFBY++wj7YFS2yo89a3jLBfKoWSdq5JfQYk1V2BS7V2c/u+KEcaCQoE65hw==} hasBin: true @@ -2658,12 +2434,6 @@ packages: terser: optional: true - vscode-oniguruma@1.7.0: - resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} - - vscode-textmate@8.0.0: - resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} - which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -2840,6 +2610,41 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@biomejs/biome@2.1.2': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.1.2 + '@biomejs/cli-darwin-x64': 2.1.2 + '@biomejs/cli-linux-arm64': 2.1.2 + '@biomejs/cli-linux-arm64-musl': 2.1.2 + '@biomejs/cli-linux-x64': 2.1.2 + '@biomejs/cli-linux-x64-musl': 2.1.2 + '@biomejs/cli-win32-arm64': 2.1.2 + '@biomejs/cli-win32-x64': 2.1.2 + + '@biomejs/cli-darwin-arm64@2.1.2': + optional: true + + '@biomejs/cli-darwin-x64@2.1.2': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.1.2': + optional: true + + '@biomejs/cli-linux-arm64@2.1.2': + optional: true + + '@biomejs/cli-linux-x64-musl@2.1.2': + optional: true + + '@biomejs/cli-linux-x64@2.1.2': + optional: true + + '@biomejs/cli-win32-arm64@2.1.2': + optional: true + + '@biomejs/cli-win32-x64@2.1.2': + optional: true + '@emotion/is-prop-valid@0.8.8': dependencies: '@emotion/memoize': 0.7.4 @@ -3006,14 +2811,10 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@pkgr/core@0.2.9': {} - '@remix-run/router@1.23.0': {} '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rtsao/scc@1.1.0': {} - '@stablelib/base64@1.0.1': {} '@stablelib/binary@1.0.1': @@ -3250,10 +3051,6 @@ snapshots: dependencies: '@types/unist': 2.0.11 - '@types/json-schema@7.0.15': {} - - '@types/json5@0.0.29': {} - '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.20 @@ -3281,30 +3078,8 @@ snapshots: '@types/prop-types': 15.7.15 csstype: 3.1.3 - '@types/semver@7.7.0': {} - '@types/unist@2.0.11': {} - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.1 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - semver: 7.7.2 - ts-api-utils: 1.4.3(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 @@ -3323,18 +3098,6 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - debug: 4.4.1 - eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/types@6.21.0': {} '@typescript-eslint/typescript-estree@6.21.0(typescript@5.8.3)': @@ -3352,20 +3115,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) - '@types/json-schema': 7.0.15 - '@types/semver': 7.7.0 - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - eslint: 8.57.1 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - typescript - '@typescript-eslint/visitor-keys@6.21.0': dependencies: '@typescript-eslint/types': 6.21.0 @@ -3408,8 +3157,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-sequence-parser@1.1.3: {} - ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -3432,60 +3179,8 @@ snapshots: call-bound: 1.0.4 is-array-buffer: 3.0.5 - array-includes@3.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - array-union@2.1.0: {} - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.tosorted@1.1.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-shim-unscopables: 1.1.0 - arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 @@ -3707,10 +3402,6 @@ snapshots: dayjs@1.11.13: {} - debug@3.2.7: - dependencies: - ms: 2.1.3 - debug@4.4.1: dependencies: ms: 2.1.3 @@ -3745,10 +3436,6 @@ snapshots: dependencies: path-type: 4.0.0 - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - doctrine@3.0.0: dependencies: esutils: 2.0.3 @@ -3851,25 +3538,6 @@ snapshots: es-errors@1.3.0: {} - es-iterator-helpers@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.1.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 - es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -3881,10 +3549,6 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 @@ -3922,100 +3586,6 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@8.10.2(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-prettier@5.5.3(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2): - dependencies: - eslint: 8.57.1 - prettier: 3.6.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.11.11 - optionalDependencies: - eslint-config-prettier: 8.10.2(eslint@8.57.1) - - eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-react-refresh@0.4.20(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - - eslint-plugin-react@7.37.5(eslint@8.57.1): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 8.57.1 - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - - eslint-plugin-simple-import-sort@10.0.0(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - eslint-scope@7.2.2: dependencies: esrecurse: 4.3.0 @@ -4100,8 +3670,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-diff@1.3.0: {} - fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4475,15 +4043,6 @@ snapshots: isexe@2.0.0: {} - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 - js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -4502,21 +4061,8 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json5@1.0.2: - dependencies: - minimist: 1.2.8 - json5@2.2.3: {} - jsonc-parser@3.3.1: {} - - jsx-ast-utils@3.3.5: - dependencies: - array-includes: 3.1.9 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -4557,10 +4103,6 @@ snapshots: dependencies: yallist: 3.1.1 - lunr@2.3.9: {} - - marked@4.3.0: {} - math-intrinsics@1.1.0: {} mdast-util-definitions@5.1.2: @@ -4769,12 +4311,6 @@ snapshots: dependencies: brace-expansion: 2.0.2 - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist@1.2.8: {} - mri@1.2.0: {} ms@2.1.3: {} @@ -4838,33 +4374,6 @@ snapshots: has-symbols: 1.1.0 object-keys: 1.1.1 - object.entries@1.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - once@1.4.0: dependencies: wrappy: 1.0.2 @@ -4948,10 +4457,6 @@ snapshots: prelude-ls@1.2.1: {} - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - prettier@2.8.8: {} prettier@3.6.2: {} @@ -5100,12 +4605,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.5: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - reusify@1.1.0: {} rimraf@3.0.2: @@ -5199,13 +4698,6 @@ snapshots: shell-quote@1.8.3: {} - shiki@0.14.7: - dependencies: - ansi-sequence-parser: 1.1.3 - jsonc-parser: 3.3.1 - vscode-oniguruma: 1.7.0 - vscode-textmate: 8.0.0 - side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -5266,22 +4758,6 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - string.prototype.matchall@4.0.12: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.4 - set-function-name: 2.0.2 - side-channel: 1.1.0 - string.prototype.padend@3.1.6: dependencies: call-bind: 1.0.8 @@ -5289,11 +4765,6 @@ snapshots: es-abstract: 1.24.0 es-object-atoms: 1.1.1 - string.prototype.repeat@1.0.0: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.24.0 - string.prototype.trim@1.2.10: dependencies: call-bind: 1.0.8 @@ -5365,10 +4836,6 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - synckit@0.11.11: - dependencies: - '@pkgr/core': 0.2.9 - tabbable@6.2.0: {} text-table@0.2.0: {} @@ -5385,13 +4852,6 @@ snapshots: dependencies: typescript: 5.8.3 - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - tslib@2.8.1: {} type-check@0.4.0: @@ -5433,14 +4893,6 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typedoc@0.24.8(typescript@5.8.3): - dependencies: - lunr: 2.3.9 - marked: 4.3.0 - minimatch: 9.0.5 - shiki: 0.14.7 - typescript: 5.8.3 - typesafe-i18n@5.26.2(typescript@5.8.3): dependencies: typescript: 5.8.3 @@ -5550,10 +5002,6 @@ snapshots: fsevents: 2.3.3 sass: 1.70.0 - vscode-oniguruma@1.7.0: {} - - vscode-textmate@8.0.0: {} - which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 diff --git a/web/src/components/LogoContainer/style.scss b/web/src/components/LogoContainer/style.scss index 3f2ceb82..b0421db1 100644 --- a/web/src/components/LogoContainer/style.scss +++ b/web/src/components/LogoContainer/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .logo-container { display: flex; flex-flow: row; diff --git a/web/src/i18n/formatters.ts b/web/src/i18n/formatters.ts index 2fec895d..10cd025d 100644 --- a/web/src/i18n/formatters.ts +++ b/web/src/i18n/formatters.ts @@ -1,12 +1,13 @@ import type { FormattersInitializer } from 'typesafe-i18n'; -import type { Formatters,Locales } from './i18n-types'; +import type { Formatters, Locales } from './i18n-types'; -export const initFormatters: FormattersInitializer = (locale: Locales) => { +export const initFormatters: FormattersInitializer = ( + locale: Locales, +) => { + const formatters: Formatters = { + // add your formatter functions here + }; - const formatters: Formatters = { - // add your formatter functions here - }; - - return formatters; + return formatters; }; diff --git a/web/src/i18n/i18n-react.tsx b/web/src/i18n/i18n-react.tsx index f113051f..4b7b8680 100644 --- a/web/src/i18n/i18n-react.tsx +++ b/web/src/i18n/i18n-react.tsx @@ -1,16 +1,27 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { useContext } from 'react' -import { initI18nReact } from 'typesafe-i18n/react' -import type { I18nContextType } from 'typesafe-i18n/react' -import type { Formatters, Locales, TranslationFunctions, Translations } from './i18n-types' -import { loadedFormatters, loadedLocales } from './i18n-util' +import { useContext } from 'react'; +import type { I18nContextType } from 'typesafe-i18n/react'; +import { initI18nReact } from 'typesafe-i18n/react'; +import type { + Formatters, + Locales, + TranslationFunctions, + Translations, +} from './i18n-types'; +import { loadedFormatters, loadedLocales } from './i18n-util'; -const { component: TypesafeI18n, context: I18nContext } = initI18nReact(loadedLocales, loadedFormatters) +const { component: TypesafeI18n, context: I18nContext } = initI18nReact< + Locales, + Translations, + TranslationFunctions, + Formatters +>(loadedLocales, loadedFormatters); -const useI18nContext = (): I18nContextType => useContext(I18nContext) +const useI18nContext = (): I18nContextType => + useContext(I18nContext); -export { I18nContext, useI18nContext } +export { I18nContext, useI18nContext }; -export default TypesafeI18n +export default TypesafeI18n; diff --git a/web/src/i18n/i18n-types.ts b/web/src/i18n/i18n-types.ts index fba01d27..d1f51260 100644 --- a/web/src/i18n/i18n-types.ts +++ b/web/src/i18n/i18n-types.ts @@ -1,172 +1,175 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import type { BaseTranslation as BaseTranslationType, LocalizedString, RequiredParams } from 'typesafe-i18n' +import type { + BaseTranslation as BaseTranslationType, + LocalizedString, + RequiredParams, +} from 'typesafe-i18n'; -export type BaseTranslation = BaseTranslationType -export type BaseLocale = 'en' +export type BaseTranslation = BaseTranslationType; +export type BaseLocale = 'en'; -export type Locales = - | 'en' +export type Locales = 'en'; -export type Translation = RootTranslation +export type Translation = RootTranslation; -export type Translations = RootTranslation +export type Translations = RootTranslation; type RootTranslation = { - time: { - seconds: { - /** - * s​e​c​o​n​d - */ - singular: string - /** - * s​e​c​o​n​d​s - */ - prular: string - } - minutes: { - /** - * m​i​n​u​t​e - */ - singular: string - /** - * m​i​n​u​t​e​s - */ - prular: string - } - } - form: { - errors: { - /** - * F​i​e​l​d​ ​i​s​ ​i​n​v​a​l​i​d - */ - invalid: string - /** - * E​n​t​e​r​ ​a​ ​v​a​l​i​d​ ​E​-​m​a​i​l - */ - email: string - /** - * F​i​e​l​d​ ​i​s​ ​r​e​q​u​i​r​e​d - */ - required: string - /** - * M​i​n​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} - * @param {number} length - */ - minLength: RequiredParams<'length'> - /** - * M​a​x​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} - * @param {number} length - */ - maxLength: RequiredParams<'length'> - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​s​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r - */ - specialsRequired: string - /** - * S​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r​s​ ​a​r​e​ ​f​o​r​b​i​d​d​e​n - */ - specialsForbidden: string - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​n​u​m​b​e​r​ ​r​e​q​u​i​r​e​d - */ - numberRequired: string - password: { - /** - * P​l​e​a​s​e​ ​c​o​r​r​e​c​t​ ​t​h​e​ ​f​o​l​l​o​w​i​n​g​: - */ - floatingTitle: string - } - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​l​o​w​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r - */ - oneLower: string - /** - * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​u​p​p​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r - */ - oneUpper: string - } - } - common: { - controls: { - /** - * B​a​c​k - */ - back: string - /** - * N​e​x​t - */ - next: string - /** - * S​u​b​m​i​t - */ - submit: string - } - } - components: { - adminInfo: { - /** - * Y​o​u​r​ ​a​d​m​i​n - */ - title: string - } - } - pages: { - enrollment: { - sideBar: { - /** - * E​n​r​o​l​l​m​e​n​t - */ - title: string - steps: { - /** - * W​e​l​c​o​m​e - */ - welcome: string - /** - * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n - */ - verification: string - /** - * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d - */ - password: string - /** - * C​o​n​f​i​g​u​r​e​ ​V​P​N - */ - vpn: string - /** - * F​i​n​i​s​h - */ - finish: string - } - /** - * A​p​p​l​i​c​a​t​i​o​n​ ​v​e​r​s​i​o​n - */ - appVersion: string - } - stepsIndicator: { - /** - * S​t​e​p - */ - step: string - /** - * o​f - */ - of: string - } - /** - * T​i​m​e​ ​l​e​f​t - */ - timeLeft: string - steps: { - welcome: { - /** - * H​e​l​l​o​,​ ​{​n​a​m​e​} - * @param {string} name - */ - title: RequiredParams<'name'> - /** + time: { + seconds: { + /** + * s​e​c​o​n​d + */ + singular: string; + /** + * s​e​c​o​n​d​s + */ + prular: string; + }; + minutes: { + /** + * m​i​n​u​t​e + */ + singular: string; + /** + * m​i​n​u​t​e​s + */ + prular: string; + }; + }; + form: { + errors: { + /** + * F​i​e​l​d​ ​i​s​ ​i​n​v​a​l​i​d + */ + invalid: string; + /** + * E​n​t​e​r​ ​a​ ​v​a​l​i​d​ ​E​-​m​a​i​l + */ + email: string; + /** + * F​i​e​l​d​ ​i​s​ ​r​e​q​u​i​r​e​d + */ + required: string; + /** + * M​i​n​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} + * @param {number} length + */ + minLength: RequiredParams<'length'>; + /** + * M​a​x​ ​l​e​n​g​t​h​ ​o​f​ ​{​l​e​n​g​t​h​} + * @param {number} length + */ + maxLength: RequiredParams<'length'>; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​s​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r + */ + specialsRequired: string; + /** + * S​p​e​c​i​a​l​ ​c​h​a​r​a​c​t​e​r​s​ ​a​r​e​ ​f​o​r​b​i​d​d​e​n + */ + specialsForbidden: string; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​n​u​m​b​e​r​ ​r​e​q​u​i​r​e​d + */ + numberRequired: string; + password: { + /** + * P​l​e​a​s​e​ ​c​o​r​r​e​c​t​ ​t​h​e​ ​f​o​l​l​o​w​i​n​g​: + */ + floatingTitle: string; + }; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​l​o​w​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r + */ + oneLower: string; + /** + * A​t​ ​l​e​a​s​t​ ​o​n​e​ ​u​p​p​e​r​ ​c​a​s​e​ ​c​h​a​r​a​c​t​e​r + */ + oneUpper: string; + }; + }; + common: { + controls: { + /** + * B​a​c​k + */ + back: string; + /** + * N​e​x​t + */ + next: string; + /** + * S​u​b​m​i​t + */ + submit: string; + }; + }; + components: { + adminInfo: { + /** + * Y​o​u​r​ ​a​d​m​i​n + */ + title: string; + }; + }; + pages: { + enrollment: { + sideBar: { + /** + * E​n​r​o​l​l​m​e​n​t + */ + title: string; + steps: { + /** + * W​e​l​c​o​m​e + */ + welcome: string; + /** + * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n + */ + verification: string; + /** + * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d + */ + password: string; + /** + * C​o​n​f​i​g​u​r​e​ ​V​P​N + */ + vpn: string; + /** + * F​i​n​i​s​h + */ + finish: string; + }; + /** + * A​p​p​l​i​c​a​t​i​o​n​ ​v​e​r​s​i​o​n + */ + appVersion: string; + }; + stepsIndicator: { + /** + * S​t​e​p + */ + step: string; + /** + * o​f + */ + of: string; + }; + /** + * T​i​m​e​ ​l​e​f​t + */ + timeLeft: string; + steps: { + welcome: { + /** + * H​e​l​l​o​,​ ​{​n​a​m​e​} + * @param {string} name + */ + title: RequiredParams<'name'>; + /** * ​I​n​ ​o​r​d​e​r​ ​t​o​ ​g​a​i​n​ ​a​c​c​e​s​s​ ​t​o​ ​t​h​e​ ​c​o​m​p​a​n​y​ ​i​n​f​r​a​s​t​r​u​c​t​u​r​e​,​ ​w​e​ ​r​e​q​u​i​r​e​ ​y​o​u​ ​t​o​ ​c​o​m​p​l​e​t​e​ ​t​h​i​s​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s​.​ ​D​u​r​i​n​g​ ​t​h​i​s​ ​p​r​o​c​e​s​s​,​ ​y​o​u​ ​w​i​l​l​ ​n​e​e​d​ ​t​o​:​ ​ @@ -178,124 +181,124 @@ type RootTranslation = { ​I​f​ ​y​o​u​ ​h​a​v​e​ ​a​n​y​ ​q​u​e​s​t​i​o​n​s​,​ ​p​l​e​a​s​e​ ​c​o​n​s​u​l​t​ ​y​o​u​r​ ​a​s​s​i​g​n​e​d​ ​a​d​m​i​n​.​A​l​l​ ​n​e​c​e​s​s​a​r​y​ ​i​n​f​o​r​m​a​t​i​o​n​ ​c​a​n​ ​b​e​ ​f​o​u​n​d​ ​a​t​ ​t​h​e​ ​b​o​t​t​o​m​ ​o​f​ ​t​h​e​ ​s​i​d​e​b​a​r​. * @param {string} time */ - explanation: RequiredParams<'time'> - } - dataVerification: { - /** - * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n - */ - title: string - /** - * P​l​e​a​s​e​,​ ​c​h​e​c​k​ ​y​o​u​r​ ​d​a​t​a​.​ ​I​f​ ​a​n​y​t​h​i​n​g​ ​i​s​ ​w​r​o​n​g​,​ ​n​o​t​i​f​y​ ​y​o​u​r​ ​a​d​m​i​n​ ​a​f​t​e​r​ ​y​o​u​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​. - */ - messageBox: string - form: { - fields: { - firstName: { - /** - * N​a​m​e - */ - label: string - } - lastName: { - /** - * L​a​s​t​ ​n​a​m​e - */ - label: string - } - email: { - /** - * E​-​m​a​i​l - */ - label: string - } - phone: { - /** - * P​h​o​n​e​ ​n​u​m​b​e​r - */ - label: string - } - } - } - } - password: { - /** - * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d - */ - title: string - form: { - fields: { - password: { - /** - * C​r​e​a​t​e​ ​n​e​w​ ​p​a​s​s​w​o​r​d - */ - label: string - } - repeat: { - /** - * C​o​n​f​i​r​m​ ​n​e​w​ ​p​a​s​s​w​o​r​d - */ - label: string - errors: { - /** - * P​a​s​s​w​o​r​d​s​ ​a​r​e​n​'​t​ ​m​a​t​c​h​i​n​g - */ - matching: string - } - } - } - } - } - deviceSetup: { - /** - * *​ ​T​h​i​s​ ​s​t​e​p​ ​i​s​ ​O​P​T​I​O​N​A​L​.​ ​Y​o​u​ ​c​a​n​ ​s​k​i​p​ ​i​t​ ​i​f​ ​y​o​u​ ​w​i​s​h​.​ ​T​h​i​s​ ​c​a​n​ ​b​e​ ​c​o​n​f​i​g​u​r​e​d​ ​l​a​t​e​r​ ​i​n​ ​d​e​f​g​u​a​r​d​. - */ - optionalMessage: string - cards: { - device: { - /** - * C​o​n​f​i​g​u​r​e​ ​y​o​u​r​ ​d​e​v​i​c​e​ ​f​o​r​ ​V​P​N - */ - title: string - create: { - /** - * C​r​e​a​t​e​ ​C​o​n​f​i​g​u​r​a​t​i​o​n - */ - submit: string - /** - * P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​y​o​u​ ​h​a​v​e​ ​t​o​ ​d​o​w​n​l​o​a​d​ ​t​h​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​n​o​w​,​ ​s​i​n​c​e​ ​w​e​ ​d​o​ ​n​o​t​ ​s​t​o​r​e​ ​y​o​u​r​ ​p​r​i​v​a​t​e​ ​k​e​y​.​ ​A​f​t​e​r​ ​t​h​i​s​ ​d​i​a​l​o​g​ ​i​s​ ​c​l​o​s​e​d​,​ ​y​o​u​ ​w​i​l​l​ ​n​o​t​ ​b​e​ ​a​b​l​e​ ​t​o​ ​g​e​t​ ​y​o​u​r​ ​f​u​l​l​l​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​(​w​i​t​h​ ​p​r​i​v​a​t​e​ ​k​e​y​s​,​ ​o​n​l​y​ ​b​l​a​n​k​ ​t​e​m​p​l​a​t​e​)​. - */ - messageBox: string - form: { - fields: { - name: { - /** - * D​e​v​i​c​e​ ​N​a​m​e - */ - label: string - } - 'public': { - /** - * M​y​ ​P​u​b​l​i​c​ ​K​e​y - */ - label: string - } - toggle: { - /** - * G​e​n​e​r​a​t​e​ ​k​e​y​ ​p​a​i​r - */ - generate: string - /** - * U​s​e​ ​m​y​ ​o​w​n​ ​p​u​b​l​i​c​ ​k​e​y - */ - own: string - } - } - } - } - config: { - messageBox: { - /** + explanation: RequiredParams<'time'>; + }; + dataVerification: { + /** + * D​a​t​a​ ​v​e​r​i​f​i​c​a​t​i​o​n + */ + title: string; + /** + * P​l​e​a​s​e​,​ ​c​h​e​c​k​ ​y​o​u​r​ ​d​a​t​a​.​ ​I​f​ ​a​n​y​t​h​i​n​g​ ​i​s​ ​w​r​o​n​g​,​ ​n​o​t​i​f​y​ ​y​o​u​r​ ​a​d​m​i​n​ ​a​f​t​e​r​ ​y​o​u​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​. + */ + messageBox: string; + form: { + fields: { + firstName: { + /** + * N​a​m​e + */ + label: string; + }; + lastName: { + /** + * L​a​s​t​ ​n​a​m​e + */ + label: string; + }; + email: { + /** + * E​-​m​a​i​l + */ + label: string; + }; + phone: { + /** + * P​h​o​n​e​ ​n​u​m​b​e​r + */ + label: string; + }; + }; + }; + }; + password: { + /** + * C​r​e​a​t​e​ ​p​a​s​s​w​o​r​d + */ + title: string; + form: { + fields: { + password: { + /** + * C​r​e​a​t​e​ ​n​e​w​ ​p​a​s​s​w​o​r​d + */ + label: string; + }; + repeat: { + /** + * C​o​n​f​i​r​m​ ​n​e​w​ ​p​a​s​s​w​o​r​d + */ + label: string; + errors: { + /** + * P​a​s​s​w​o​r​d​s​ ​a​r​e​n​'​t​ ​m​a​t​c​h​i​n​g + */ + matching: string; + }; + }; + }; + }; + }; + deviceSetup: { + /** + * *​ ​T​h​i​s​ ​s​t​e​p​ ​i​s​ ​O​P​T​I​O​N​A​L​.​ ​Y​o​u​ ​c​a​n​ ​s​k​i​p​ ​i​t​ ​i​f​ ​y​o​u​ ​w​i​s​h​.​ ​T​h​i​s​ ​c​a​n​ ​b​e​ ​c​o​n​f​i​g​u​r​e​d​ ​l​a​t​e​r​ ​i​n​ ​d​e​f​g​u​a​r​d​. + */ + optionalMessage: string; + cards: { + device: { + /** + * C​o​n​f​i​g​u​r​e​ ​y​o​u​r​ ​d​e​v​i​c​e​ ​f​o​r​ ​V​P​N + */ + title: string; + create: { + /** + * C​r​e​a​t​e​ ​C​o​n​f​i​g​u​r​a​t​i​o​n + */ + submit: string; + /** + * P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​y​o​u​ ​h​a​v​e​ ​t​o​ ​d​o​w​n​l​o​a​d​ ​t​h​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​n​o​w​,​ ​s​i​n​c​e​ ​w​e​ ​d​o​ ​n​o​t​ ​s​t​o​r​e​ ​y​o​u​r​ ​p​r​i​v​a​t​e​ ​k​e​y​.​ ​A​f​t​e​r​ ​t​h​i​s​ ​d​i​a​l​o​g​ ​i​s​ ​c​l​o​s​e​d​,​ ​y​o​u​ ​w​i​l​l​ ​n​o​t​ ​b​e​ ​a​b​l​e​ ​t​o​ ​g​e​t​ ​y​o​u​r​ ​f​u​l​l​l​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​(​w​i​t​h​ ​p​r​i​v​a​t​e​ ​k​e​y​s​,​ ​o​n​l​y​ ​b​l​a​n​k​ ​t​e​m​p​l​a​t​e​)​. + */ + messageBox: string; + form: { + fields: { + name: { + /** + * D​e​v​i​c​e​ ​N​a​m​e + */ + label: string; + }; + public: { + /** + * M​y​ ​P​u​b​l​i​c​ ​K​e​y + */ + label: string; + }; + toggle: { + /** + * G​e​n​e​r​a​t​e​ ​k​e​y​ ​p​a​i​r + */ + generate: string; + /** + * U​s​e​ ​m​y​ ​o​w​n​ ​p​u​b​l​i​c​ ​k​e​y + */ + own: string; + }; + }; + }; + }; + config: { + messageBox: { + /** * ​ ​ ​ ​ ​ ​ ​ ​<​p​>​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​y​o​u​ ​h​a​v​e​ ​t​o​ ​d​o​w​n​l​o​a​d​ ​t​h​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​n​o​w​,​ @@ -305,306 +308,306 @@ type RootTranslation = { ​ ​ ​ ​ ​ ​ ​ ​ ​<​/​p​>​ */ - auto: string - /** + auto: string; + /** * ​ ​ ​ ​ ​ ​ ​ ​ ​<​p​>​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​P​l​e​a​s​e​ ​b​e​ ​a​d​v​i​s​e​d​ ​t​h​a​t​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​p​r​o​v​i​d​e​d​ ​h​e​r​e​ ​<​s​t​r​o​n​g​>​ ​d​o​e​s​ ​n​o​t​ ​i​n​c​l​u​d​e​ ​p​r​i​v​a​t​e​ ​k​e​y​ ​a​n​d​ ​u​s​e​s​ ​p​u​b​l​i​c​ ​k​e​y​ ​t​o​ ​f​i​l​l​ ​i​t​'​s​ ​p​l​a​c​e​ ​<​/​s​t​r​o​n​g​>​ ​y​o​u​ ​w​i​l​l​ ​n​e​e​d​ ​t​o​ ​r​e​p​a​l​c​e​ ​i​t​ ​o​n​ ​y​o​u​r​ ​o​w​n​ ​f​o​r​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​t​o​ ​w​o​r​k​ ​p​r​o​p​e​r​l​y​.​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​/​p​>​ */ - manual: string - } - /** - * M​y​ ​D​e​v​i​c​e​ ​N​a​m​e - */ - deviceNameLabel: string - /** - * Y​o​u​ ​d​o​n​'​t​ ​h​a​v​e​ ​a​c​c​e​s​s​ ​t​o​ ​a​n​y​ ​n​e​t​w​o​r​k​s - */ - noNetworksMessage: string - /** - * U​s​e​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​b​e​l​o​w​ ​b​y​ ​s​c​a​n​n​i​n​g​ ​Q​R​ ​C​o​d​e​ ​o​r​ ​i​m​p​o​r​t​i​n​g​ ​i​t​ ​a​s​ ​f​i​l​e​ ​o​n​ ​y​o​u​r​ ​d​e​v​i​c​e​s​ ​W​i​r​e​G​u​a​r​d​ ​a​p​p​. - */ - cardTitle: string - card: { - /** - * C​o​n​f​i​g​ ​f​i​l​e​ ​f​o​r​ ​l​o​c​a​t​i​o​n - */ - selectLabel: string - } - } - } - guide: { - /** - * Q​u​i​c​k​ ​G​u​i​d​e - */ - title: string - /** - * T​h​i​s​ ​q​u​i​c​k​ ​g​u​i​d​e​ ​w​i​l​l​ ​h​e​l​p​ ​y​o​u​ ​w​i​t​h​ ​d​e​v​i​c​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​. - */ - messageBox: string - /** - * S​t​e​p​ ​{​s​t​e​p​}​: - * @param {number} step - */ - step: RequiredParams<'step'> - steps: { - wireguard: { - /** - * D​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​W​i​r​e​G​u​a​r​d​ ​c​l​i​e​n​t​ ​o​n​ ​y​o​u​r​ ​c​o​m​p​p​u​t​e​r​ ​o​r​ ​a​p​p​ ​o​n​ ​p​h​o​n​e​. - */ - content: string - /** - * D​o​w​n​l​o​a​d​ ​W​i​r​e​G​u​a​r​d - */ - button: string - } - /** - * D​o​w​n​l​o​a​d​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​t​o​ ​y​o​u​r​ ​d​e​v​i​c​e​. - */ - downloadConfig: string - /** + manual: string; + }; + /** + * M​y​ ​D​e​v​i​c​e​ ​N​a​m​e + */ + deviceNameLabel: string; + /** + * Y​o​u​ ​d​o​n​'​t​ ​h​a​v​e​ ​a​c​c​e​s​s​ ​t​o​ ​a​n​y​ ​n​e​t​w​o​r​k​s + */ + noNetworksMessage: string; + /** + * U​s​e​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​b​e​l​o​w​ ​b​y​ ​s​c​a​n​n​i​n​g​ ​Q​R​ ​C​o​d​e​ ​o​r​ ​i​m​p​o​r​t​i​n​g​ ​i​t​ ​a​s​ ​f​i​l​e​ ​o​n​ ​y​o​u​r​ ​d​e​v​i​c​e​s​ ​W​i​r​e​G​u​a​r​d​ ​a​p​p​. + */ + cardTitle: string; + card: { + /** + * C​o​n​f​i​g​ ​f​i​l​e​ ​f​o​r​ ​l​o​c​a​t​i​o​n + */ + selectLabel: string; + }; + }; + }; + guide: { + /** + * Q​u​i​c​k​ ​G​u​i​d​e + */ + title: string; + /** + * T​h​i​s​ ​q​u​i​c​k​ ​g​u​i​d​e​ ​w​i​l​l​ ​h​e​l​p​ ​y​o​u​ ​w​i​t​h​ ​d​e​v​i​c​e​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​. + */ + messageBox: string; + /** + * S​t​e​p​ ​{​s​t​e​p​}​: + * @param {number} step + */ + step: RequiredParams<'step'>; + steps: { + wireguard: { + /** + * D​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​W​i​r​e​G​u​a​r​d​ ​c​l​i​e​n​t​ ​o​n​ ​y​o​u​r​ ​c​o​m​p​p​u​t​e​r​ ​o​r​ ​a​p​p​ ​o​n​ ​p​h​o​n​e​. + */ + content: string; + /** + * D​o​w​n​l​o​a​d​ ​W​i​r​e​G​u​a​r​d + */ + button: string; + }; + /** + * D​o​w​n​l​o​a​d​ ​p​r​o​v​i​d​e​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​t​o​ ​y​o​u​r​ ​d​e​v​i​c​e​. + */ + downloadConfig: string; + /** * O​p​e​n​ ​W​i​r​e​G​u​a​r​d​ ​a​n​d​ ​s​e​l​e​c​t​ ​"​A​d​d​ ​T​u​n​n​e​l​"​ ​(​I​m​p​o​r​t​ ​t​u​n​n​e​l​(​s​)​ ​f​r​o​m​ ​f​i​l​e​)​.​ ​F​i​n​d​ ​y​o​u​r​ ​D​e​f​g​u​a​r​d​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​f​i​l​e​ ​a​n​d​ ​h​i​t​ ​"​O​K​"​.​ ​O​n​ ​p​h​o​n​e​ ​u​s​e​ ​W​i​r​e​G​u​a​r​d​ ​a​p​p​ ​“​+​”​ ​i​c​o​n​ ​a​n​d​ ​s​c​a​n​ ​Q​R​ ​c​o​d​e​. */ - addTunnel: string - /** - * S​e​l​e​c​t​ ​y​o​u​r​ ​t​u​n​n​e​l​ ​f​r​o​m​ ​t​h​e​ ​l​i​s​t​ ​a​n​d​ ​p​r​e​s​s​ ​"​a​c​t​i​v​a​t​e​"​. - */ - activate: string - /** + addTunnel: string; + /** + * S​e​l​e​c​t​ ​y​o​u​r​ ​t​u​n​n​e​l​ ​f​r​o​m​ ​t​h​e​ ​l​i​s​t​ ​a​n​d​ ​p​r​e​s​s​ ​"​a​c​t​i​v​a​t​e​"​. + */ + activate: string; + /** * ​*​*​G​r​e​a​t​ ​w​o​r​k​ ​-​ ​y​o​u​r​ ​D​e​f​g​u​a​r​d​ ​V​P​N​ ​i​s​ ​n​o​w​ ​a​c​t​i​v​e​!​*​*​ ​ ​I​f​ ​y​o​u​ ​w​a​n​t​ ​t​o​ ​d​i​s​e​n​g​a​g​e​ ​y​o​u​r​ ​V​P​N​ ​c​o​n​n​e​c​t​i​o​n​,​ ​s​i​m​p​l​y​ ​p​r​e​s​s​ ​"​d​e​a​c​t​i​v​a​t​e​"​.​ */ - finish: string - } - } - } - } - finish: { - /** - * C​o​n​f​i​g​u​r​a​t​i​o​n​ ​c​o​m​p​l​e​t​e​d​! - */ - title: string - } - } - } - resetPassword: { - steps: { - email: { - controls: { - /** - * S​e​n​d - */ - send: string - } - /** - * E​n​t​e​r​ ​y​o​u​r​ ​e​-​m​a​i​l - */ - title: string - form: { - fields: { - email: { - /** - * E​-​m​a​i​l - */ - label: string - } - } - } - } - linkSent: { - controls: { - /** - * B​a​c​k​ ​t​o​ ​m​a​i​n​ ​m​e​n​u - */ - back: string - } - /** - * I​f​ ​t​h​e​ ​p​r​o​v​i​d​e​d​ ​e​m​a​i​l​ ​a​d​d​r​e​s​s​ ​i​s​ ​a​s​s​i​g​n​e​d​ ​t​o​ ​a​n​y​ ​a​c​c​o​u​n​t​ ​-​ ​t​h​e​ ​p​a​s​s​w​o​r​d​ ​r​e​s​e​t​ ​w​i​l​l​ ​b​e​ ​i​n​i​t​i​a​t​e​d​ ​a​n​d​ ​y​o​u​ ​w​i​l​l​ ​r​e​c​i​e​v​e​ ​a​n​ ​e​m​a​i​l​ ​w​i​t​h​ ​f​u​r​t​h​e​r​ ​i​s​t​r​u​c​t​i​o​n​s​. - */ - messageBox: string - } - securityCode: { - controls: { - /** - * S​e​n​d​ ​c​o​d​e - */ - sendCode: string - } - /** - * E​n​t​e​r​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e - */ - title: string - /** - * I​n​ ​o​r​d​e​r​ ​t​o​ ​r​e​s​e​t​ ​t​h​e​ ​p​a​s​s​w​o​r​d​,​ ​p​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e​ ​t​h​a​t​ ​w​i​l​l​ ​b​e​ ​s​e​n​t​ ​t​o​ ​y​o​u​r​ ​n​u​m​b​e​r​: - */ - messagebox: string - form: { - fields: { - code: { - /** - * S​e​c​u​r​i​t​y​ ​c​o​d​e - */ - label: string - } - } - } - } - resetPassword: { - /** - * R​e​s​e​t​ ​y​o​u​r​ ​p​a​s​s​w​o​r​d - */ - title: string - controls: { - /** - * R​e​s​e​t​ ​p​a​s​s​w​o​r​d - */ - submit: string - } - form: { - errors: { - /** - * F​i​e​l​d​s​ ​d​o​e​s​n​'​t​ ​m​a​t​c​h - */ - repeat: string - } - fields: { - password: { - /** - * N​e​w​ ​p​a​s​s​w​o​r​d - */ - label: string - } - repeat: { - /** - * C​o​n​f​i​r​m​ ​p​a​s​s​w​o​r​d - */ - label: string - } - } - } - } - resetSuccess: { - controls: { - /** - * R​e​t​u​r​n​ ​t​o​ ​s​e​r​v​i​c​e​s​ ​m​e​n​u - */ - back: string - } - /** - * C​o​n​g​r​a​t​u​l​a​t​i​o​n​s​,​ ​y​o​u​r​ ​n​e​w​ ​p​a​s​s​w​o​r​d​ ​i​s​ ​s​e​t​. - */ - messageBox: string - } - resetFailed: { - controls: { - /** - * R​e​t​u​r​n​ ​t​o​ ​s​t​a​r​t - */ - back: string - } - /** - * T​h​e​ ​e​n​t​e​r​e​d​ ​c​o​d​e​ ​i​s​ ​i​n​v​a​l​i​d​.​ ​P​l​e​a​s​e​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​ ​f​r​o​m​ ​t​h​e​ ​b​e​g​i​n​n​i​n​g​. - */ - messageBox: string - } - } - } - sessionTimeout: { - card: { - /** - * S​e​s​s​i​o​n​ ​t​i​m​e​d​ ​o​u​t - */ - header: string - /** - * S​o​r​r​y​,​ ​y​o​u​ ​h​a​v​e​ ​e​x​c​e​e​d​e​d​ ​t​h​e​ ​t​i​m​e​ ​l​i​m​i​t​ ​t​o​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​.​ ​P​l​e​a​s​e​ ​t​r​y​ ​a​g​a​i​n​.​ ​I​f​ ​y​o​u​ ​n​e​e​d​ ​a​s​s​i​s​t​a​n​c​e​,​ ​p​l​e​a​s​e​ ​w​a​t​c​h​ ​o​u​r​ ​g​u​i​d​e​ ​o​r​ ​c​o​n​t​a​c​t​ ​y​o​u​r​ ​a​d​m​i​n​i​s​t​r​a​t​o​r​. - */ - message: string - } - controls: { - /** - * E​n​t​e​r​ ​n​e​w​ ​t​o​k​e​n - */ - back: string - /** - * C​o​n​t​a​c​t​ ​a​d​m​i​n - */ - contact: string - } - } - token: { - card: { - /** - * P​l​e​a​s​e​,​ ​e​n​t​e​r​ ​y​o​u​r​ ​p​e​r​s​o​n​a​l​ ​e​n​r​o​l​l​m​e​n​t​ ​t​o​k​e​n - */ - title: string - messageBox: { - /** - * Y​o​u​ ​c​a​n​ ​f​i​n​d​ ​t​o​k​e​n​ ​i​n​ ​e​-​m​a​i​l​ ​m​e​s​s​a​g​e​ ​o​r​ ​u​s​e​ ​d​i​r​e​c​t​ ​l​i​n​k​. - */ - email: string - } - form: { - errors: { - token: { - /** - * T​o​k​e​n​ ​i​s​ ​r​e​q​u​i​r​e​d - */ - required: string - } - } - fields: { - token: { - /** - * T​o​k​e​n - */ - placeholder: string - } - } - controls: { - /** - * N​e​x​t - */ - submit: string - } - } - oidc: { - /** - * S​i​g​n​ ​i​n​ ​w​i​t​h - */ - oidcButton: string - /** - * O​r​ ​S​i​g​n​ ​I​n​ ​w​i​t​h​ ​E​x​t​e​r​n​a​l​ ​S​S​O - */ - title: string - /** - * I​f​ ​y​o​u​ ​w​o​u​l​d​ ​l​i​k​e​ ​t​o​ ​i​n​i​t​i​a​t​e​ ​t​h​e​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s​ ​u​s​i​n​g​ ​E​x​t​e​r​n​a​l​ ​S​S​O​,​ ​p​l​e​a​s​e​ ​c​l​i​c​k​ ​t​h​e​ ​l​i​n​k​ ​b​e​l​o​w​ ​t​o​ ​s​i​g​n​ ​i​n​ ​a​n​d​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. - */ - infoBox: string - } - } - } - oidcLogin: { - card: { - /** - * S​t​a​r​t​ ​y​o​u​r​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s - */ - title: string - /** - * T​h​a​n​k​ ​y​o​u​ ​f​o​r​ ​v​a​l​i​d​a​t​i​n​g​ ​y​o​u​r​ ​a​c​c​o​u​n​t​,​ ​p​l​e​a​s​e​ ​f​o​l​l​o​w​ ​i​n​s​t​r​u​c​t​i​o​n​ ​b​e​l​o​w​ ​f​o​r​ ​c​o​n​f​i​g​u​r​i​n​g​ ​y​o​u​r​ ​V​P​N​ ​c​o​n​n​e​c​t​i​o​n​. - */ - infoBox: string - steps: { - /** - * P​l​e​a​s​e​ ​d​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​d​e​f​g​u​a​r​d​ ​V​P​N​ ​D​e​s​k​t​o​p​ ​C​l​i​e​n​t​. - */ - first: string - /** + finish: string; + }; + }; + }; + }; + finish: { + /** + * C​o​n​f​i​g​u​r​a​t​i​o​n​ ​c​o​m​p​l​e​t​e​d​! + */ + title: string; + }; + }; + }; + resetPassword: { + steps: { + email: { + controls: { + /** + * S​e​n​d + */ + send: string; + }; + /** + * E​n​t​e​r​ ​y​o​u​r​ ​e​-​m​a​i​l + */ + title: string; + form: { + fields: { + email: { + /** + * E​-​m​a​i​l + */ + label: string; + }; + }; + }; + }; + linkSent: { + controls: { + /** + * B​a​c​k​ ​t​o​ ​m​a​i​n​ ​m​e​n​u + */ + back: string; + }; + /** + * I​f​ ​t​h​e​ ​p​r​o​v​i​d​e​d​ ​e​m​a​i​l​ ​a​d​d​r​e​s​s​ ​i​s​ ​a​s​s​i​g​n​e​d​ ​t​o​ ​a​n​y​ ​a​c​c​o​u​n​t​ ​-​ ​t​h​e​ ​p​a​s​s​w​o​r​d​ ​r​e​s​e​t​ ​w​i​l​l​ ​b​e​ ​i​n​i​t​i​a​t​e​d​ ​a​n​d​ ​y​o​u​ ​w​i​l​l​ ​r​e​c​i​e​v​e​ ​a​n​ ​e​m​a​i​l​ ​w​i​t​h​ ​f​u​r​t​h​e​r​ ​i​s​t​r​u​c​t​i​o​n​s​. + */ + messageBox: string; + }; + securityCode: { + controls: { + /** + * S​e​n​d​ ​c​o​d​e + */ + sendCode: string; + }; + /** + * E​n​t​e​r​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e + */ + title: string; + /** + * I​n​ ​o​r​d​e​r​ ​t​o​ ​r​e​s​e​t​ ​t​h​e​ ​p​a​s​s​w​o​r​d​,​ ​p​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​s​e​c​u​r​i​t​y​ ​c​o​d​e​ ​t​h​a​t​ ​w​i​l​l​ ​b​e​ ​s​e​n​t​ ​t​o​ ​y​o​u​r​ ​n​u​m​b​e​r​: + */ + messagebox: string; + form: { + fields: { + code: { + /** + * S​e​c​u​r​i​t​y​ ​c​o​d​e + */ + label: string; + }; + }; + }; + }; + resetPassword: { + /** + * R​e​s​e​t​ ​y​o​u​r​ ​p​a​s​s​w​o​r​d + */ + title: string; + controls: { + /** + * R​e​s​e​t​ ​p​a​s​s​w​o​r​d + */ + submit: string; + }; + form: { + errors: { + /** + * F​i​e​l​d​s​ ​d​o​e​s​n​'​t​ ​m​a​t​c​h + */ + repeat: string; + }; + fields: { + password: { + /** + * N​e​w​ ​p​a​s​s​w​o​r​d + */ + label: string; + }; + repeat: { + /** + * C​o​n​f​i​r​m​ ​p​a​s​s​w​o​r​d + */ + label: string; + }; + }; + }; + }; + resetSuccess: { + controls: { + /** + * R​e​t​u​r​n​ ​t​o​ ​s​e​r​v​i​c​e​s​ ​m​e​n​u + */ + back: string; + }; + /** + * C​o​n​g​r​a​t​u​l​a​t​i​o​n​s​,​ ​y​o​u​r​ ​n​e​w​ ​p​a​s​s​w​o​r​d​ ​i​s​ ​s​e​t​. + */ + messageBox: string; + }; + resetFailed: { + controls: { + /** + * R​e​t​u​r​n​ ​t​o​ ​s​t​a​r​t + */ + back: string; + }; + /** + * T​h​e​ ​e​n​t​e​r​e​d​ ​c​o​d​e​ ​i​s​ ​i​n​v​a​l​i​d​.​ ​P​l​e​a​s​e​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​ ​f​r​o​m​ ​t​h​e​ ​b​e​g​i​n​n​i​n​g​. + */ + messageBox: string; + }; + }; + }; + sessionTimeout: { + card: { + /** + * S​e​s​s​i​o​n​ ​t​i​m​e​d​ ​o​u​t + */ + header: string; + /** + * S​o​r​r​y​,​ ​y​o​u​ ​h​a​v​e​ ​e​x​c​e​e​d​e​d​ ​t​h​e​ ​t​i​m​e​ ​l​i​m​i​t​ ​t​o​ ​c​o​m​p​l​e​t​e​ ​t​h​e​ ​p​r​o​c​e​s​s​.​ ​P​l​e​a​s​e​ ​t​r​y​ ​a​g​a​i​n​.​ ​I​f​ ​y​o​u​ ​n​e​e​d​ ​a​s​s​i​s​t​a​n​c​e​,​ ​p​l​e​a​s​e​ ​w​a​t​c​h​ ​o​u​r​ ​g​u​i​d​e​ ​o​r​ ​c​o​n​t​a​c​t​ ​y​o​u​r​ ​a​d​m​i​n​i​s​t​r​a​t​o​r​. + */ + message: string; + }; + controls: { + /** + * E​n​t​e​r​ ​n​e​w​ ​t​o​k​e​n + */ + back: string; + /** + * C​o​n​t​a​c​t​ ​a​d​m​i​n + */ + contact: string; + }; + }; + token: { + card: { + /** + * P​l​e​a​s​e​,​ ​e​n​t​e​r​ ​y​o​u​r​ ​p​e​r​s​o​n​a​l​ ​e​n​r​o​l​l​m​e​n​t​ ​t​o​k​e​n + */ + title: string; + messageBox: { + /** + * Y​o​u​ ​c​a​n​ ​f​i​n​d​ ​t​o​k​e​n​ ​i​n​ ​e​-​m​a​i​l​ ​m​e​s​s​a​g​e​ ​o​r​ ​u​s​e​ ​d​i​r​e​c​t​ ​l​i​n​k​. + */ + email: string; + }; + form: { + errors: { + token: { + /** + * T​o​k​e​n​ ​i​s​ ​r​e​q​u​i​r​e​d + */ + required: string; + }; + }; + fields: { + token: { + /** + * T​o​k​e​n + */ + placeholder: string; + }; + }; + controls: { + /** + * N​e​x​t + */ + submit: string; + }; + }; + oidc: { + /** + * S​i​g​n​ ​i​n​ ​w​i​t​h + */ + oidcButton: string; + /** + * O​r​ ​S​i​g​n​ ​I​n​ ​w​i​t​h​ ​E​x​t​e​r​n​a​l​ ​S​S​O + */ + title: string; + /** + * I​f​ ​y​o​u​ ​w​o​u​l​d​ ​l​i​k​e​ ​t​o​ ​i​n​i​t​i​a​t​e​ ​t​h​e​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s​ ​u​s​i​n​g​ ​E​x​t​e​r​n​a​l​ ​S​S​O​,​ ​p​l​e​a​s​e​ ​c​l​i​c​k​ ​t​h​e​ ​l​i​n​k​ ​b​e​l​o​w​ ​t​o​ ​s​i​g​n​ ​i​n​ ​a​n​d​ ​s​t​a​r​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. + */ + infoBox: string; + }; + }; + }; + oidcLogin: { + card: { + /** + * S​t​a​r​t​ ​y​o​u​r​ ​e​n​r​o​l​l​m​e​n​t​ ​p​r​o​c​e​s​s + */ + title: string; + /** + * T​h​a​n​k​ ​y​o​u​ ​f​o​r​ ​v​a​l​i​d​a​t​i​n​g​ ​y​o​u​r​ ​a​c​c​o​u​n​t​,​ ​p​l​e​a​s​e​ ​f​o​l​l​o​w​ ​i​n​s​t​r​u​c​t​i​o​n​ ​b​e​l​o​w​ ​f​o​r​ ​c​o​n​f​i​g​u​r​i​n​g​ ​y​o​u​r​ ​V​P​N​ ​c​o​n​n​e​c​t​i​o​n​. + */ + infoBox: string; + steps: { + /** + * P​l​e​a​s​e​ ​d​o​w​n​l​o​a​d​ ​a​n​d​ ​i​n​s​t​a​l​l​ ​d​e​f​g​u​a​r​d​ ​V​P​N​ ​D​e​s​k​t​o​p​ ​C​l​i​e​n​t​. + */ + first: string; + /** * 2​.​ ​O​p​e​n​ ​t​h​e​ ​c​l​i​e​n​t​ ​a​n​d​ ​<​i​>​A​d​d​ ​I​n​s​t​a​n​c​e​<​/​i​>​.​ ​C​o​p​y​ ​t​h​e​ ​d​a​t​a​ ​p​r​o​v​i​d​e​d​ ​b​e​l​o​w​ ​i​n​t​o​ ​t​h​e​ ​c​o​r​r​e​s​p​o​n​d​i​n​g​ ​f​i​e​l​d​s​.​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​Y​o​u​ ​c​a​n​ ​a​l​s​o​ ​l​e​a​r​n​ ​m​o​r​e​ ​a​b​o​u​t​ ​t​h​e​ ​p​r​o​c​e​s​s​ ​i​n​ ​o​u​r​ ​<​a​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​h​r​e​f​=​"​h​t​t​p​s​:​/​/​d​o​c​s​.​d​e​f​g​u​a​r​d​.​n​e​t​/​h​e​l​p​/​c​o​n​f​i​g​u​r​i​n​g​-​v​p​n​/​a​d​d​-​n​e​w​-​i​n​s​t​a​n​c​e​"​ @@ -613,221 +616,221 @@ type RootTranslation = { ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​d​o​c​u​m​e​n​t​a​t​i​o​n​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​/​a​>​. */ - second: string - tokenInput: { - /** - * I​n​s​t​a​n​c​e​ ​U​R​L - */ - instanceUrl: string - /** - * T​o​k​e​n - */ - token: string - /** - * P​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​i​n​s​t​a​n​c​e​ ​U​R​L​ ​a​n​d​ ​t​o​k​e​n - */ - title: string - /** - * A​d​d​ ​I​n​s​t​a​n​c​e - */ - addInstance: string - } - } - } - } - openidMfaCallback: { - error: { - /** - * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r - */ - title: string - /** - * T​h​e​r​e​ ​w​a​s​ ​a​n​ ​e​r​r​o​r​ ​d​u​r​i​n​g​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​w​i​t​h​ ​t​h​e​ ​p​r​o​v​i​d​e​r​.​ ​P​l​e​a​s​e​ ​g​o​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​ ​a​n​d​ ​r​e​p​e​a​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. - */ - message: string - /** - * E​r​r​o​r​ ​D​e​t​a​i​l​s - */ - detailsTitle: string - } - success: { - /** - * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​C​o​m​p​l​e​t​e​d - */ - title: string - /** - * Y​o​u​ ​h​a​v​e​ ​b​e​e​n​ ​s​u​c​c​e​s​s​f​u​l​l​y​ ​a​u​t​h​e​n​t​i​c​a​t​e​d​.​ ​P​l​e​a​s​e​ ​c​l​o​s​e​ ​t​h​i​s​ ​w​i​n​d​o​w​ ​a​n​d​ ​g​e​t​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​. - */ - message: string - } - } - openidMfaRedirect: { - error: { - /** - * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r - */ - title: string - /** - * N​o​ ​t​o​k​e​n​ ​p​r​o​v​i​d​e​d​ ​i​n​ ​t​h​e​ ​U​R​L​.​ ​P​l​e​a​s​e​ ​e​n​s​u​r​e​ ​y​o​u​ ​h​a​v​e​ ​a​ ​v​a​l​i​d​ ​t​o​k​e​n​ ​t​o​ ​p​r​o​c​e​e​d​ ​w​i​t​h​ ​O​p​e​n​I​D​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​. - */ - message: string - } - } - } -} + second: string; + tokenInput: { + /** + * I​n​s​t​a​n​c​e​ ​U​R​L + */ + instanceUrl: string; + /** + * T​o​k​e​n + */ + token: string; + /** + * P​l​e​a​s​e​ ​p​r​o​v​i​d​e​ ​i​n​s​t​a​n​c​e​ ​U​R​L​ ​a​n​d​ ​t​o​k​e​n + */ + title: string; + /** + * A​d​d​ ​I​n​s​t​a​n​c​e + */ + addInstance: string; + }; + }; + }; + }; + openidMfaCallback: { + error: { + /** + * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r + */ + title: string; + /** + * T​h​e​r​e​ ​w​a​s​ ​a​n​ ​e​r​r​o​r​ ​d​u​r​i​n​g​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​w​i​t​h​ ​t​h​e​ ​p​r​o​v​i​d​e​r​.​ ​P​l​e​a​s​e​ ​g​o​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​ ​a​n​d​ ​r​e​p​e​a​t​ ​t​h​e​ ​p​r​o​c​e​s​s​. + */ + message: string; + /** + * E​r​r​o​r​ ​D​e​t​a​i​l​s + */ + detailsTitle: string; + }; + success: { + /** + * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​C​o​m​p​l​e​t​e​d + */ + title: string; + /** + * Y​o​u​ ​h​a​v​e​ ​b​e​e​n​ ​s​u​c​c​e​s​s​f​u​l​l​y​ ​a​u​t​h​e​n​t​i​c​a​t​e​d​.​ ​P​l​e​a​s​e​ ​c​l​o​s​e​ ​t​h​i​s​ ​w​i​n​d​o​w​ ​a​n​d​ ​g​e​t​ ​b​a​c​k​ ​t​o​ ​t​h​e​ ​*​*​D​e​f​g​u​a​r​d​ ​V​P​N​ ​C​l​i​e​n​t​*​*​. + */ + message: string; + }; + }; + openidMfaRedirect: { + error: { + /** + * A​u​t​h​e​n​t​i​c​a​t​i​o​n​ ​E​r​r​o​r + */ + title: string; + /** + * N​o​ ​t​o​k​e​n​ ​p​r​o​v​i​d​e​d​ ​i​n​ ​t​h​e​ ​U​R​L​.​ ​P​l​e​a​s​e​ ​e​n​s​u​r​e​ ​y​o​u​ ​h​a​v​e​ ​a​ ​v​a​l​i​d​ ​t​o​k​e​n​ ​t​o​ ​p​r​o​c​e​e​d​ ​w​i​t​h​ ​O​p​e​n​I​D​ ​a​u​t​h​e​n​t​i​c​a​t​i​o​n​. + */ + message: string; + }; + }; + }; +}; export type TranslationFunctions = { - time: { - seconds: { - /** - * second - */ - singular: () => LocalizedString - /** - * seconds - */ - prular: () => LocalizedString - } - minutes: { - /** - * minute - */ - singular: () => LocalizedString - /** - * minutes - */ - prular: () => LocalizedString - } - } - form: { - errors: { - /** - * Field is invalid - */ - invalid: () => LocalizedString - /** - * Enter a valid E-mail - */ - email: () => LocalizedString - /** - * Field is required - */ - required: () => LocalizedString - /** - * Min length of {length} - */ - minLength: (arg: { length: number }) => LocalizedString - /** - * Max length of {length} - */ - maxLength: (arg: { length: number }) => LocalizedString - /** - * At least one special character - */ - specialsRequired: () => LocalizedString - /** - * Special characters are forbidden - */ - specialsForbidden: () => LocalizedString - /** - * At least one number required - */ - numberRequired: () => LocalizedString - password: { - /** - * Please correct the following: - */ - floatingTitle: () => LocalizedString - } - /** - * At least one lower case character - */ - oneLower: () => LocalizedString - /** - * At least one upper case character - */ - oneUpper: () => LocalizedString - } - } - common: { - controls: { - /** - * Back - */ - back: () => LocalizedString - /** - * Next - */ - next: () => LocalizedString - /** - * Submit - */ - submit: () => LocalizedString - } - } - components: { - adminInfo: { - /** - * Your admin - */ - title: () => LocalizedString - } - } - pages: { - enrollment: { - sideBar: { - /** - * Enrollment - */ - title: () => LocalizedString - steps: { - /** - * Welcome - */ - welcome: () => LocalizedString - /** - * Data verification - */ - verification: () => LocalizedString - /** - * Create password - */ - password: () => LocalizedString - /** - * Configure VPN - */ - vpn: () => LocalizedString - /** - * Finish - */ - finish: () => LocalizedString - } - /** - * Application version - */ - appVersion: () => LocalizedString - } - stepsIndicator: { - /** - * Step - */ - step: () => LocalizedString - /** - * of - */ - of: () => LocalizedString - } - /** - * Time left - */ - timeLeft: () => LocalizedString - steps: { - welcome: { - /** - * Hello, {name} - */ - title: (arg: { name: string }) => LocalizedString - /** + time: { + seconds: { + /** + * second + */ + singular: () => LocalizedString; + /** + * seconds + */ + prular: () => LocalizedString; + }; + minutes: { + /** + * minute + */ + singular: () => LocalizedString; + /** + * minutes + */ + prular: () => LocalizedString; + }; + }; + form: { + errors: { + /** + * Field is invalid + */ + invalid: () => LocalizedString; + /** + * Enter a valid E-mail + */ + email: () => LocalizedString; + /** + * Field is required + */ + required: () => LocalizedString; + /** + * Min length of {length} + */ + minLength: (arg: { length: number }) => LocalizedString; + /** + * Max length of {length} + */ + maxLength: (arg: { length: number }) => LocalizedString; + /** + * At least one special character + */ + specialsRequired: () => LocalizedString; + /** + * Special characters are forbidden + */ + specialsForbidden: () => LocalizedString; + /** + * At least one number required + */ + numberRequired: () => LocalizedString; + password: { + /** + * Please correct the following: + */ + floatingTitle: () => LocalizedString; + }; + /** + * At least one lower case character + */ + oneLower: () => LocalizedString; + /** + * At least one upper case character + */ + oneUpper: () => LocalizedString; + }; + }; + common: { + controls: { + /** + * Back + */ + back: () => LocalizedString; + /** + * Next + */ + next: () => LocalizedString; + /** + * Submit + */ + submit: () => LocalizedString; + }; + }; + components: { + adminInfo: { + /** + * Your admin + */ + title: () => LocalizedString; + }; + }; + pages: { + enrollment: { + sideBar: { + /** + * Enrollment + */ + title: () => LocalizedString; + steps: { + /** + * Welcome + */ + welcome: () => LocalizedString; + /** + * Data verification + */ + verification: () => LocalizedString; + /** + * Create password + */ + password: () => LocalizedString; + /** + * Configure VPN + */ + vpn: () => LocalizedString; + /** + * Finish + */ + finish: () => LocalizedString; + }; + /** + * Application version + */ + appVersion: () => LocalizedString; + }; + stepsIndicator: { + /** + * Step + */ + step: () => LocalizedString; + /** + * of + */ + of: () => LocalizedString; + }; + /** + * Time left + */ + timeLeft: () => LocalizedString; + steps: { + welcome: { + /** + * Hello, {name} + */ + title: (arg: { name: string }) => LocalizedString; + /** * In order to gain access to the company infrastructure, we require you to complete this enrollment process. During this process, you will need to: @@ -838,124 +841,124 @@ export type TranslationFunctions = { You have a time limit of **{time} minutes** to complete this process. If you have any questions, please consult your assigned admin.All necessary information can be found at the bottom of the sidebar. */ - explanation: (arg: { time: string }) => LocalizedString - } - dataVerification: { - /** - * Data verification - */ - title: () => LocalizedString - /** - * Please, check your data. If anything is wrong, notify your admin after you complete the process. - */ - messageBox: () => LocalizedString - form: { - fields: { - firstName: { - /** - * Name - */ - label: () => LocalizedString - } - lastName: { - /** - * Last name - */ - label: () => LocalizedString - } - email: { - /** - * E-mail - */ - label: () => LocalizedString - } - phone: { - /** - * Phone number - */ - label: () => LocalizedString - } - } - } - } - password: { - /** - * Create password - */ - title: () => LocalizedString - form: { - fields: { - password: { - /** - * Create new password - */ - label: () => LocalizedString - } - repeat: { - /** - * Confirm new password - */ - label: () => LocalizedString - errors: { - /** - * Passwords aren't matching - */ - matching: () => LocalizedString - } - } - } - } - } - deviceSetup: { - /** - * * This step is OPTIONAL. You can skip it if you wish. This can be configured later in defguard. - */ - optionalMessage: () => LocalizedString - cards: { - device: { - /** - * Configure your device for VPN - */ - title: () => LocalizedString - create: { - /** - * Create Configuration - */ - submit: () => LocalizedString - /** - * Please be advised that you have to download the configuration now, since we do not store your private key. After this dialog is closed, you will not be able to get your fulll configuration file (with private keys, only blank template). - */ - messageBox: () => LocalizedString - form: { - fields: { - name: { - /** - * Device Name - */ - label: () => LocalizedString - } - 'public': { - /** - * My Public Key - */ - label: () => LocalizedString - } - toggle: { - /** - * Generate key pair - */ - generate: () => LocalizedString - /** - * Use my own public key - */ - own: () => LocalizedString - } - } - } - } - config: { - messageBox: { - /** + explanation: (arg: { time: string }) => LocalizedString; + }; + dataVerification: { + /** + * Data verification + */ + title: () => LocalizedString; + /** + * Please, check your data. If anything is wrong, notify your admin after you complete the process. + */ + messageBox: () => LocalizedString; + form: { + fields: { + firstName: { + /** + * Name + */ + label: () => LocalizedString; + }; + lastName: { + /** + * Last name + */ + label: () => LocalizedString; + }; + email: { + /** + * E-mail + */ + label: () => LocalizedString; + }; + phone: { + /** + * Phone number + */ + label: () => LocalizedString; + }; + }; + }; + }; + password: { + /** + * Create password + */ + title: () => LocalizedString; + form: { + fields: { + password: { + /** + * Create new password + */ + label: () => LocalizedString; + }; + repeat: { + /** + * Confirm new password + */ + label: () => LocalizedString; + errors: { + /** + * Passwords aren't matching + */ + matching: () => LocalizedString; + }; + }; + }; + }; + }; + deviceSetup: { + /** + * * This step is OPTIONAL. You can skip it if you wish. This can be configured later in defguard. + */ + optionalMessage: () => LocalizedString; + cards: { + device: { + /** + * Configure your device for VPN + */ + title: () => LocalizedString; + create: { + /** + * Create Configuration + */ + submit: () => LocalizedString; + /** + * Please be advised that you have to download the configuration now, since we do not store your private key. After this dialog is closed, you will not be able to get your fulll configuration file (with private keys, only blank template). + */ + messageBox: () => LocalizedString; + form: { + fields: { + name: { + /** + * Device Name + */ + label: () => LocalizedString; + }; + public: { + /** + * My Public Key + */ + label: () => LocalizedString; + }; + toggle: { + /** + * Generate key pair + */ + generate: () => LocalizedString; + /** + * Use my own public key + */ + own: () => LocalizedString; + }; + }; + }; + }; + config: { + messageBox: { + /** *

Please be advised that you have to download the configuration now, @@ -965,305 +968,305 @@ export type TranslationFunctions = {

*/ - auto: () => LocalizedString - /** + auto: () => LocalizedString; + /** *

Please be advised that configuration provided here does not include private key and uses public key to fill it's place you will need to repalce it on your own for configuration to work properly.

*/ - manual: () => LocalizedString - } - /** - * My Device Name - */ - deviceNameLabel: () => LocalizedString - /** - * You don't have access to any networks - */ - noNetworksMessage: () => LocalizedString - /** - * Use provided configuration file below by scanning QR Code or importing it as file on your devices WireGuard app. - */ - cardTitle: () => LocalizedString - card: { - /** - * Config file for location - */ - selectLabel: () => LocalizedString - } - } - } - guide: { - /** - * Quick Guide - */ - title: () => LocalizedString - /** - * This quick guide will help you with device configuration. - */ - messageBox: () => LocalizedString - /** - * Step {step}: - */ - step: (arg: { step: number }) => LocalizedString - steps: { - wireguard: { - /** - * Download and install WireGuard client on your compputer or app on phone. - */ - content: () => LocalizedString - /** - * Download WireGuard - */ - button: () => LocalizedString - } - /** - * Download provided configuration file to your device. - */ - downloadConfig: () => LocalizedString - /** + manual: () => LocalizedString; + }; + /** + * My Device Name + */ + deviceNameLabel: () => LocalizedString; + /** + * You don't have access to any networks + */ + noNetworksMessage: () => LocalizedString; + /** + * Use provided configuration file below by scanning QR Code or importing it as file on your devices WireGuard app. + */ + cardTitle: () => LocalizedString; + card: { + /** + * Config file for location + */ + selectLabel: () => LocalizedString; + }; + }; + }; + guide: { + /** + * Quick Guide + */ + title: () => LocalizedString; + /** + * This quick guide will help you with device configuration. + */ + messageBox: () => LocalizedString; + /** + * Step {step}: + */ + step: (arg: { step: number }) => LocalizedString; + steps: { + wireguard: { + /** + * Download and install WireGuard client on your compputer or app on phone. + */ + content: () => LocalizedString; + /** + * Download WireGuard + */ + button: () => LocalizedString; + }; + /** + * Download provided configuration file to your device. + */ + downloadConfig: () => LocalizedString; + /** * Open WireGuard and select "Add Tunnel" (Import tunnel(s) from file). Find your Defguard configuration file and hit "OK". On phone use WireGuard app “+” icon and scan QR code. */ - addTunnel: () => LocalizedString - /** - * Select your tunnel from the list and press "activate". - */ - activate: () => LocalizedString - /** + addTunnel: () => LocalizedString; + /** + * Select your tunnel from the list and press "activate". + */ + activate: () => LocalizedString; + /** * **Great work - your Defguard VPN is now active!** If you want to disengage your VPN connection, simply press "deactivate". */ - finish: () => LocalizedString - } - } - } - } - finish: { - /** - * Configuration completed! - */ - title: () => LocalizedString - } - } - } - resetPassword: { - steps: { - email: { - controls: { - /** - * Send - */ - send: () => LocalizedString - } - /** - * Enter your e-mail - */ - title: () => LocalizedString - form: { - fields: { - email: { - /** - * E-mail - */ - label: () => LocalizedString - } - } - } - } - linkSent: { - controls: { - /** - * Back to main menu - */ - back: () => LocalizedString - } - /** - * If the provided email address is assigned to any account - the password reset will be initiated and you will recieve an email with further istructions. - */ - messageBox: () => LocalizedString - } - securityCode: { - controls: { - /** - * Send code - */ - sendCode: () => LocalizedString - } - /** - * Enter security code - */ - title: () => LocalizedString - /** - * In order to reset the password, please provide security code that will be sent to your number: - */ - messagebox: () => LocalizedString - form: { - fields: { - code: { - /** - * Security code - */ - label: () => LocalizedString - } - } - } - } - resetPassword: { - /** - * Reset your password - */ - title: () => LocalizedString - controls: { - /** - * Reset password - */ - submit: () => LocalizedString - } - form: { - errors: { - /** - * Fields doesn't match - */ - repeat: () => LocalizedString - } - fields: { - password: { - /** - * New password - */ - label: () => LocalizedString - } - repeat: { - /** - * Confirm password - */ - label: () => LocalizedString - } - } - } - } - resetSuccess: { - controls: { - /** - * Return to services menu - */ - back: () => LocalizedString - } - /** - * Congratulations, your new password is set. - */ - messageBox: () => LocalizedString - } - resetFailed: { - controls: { - /** - * Return to start - */ - back: () => LocalizedString - } - /** - * The entered code is invalid. Please start the process from the beginning. - */ - messageBox: () => LocalizedString - } - } - } - sessionTimeout: { - card: { - /** - * Session timed out - */ - header: () => LocalizedString - /** - * Sorry, you have exceeded the time limit to complete the process. Please try again. If you need assistance, please watch our guide or contact your administrator. - */ - message: () => LocalizedString - } - controls: { - /** - * Enter new token - */ - back: () => LocalizedString - /** - * Contact admin - */ - contact: () => LocalizedString - } - } - token: { - card: { - /** - * Please, enter your personal enrollment token - */ - title: () => LocalizedString - messageBox: { - /** - * You can find token in e-mail message or use direct link. - */ - email: () => LocalizedString - } - form: { - errors: { - token: { - /** - * Token is required - */ - required: () => LocalizedString - } - } - fields: { - token: { - /** - * Token - */ - placeholder: () => LocalizedString - } - } - controls: { - /** - * Next - */ - submit: () => LocalizedString - } - } - oidc: { - /** - * Sign in with - */ - oidcButton: () => LocalizedString - /** - * Or Sign In with External SSO - */ - title: () => LocalizedString - /** - * If you would like to initiate the enrollment process using External SSO, please click the link below to sign in and start the process. - */ - infoBox: () => LocalizedString - } - } - } - oidcLogin: { - card: { - /** - * Start your enrollment process - */ - title: () => LocalizedString - /** - * Thank you for validating your account, please follow instruction below for configuring your VPN connection. - */ - infoBox: () => LocalizedString - steps: { - /** - * Please download and install defguard VPN Desktop Client. - */ - first: () => LocalizedString - /** + finish: () => LocalizedString; + }; + }; + }; + }; + finish: { + /** + * Configuration completed! + */ + title: () => LocalizedString; + }; + }; + }; + resetPassword: { + steps: { + email: { + controls: { + /** + * Send + */ + send: () => LocalizedString; + }; + /** + * Enter your e-mail + */ + title: () => LocalizedString; + form: { + fields: { + email: { + /** + * E-mail + */ + label: () => LocalizedString; + }; + }; + }; + }; + linkSent: { + controls: { + /** + * Back to main menu + */ + back: () => LocalizedString; + }; + /** + * If the provided email address is assigned to any account - the password reset will be initiated and you will recieve an email with further istructions. + */ + messageBox: () => LocalizedString; + }; + securityCode: { + controls: { + /** + * Send code + */ + sendCode: () => LocalizedString; + }; + /** + * Enter security code + */ + title: () => LocalizedString; + /** + * In order to reset the password, please provide security code that will be sent to your number: + */ + messagebox: () => LocalizedString; + form: { + fields: { + code: { + /** + * Security code + */ + label: () => LocalizedString; + }; + }; + }; + }; + resetPassword: { + /** + * Reset your password + */ + title: () => LocalizedString; + controls: { + /** + * Reset password + */ + submit: () => LocalizedString; + }; + form: { + errors: { + /** + * Fields doesn't match + */ + repeat: () => LocalizedString; + }; + fields: { + password: { + /** + * New password + */ + label: () => LocalizedString; + }; + repeat: { + /** + * Confirm password + */ + label: () => LocalizedString; + }; + }; + }; + }; + resetSuccess: { + controls: { + /** + * Return to services menu + */ + back: () => LocalizedString; + }; + /** + * Congratulations, your new password is set. + */ + messageBox: () => LocalizedString; + }; + resetFailed: { + controls: { + /** + * Return to start + */ + back: () => LocalizedString; + }; + /** + * The entered code is invalid. Please start the process from the beginning. + */ + messageBox: () => LocalizedString; + }; + }; + }; + sessionTimeout: { + card: { + /** + * Session timed out + */ + header: () => LocalizedString; + /** + * Sorry, you have exceeded the time limit to complete the process. Please try again. If you need assistance, please watch our guide or contact your administrator. + */ + message: () => LocalizedString; + }; + controls: { + /** + * Enter new token + */ + back: () => LocalizedString; + /** + * Contact admin + */ + contact: () => LocalizedString; + }; + }; + token: { + card: { + /** + * Please, enter your personal enrollment token + */ + title: () => LocalizedString; + messageBox: { + /** + * You can find token in e-mail message or use direct link. + */ + email: () => LocalizedString; + }; + form: { + errors: { + token: { + /** + * Token is required + */ + required: () => LocalizedString; + }; + }; + fields: { + token: { + /** + * Token + */ + placeholder: () => LocalizedString; + }; + }; + controls: { + /** + * Next + */ + submit: () => LocalizedString; + }; + }; + oidc: { + /** + * Sign in with + */ + oidcButton: () => LocalizedString; + /** + * Or Sign In with External SSO + */ + title: () => LocalizedString; + /** + * If you would like to initiate the enrollment process using External SSO, please click the link below to sign in and start the process. + */ + infoBox: () => LocalizedString; + }; + }; + }; + oidcLogin: { + card: { + /** + * Start your enrollment process + */ + title: () => LocalizedString; + /** + * Thank you for validating your account, please follow instruction below for configuring your VPN connection. + */ + infoBox: () => LocalizedString; + steps: { + /** + * Please download and install defguard VPN Desktop Client. + */ + first: () => LocalizedString; + /** * 2. Open the client and Add Instance. Copy the data provided below into the corresponding fields. You can also learn more about the process in our . */ - second: () => LocalizedString - tokenInput: { - /** - * Instance URL - */ - instanceUrl: () => LocalizedString - /** - * Token - */ - token: () => LocalizedString - /** - * Please provide instance URL and token - */ - title: () => LocalizedString - /** - * Add Instance - */ - addInstance: () => LocalizedString - } - } - } - } - openidMfaCallback: { - error: { - /** - * Authentication Error - */ - title: () => LocalizedString - /** - * There was an error during authentication with the provider. Please go back to the **Defguard VPN Client** and repeat the process. - */ - message: () => LocalizedString - /** - * Error Details - */ - detailsTitle: () => LocalizedString - } - success: { - /** - * Authentication Completed - */ - title: () => LocalizedString - /** - * You have been successfully authenticated. Please close this window and get back to the **Defguard VPN Client**. - */ - message: () => LocalizedString - } - } - openidMfaRedirect: { - error: { - /** - * Authentication Error - */ - title: () => LocalizedString - /** - * No token provided in the URL. Please ensure you have a valid token to proceed with OpenID authentication. - */ - message: () => LocalizedString - } - } - } -} + second: () => LocalizedString; + tokenInput: { + /** + * Instance URL + */ + instanceUrl: () => LocalizedString; + /** + * Token + */ + token: () => LocalizedString; + /** + * Please provide instance URL and token + */ + title: () => LocalizedString; + /** + * Add Instance + */ + addInstance: () => LocalizedString; + }; + }; + }; + }; + openidMfaCallback: { + error: { + /** + * Authentication Error + */ + title: () => LocalizedString; + /** + * There was an error during authentication with the provider. Please go back to the **Defguard VPN Client** and repeat the process. + */ + message: () => LocalizedString; + /** + * Error Details + */ + detailsTitle: () => LocalizedString; + }; + success: { + /** + * Authentication Completed + */ + title: () => LocalizedString; + /** + * You have been successfully authenticated. Please close this window and get back to the **Defguard VPN Client**. + */ + message: () => LocalizedString; + }; + }; + openidMfaRedirect: { + error: { + /** + * Authentication Error + */ + title: () => LocalizedString; + /** + * No token provided in the URL. Please ensure you have a valid token to proceed with OpenID authentication. + */ + message: () => LocalizedString; + }; + }; + }; +}; -export type Formatters = {} +export type Formatters = {}; diff --git a/web/src/i18n/i18n-util.async.ts b/web/src/i18n/i18n-util.async.ts index d87b5263..6076abda 100644 --- a/web/src/i18n/i18n-util.async.ts +++ b/web/src/i18n/i18n-util.async.ts @@ -1,26 +1,29 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { initFormatters } from './formatters' -import type { Locales, Translations } from './i18n-types' -import { loadedFormatters, loadedLocales, locales } from './i18n-util' +import { initFormatters } from './formatters'; +import type { Locales, Translations } from './i18n-types'; +import { loadedFormatters, loadedLocales, locales } from './i18n-util'; const localeTranslationLoaders = { - en: () => import('./en'), -} + en: () => import('./en'), +}; -const updateDictionary = (locale: Locales, dictionary: Partial): Translations => - loadedLocales[locale] = { ...loadedLocales[locale], ...dictionary } +const updateDictionary = ( + locale: Locales, + dictionary: Partial, +): Translations => (loadedLocales[locale] = { ...loadedLocales[locale], ...dictionary }); export const importLocaleAsync = async (locale: Locales): Promise => - (await localeTranslationLoaders[locale]()).default as unknown as Translations + (await localeTranslationLoaders[locale]()).default as unknown as Translations; export const loadLocaleAsync = async (locale: Locales): Promise => { - updateDictionary(locale, await importLocaleAsync(locale)) - loadFormatters(locale) -} + updateDictionary(locale, await importLocaleAsync(locale)); + loadFormatters(locale); +}; -export const loadAllLocalesAsync = (): Promise => Promise.all(locales.map(loadLocaleAsync)) +export const loadAllLocalesAsync = (): Promise => + Promise.all(locales.map(loadLocaleAsync)); export const loadFormatters = (locale: Locales): void => - void (loadedFormatters[locale] = initFormatters(locale)) + void (loadedFormatters[locale] = initFormatters(locale)); diff --git a/web/src/i18n/i18n-util.sync.ts b/web/src/i18n/i18n-util.sync.ts index bebffe4b..4a345923 100644 --- a/web/src/i18n/i18n-util.sync.ts +++ b/web/src/i18n/i18n-util.sync.ts @@ -1,24 +1,23 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { initFormatters } from './formatters' -import type { Locales, Translations } from './i18n-types' -import { loadedFormatters, loadedLocales, locales } from './i18n-util' - -import en from './en' +import en from './en'; +import { initFormatters } from './formatters'; +import type { Locales, Translations } from './i18n-types'; +import { loadedFormatters, loadedLocales, locales } from './i18n-util'; const localeTranslations = { - en, -} + en, +}; export const loadLocale = (locale: Locales): void => { - if (loadedLocales[locale]) return + if (loadedLocales[locale]) return; - loadedLocales[locale] = localeTranslations[locale] as unknown as Translations - loadFormatters(locale) -} + loadedLocales[locale] = localeTranslations[locale] as unknown as Translations; + loadFormatters(locale); +}; -export const loadAllLocales = (): void => locales.forEach(loadLocale) +export const loadAllLocales = (): void => locales.forEach(loadLocale); export const loadFormatters = (locale: Locales): void => - void (loadedFormatters[locale] = initFormatters(locale)) + void (loadedFormatters[locale] = initFormatters(locale)); diff --git a/web/src/i18n/i18n-util.ts b/web/src/i18n/i18n-util.ts index 452e0a6d..eb996835 100644 --- a/web/src/i18n/i18n-util.ts +++ b/web/src/i18n/i18n-util.ts @@ -1,37 +1,60 @@ // This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten. /* eslint-disable */ -import { i18n as initI18n, i18nObject as initI18nObject, i18nString as initI18nString } from 'typesafe-i18n' -import type { LocaleDetector } from 'typesafe-i18n/detectors' -import type { LocaleTranslationFunctions, TranslateByString } from 'typesafe-i18n' -import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors' -import { initExtendDictionary } from 'typesafe-i18n/utils' -import type { Formatters, Locales, Translations, TranslationFunctions } from './i18n-types' - -export const baseLocale: Locales = 'en' - -export const locales: Locales[] = [ - 'en' -] - -export const isLocale = (locale: string): locale is Locales => locales.includes(locale as Locales) - -export const loadedLocales: Record = {} as Record - -export const loadedFormatters: Record = {} as Record - -export const extendDictionary = initExtendDictionary() - -export const i18nString = (locale: Locales): TranslateByString => initI18nString(locale, loadedFormatters[locale]) +import type { LocaleTranslationFunctions, TranslateByString } from 'typesafe-i18n'; +import { + i18n as initI18n, + i18nObject as initI18nObject, + i18nString as initI18nString, +} from 'typesafe-i18n'; +import type { LocaleDetector } from 'typesafe-i18n/detectors'; +import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors'; +import { initExtendDictionary } from 'typesafe-i18n/utils'; +import type { + Formatters, + Locales, + TranslationFunctions, + Translations, +} from './i18n-types'; + +export const baseLocale: Locales = 'en'; + +export const locales: Locales[] = ['en']; + +export const isLocale = (locale: string): locale is Locales => + locales.includes(locale as Locales); + +export const loadedLocales: Record = {} as Record< + Locales, + Translations +>; + +export const loadedFormatters: Record = {} as Record< + Locales, + Formatters +>; + +export const extendDictionary = initExtendDictionary(); + +export const i18nString = (locale: Locales): TranslateByString => + initI18nString(locale, loadedFormatters[locale]); export const i18nObject = (locale: Locales): TranslationFunctions => - initI18nObject( - locale, - loadedLocales[locale], - loadedFormatters[locale] - ) - -export const i18n = (): LocaleTranslationFunctions => - initI18n(loadedLocales, loadedFormatters) - -export const detectLocale = (...detectors: LocaleDetector[]): Locales => detectLocaleFn(baseLocale, locales, ...detectors) + initI18nObject( + locale, + loadedLocales[locale], + loadedFormatters[locale], + ); + +export const i18n = (): LocaleTranslationFunctions< + Locales, + Translations, + TranslationFunctions +> => + initI18n( + loadedLocales, + loadedFormatters, + ); + +export const detectLocale = (...detectors: LocaleDetector[]): Locales => + detectLocaleFn(baseLocale, locales, ...detectors); diff --git a/web/src/pages/enrollment/EnrollmentPage.tsx b/web/src/pages/enrollment/EnrollmentPage.tsx index 4c44b779..0309d784 100644 --- a/web/src/pages/enrollment/EnrollmentPage.tsx +++ b/web/src/pages/enrollment/EnrollmentPage.tsx @@ -1,7 +1,7 @@ import './style.scss'; import dayjs from 'dayjs'; -import { ReactNode, useEffect, useRef } from 'react'; +import { type ReactNode, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import { useBreakpoint } from 'use-breakpoint'; import { shallow } from 'zustand/shallow'; @@ -40,7 +40,7 @@ export const EnrollmentPage = () => { const stepsMax = useEnrollmentStore((state) => state.stepsMax); const loading = useEnrollmentStore((state) => state.loading); - const [setEnrollmentState, back, reset, nextSubject] = useEnrollmentStore( + const [setEnrollmentState, back, _reset, nextSubject] = useEnrollmentStore( (state) => [state.setState, state.perviousStep, state.reset, state.nextSubject], shallow, ); @@ -76,7 +76,7 @@ export const EnrollmentPage = () => { navigate(routes.timeout, { replace: true }); } } - }, [sessionEnd, navigate, reset]); + }, [sessionEnd, navigate]); useEffect(() => { enrollmentFinished.current = stepsMax === currentStep; diff --git a/web/src/pages/enrollment/components/AdminInfo/style.scss b/web/src/pages/enrollment/components/AdminInfo/style.scss index 8fb4686b..484af21b 100644 --- a/web/src/pages/enrollment/components/AdminInfo/style.scss +++ b/web/src/pages/enrollment/components/AdminInfo/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .admin-info { width: 100%; diff --git a/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx b/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx index 8b1a28ae..80c4746c 100644 --- a/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx +++ b/web/src/pages/enrollment/components/EnrollmentSideBar/EnrollmentSideBar.tsx @@ -2,7 +2,7 @@ import './style.scss'; import classNames from 'classnames'; import { useEffect, useMemo, useState } from 'react'; -import { LocalizedString } from 'typesafe-i18n'; +import type { LocalizedString } from 'typesafe-i18n'; import { useI18nContext } from '../../../../i18n/i18n-react'; import { Divider } from '../../../../shared/components/layout/Divider/Divider'; @@ -42,7 +42,7 @@ export const EnrollmentSideBar = () => { }); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [appVersion, getAppInfo]); const steps = useMemo((): LocalizedString[] => { const stepsLL = LL.pages.enrollment.sideBar.steps; diff --git a/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss b/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss index e13cd321..fd02a72f 100644 --- a/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss +++ b/web/src/pages/enrollment/components/EnrollmentSideBar/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-side-bar { box-sizing: border-box; width: 270px; @@ -61,6 +59,7 @@ & > .admin-info { box-sizing: border-box; padding: 20px 10px 20px 40px; + & > p { @include typography(app-body-2); @include text-overflow-dots; diff --git a/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx b/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx index 85ee8d64..c392faf2 100644 --- a/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx +++ b/web/src/pages/enrollment/components/EnrollmentStepControls/EnrollmentStepControls.tsx @@ -1,7 +1,7 @@ import './style.scss'; import classNames from 'classnames'; -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { AdminInfo } from '../AdminInfo/AdminInfo'; import { TimeLeft } from '../TimeLeft/TimeLeft'; diff --git a/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss b/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss index 6c2fcb55..e326ed58 100644 --- a/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss +++ b/web/src/pages/enrollment/components/EnrollmentStepControls/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment { & > .controls { box-sizing: border-box; @@ -38,6 +36,7 @@ @include media-breakpoint-down(lg) { height: 44px; } + &.variant-standard { svg { g { @@ -45,6 +44,7 @@ } } } + &.variant-primary { svg { g { @@ -59,6 +59,7 @@ display: flex; flex-flow: row nowrap; overflow: hidden; + .admin-info { display: flex; flex-flow: row wrap; @@ -75,6 +76,7 @@ @include typography(app-copyright); } } + & > .time-left { margin-left: auto; text-align: right; diff --git a/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss b/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss index 1fd9c13d..f16c3434 100644 --- a/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss +++ b/web/src/pages/enrollment/components/EnrollmentStepIndicator/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .step-indicator { width: 100%; height: auto; @@ -9,6 +7,7 @@ @include typography(app-avatar-s); color: var(--text-body-primary); + & > span { color: var(--text-body-tertiary); } diff --git a/web/src/pages/enrollment/components/TimeLeft/style.scss b/web/src/pages/enrollment/components/TimeLeft/style.scss index 9e11b987..1aad4b0b 100644 --- a/web/src/pages/enrollment/components/TimeLeft/style.scss +++ b/web/src/pages/enrollment/components/TimeLeft/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .time-left { display: inline-block; diff --git a/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx b/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx index fb9c659a..f7ef168b 100644 --- a/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx +++ b/web/src/pages/enrollment/hooks/store/useEnrollmentStore.tsx @@ -3,7 +3,7 @@ import { Subject } from 'rxjs'; import { createJSONStorage, devtools, persist } from 'zustand/middleware'; import { createWithEqualityFn } from 'zustand/traditional'; -import { +import type { AdminInfo, Device, DeviceConfig, diff --git a/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx b/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx index ba3632c5..a4eb6b48 100644 --- a/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx +++ b/web/src/pages/enrollment/steps/DataVerificationStep/DataVerificationStep.tsx @@ -2,7 +2,7 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useEffect, useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; diff --git a/web/src/pages/enrollment/steps/DataVerificationStep/style.scss b/web/src/pages/enrollment/steps/DataVerificationStep/style.scss index 638b8e89..fefa18a4 100644 --- a/web/src/pages/enrollment/steps/DataVerificationStep/style.scss +++ b/web/src/pages/enrollment/steps/DataVerificationStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-data-verification-card { padding: 0 20px; @@ -49,6 +47,7 @@ margin-bottom: 8px; padding: 0; } + & > p { @include typography(app-input); diff --git a/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx b/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx index 22d260e3..2ef2a9da 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/DeviceStep.tsx @@ -1,7 +1,7 @@ import './style.scss'; import { useMutation } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import classNames from 'classnames'; import { useEffect } from 'react'; import { shallow } from 'zustand/shallow'; @@ -59,7 +59,7 @@ export const DeviceStep = () => { if (userPassword) { const sub = nextSubject.subscribe(() => { if ( - (deviceState && deviceState.device && deviceState.configs) || + (deviceState?.device && deviceState.configs) || settings?.vpn_setup_optional || settings?.only_client_activation || deviceManagementDisabled diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx index 27965937..be27b387 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/CreateDevice.tsx @@ -1,7 +1,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; import { useMemo, useState } from 'react'; -import { SubmitHandler, useController, useForm } from 'react-hook-form'; +import { type SubmitHandler, useController, useForm } from 'react-hook-form'; import { z } from 'zod'; import { useI18nContext } from '../../../../../../../i18n/i18n-react'; @@ -13,7 +13,7 @@ import { ButtonStyleVariant, } from '../../../../../../../shared/components/layout/Button/types'; import { MessageBox } from '../../../../../../../shared/components/layout/MessageBox/MessageBox'; -import { ToggleOption } from '../../../../../../../shared/components/layout/Toggle/types'; +import type { ToggleOption } from '../../../../../../../shared/components/layout/Toggle/types'; import { useApi } from '../../../../../../../shared/hooks/api/useApi'; import { generateWGKeys } from '../../../../../../../shared/utils/generateWGKeys'; import { useEnrollmentStore } from '../../../../../hooks/store/useEnrollmentStore'; diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx index a0b75ff8..25d6bc97 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/DeviceConfiguration.tsx @@ -14,9 +14,9 @@ import { Input } from '../../../../../../../../shared/components/layout/Input/In import { MessageBox } from '../../../../../../../../shared/components/layout/MessageBox/MessageBox'; import { MessageBoxType } from '../../../../../../../../shared/components/layout/MessageBox/types'; import { Select } from '../../../../../../../../shared/components/layout/Select/Select'; -import { SelectOption } from '../../../../../../../../shared/components/layout/Select/types'; +import type { SelectOption } from '../../../../../../../../shared/components/layout/Select/types'; import SvgIconHamburger from '../../../../../../../../shared/components/svg/IconHamburger'; -import { DeviceConfig } from '../../../../../../../../shared/hooks/api/types'; +import type { DeviceConfig } from '../../../../../../../../shared/hooks/api/types'; import { downloadWGConfig } from '../../../../../../../../shared/utils/downloadWGConfig'; import { useEnrollmentStore } from '../../../../../../hooks/store/useEnrollmentStore'; @@ -43,7 +43,10 @@ export const DeviceConfiguration = () => { })) ?? [], [deviceState?.configs], ); - const networksAvailable = deviceState?.configs?.length > 0 ?? false; + + const networksAvailable = + deviceState && Array.isArray(deviceState.configs) && deviceState.configs.length > 0; + const preparedConfig = useMemo(() => { if (deviceState?.device?.privateKey) { return selected?.config.replace('YOUR_PRIVATE_KEY', deviceState.device.privateKey); @@ -57,7 +60,7 @@ export const DeviceConfiguration = () => { }, [selected, deviceState?.device?.privateKey, deviceState?.device?.pubkey]); useEffect(() => { - if (deviceState?.configs && deviceState.configs.length) { + if (deviceState?.configs?.length) { setSelected(deviceState.configs[0]); } }, [deviceState?.configs]); diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss index a903bc80..656ed249 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/components/DeviceConfiguration/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #configure-device-card { .qr-info { display: flex; diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss index 5f6a49c2..d785fd04 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #configure-device-card { .message-box { margin-bottom: 20px; diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss index 3b014cb7..9b38196d 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #device-setup-guide { & > h3 { margin-bottom: 23px; diff --git a/web/src/pages/enrollment/steps/DeviceStep/style.scss b/web/src/pages/enrollment/steps/DeviceStep/style.scss index 775dee3d..7e9f171d 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-device-step { width: 100%; height: auto; @@ -15,6 +13,7 @@ .message { width: 100%; + & > * { text-align: center; } @@ -28,6 +27,7 @@ row-gap: 25px; align-items: flex-start; justify-content: center; + & > .card { width: 100%; max-width: 750px; diff --git a/web/src/pages/enrollment/steps/FinishStep/style.scss b/web/src/pages/enrollment/steps/FinishStep/style.scss index a9402e2d..92bc8060 100644 --- a/web/src/pages/enrollment/steps/FinishStep/style.scss +++ b/web/src/pages/enrollment/steps/FinishStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-finish-card { width: 100%; max-width: 1200px; diff --git a/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx b/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx index 09b9c287..03626825 100644 --- a/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx +++ b/web/src/pages/enrollment/steps/PasswordStep/PasswordStep.tsx @@ -2,7 +2,7 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useEffect, useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; @@ -68,12 +68,12 @@ export const PasswordStep = () => { return () => { sub.unsubscribe(); }; - }, [nextSubject, submitRef]); + }, [nextSubject]); useEffect(() => { reset(); //eslint-disable-next-line - }, []); + }, [reset]); return ( diff --git a/web/src/pages/enrollment/steps/PasswordStep/style.scss b/web/src/pages/enrollment/steps/PasswordStep/style.scss index 9123aa6f..4df9aac7 100644 --- a/web/src/pages/enrollment/steps/PasswordStep/style.scss +++ b/web/src/pages/enrollment/steps/PasswordStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment-password-card { width: 100%; max-width: 650px; diff --git a/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx b/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx index 625454a9..b8ab368b 100644 --- a/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx +++ b/web/src/pages/enrollment/steps/WelcomeStep/WelcomeStep.tsx @@ -46,17 +46,15 @@ export const WelcomeStep = () => { }, [next, nextSubject]); return ( - <> - - -

- {LL.pages.enrollment.steps.welcome.title({ name: `${userInfo?.first_name}` })} -

-
- {markdown} -
- -
- + + +

+ {LL.pages.enrollment.steps.welcome.title({ name: `${userInfo?.first_name}` })} +

+
+ {markdown} +
+ +
); }; diff --git a/web/src/pages/enrollment/steps/WelcomeStep/style.scss b/web/src/pages/enrollment/steps/WelcomeStep/style.scss index 49b2586d..e8497a52 100644 --- a/web/src/pages/enrollment/steps/WelcomeStep/style.scss +++ b/web/src/pages/enrollment/steps/WelcomeStep/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment { #enrollment-welcome-card { box-sizing: border-box; @@ -15,6 +13,7 @@ & > .explenation { user-select: none; margin-bottom: 30px; + p, ul, ol, @@ -31,11 +30,13 @@ & > .admin-info { user-select: text; + & > p { &:not(.title) { font-weight: 700; } } + & > .title { user-select: none; } diff --git a/web/src/pages/enrollment/style.scss b/web/src/pages/enrollment/style.scss index ce34d58d..39d9a6e0 100644 --- a/web/src/pages/enrollment/style.scss +++ b/web/src/pages/enrollment/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #enrollment { @include media-breakpoint-up(lg) { margin-left: 270px; diff --git a/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx b/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx index ce6127ae..02a04f80 100644 --- a/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx +++ b/web/src/pages/main/DeviceSetupMethodCard/DeviceSetupMethodCard.tsx @@ -1,6 +1,6 @@ import './style.scss'; -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Button } from '../../../shared/components/layout/Button/Button'; import { diff --git a/web/src/pages/main/DeviceSetupMethodCard/style.scss b/web/src/pages/main/DeviceSetupMethodCard/style.scss index e4f92ecc..e9c2eec3 100644 --- a/web/src/pages/main/DeviceSetupMethodCard/style.scss +++ b/web/src/pages/main/DeviceSetupMethodCard/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - .device-setup-method { width: 100%; box-sizing: border-box; diff --git a/web/src/pages/main/MainPage.tsx b/web/src/pages/main/MainPage.tsx index 0779fe33..3e5f879e 100644 --- a/web/src/pages/main/MainPage.tsx +++ b/web/src/pages/main/MainPage.tsx @@ -26,7 +26,7 @@ export const MainPage = () => { // check if navigated from link with token if not do nothing useEffect(() => { const token = searchParams.get('token'); - if (token && token.length && !requestPending.current) { + if (token?.length && !requestPending.current) { requestPending.current = true; startEnrollment({ token, @@ -51,7 +51,7 @@ export const MainPage = () => { }); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchParams]); + }, [searchParams, initEnrollment, navigate, startEnrollment]); return ( diff --git a/web/src/pages/main/style.scss b/web/src/pages/main/style.scss index 51893bf3..7a45a6e1 100644 --- a/web/src/pages/main/style.scss +++ b/web/src/pages/main/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #main-page { @include media-breakpoint-up(lg) { padding: 100px 50px; diff --git a/web/src/pages/mfa/OpenIDCallback.tsx b/web/src/pages/mfa/OpenIDCallback.tsx index 4ee6b3ab..3a729ef1 100644 --- a/web/src/pages/mfa/OpenIDCallback.tsx +++ b/web/src/pages/mfa/OpenIDCallback.tsx @@ -1,7 +1,7 @@ import './style.scss'; import { useQuery } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import { useState } from 'react'; import ReactMarkdown from 'react-markdown'; import rehypeSanitize from 'rehype-sanitize'; diff --git a/web/src/pages/mfa/style.scss b/web/src/pages/mfa/style.scss index 4a2e4e2b..d598cc6c 100644 --- a/web/src/pages/mfa/style.scss +++ b/web/src/pages/mfa/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #openid-mfa-page { gap: var(--spacing-xs); diff --git a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx index ad77e0b6..fc70c4fc 100644 --- a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx +++ b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx @@ -1,7 +1,7 @@ import './style.scss'; import { useQuery } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import parse from 'html-react-parser'; import { useState } from 'react'; import { useBreakpoint } from 'use-breakpoint'; @@ -105,61 +105,59 @@ export const OpenIDCallbackCard = () => { } return ( - <> - -

{LL.pages.oidcLogin.card.title()}

- -
-

1. {LL.pages.oidcLogin.card.steps.first()}

-
-
-

{parse(LL.pages.oidcLogin.card.steps.second())}

- -

{LL.pages.oidcLogin.card.steps.tokenInput.title()}

-
- -
- - { - // This should never be undefined, but just in case - navigator.clipboard.writeText(data?.url || ''); - }} - /> -
+ +

{LL.pages.oidcLogin.card.title()}

+ +
+

1. {LL.pages.oidcLogin.card.steps.first()}

+
+
+

{parse(LL.pages.oidcLogin.card.steps.second())}

+ +

{LL.pages.oidcLogin.card.steps.tokenInput.title()}

+
+ +
+ + { + // This should never be undefined, but just in case + navigator.clipboard.writeText(data?.url || ''); + }} + />
+
-
- -
- - { - // This should never be undefined, but just in case - navigator.clipboard.writeText(data?.token || ''); - }} - /> -
+
+ +
+ + { + // This should never be undefined, but just in case + navigator.clipboard.writeText(data?.token || ''); + }} + />
+
-
-
- +
+
); }; diff --git a/web/src/pages/openidCallback/components/style.scss b/web/src/pages/openidCallback/components/style.scss index 8904637c..06aaacb8 100644 --- a/web/src/pages/openidCallback/components/style.scss +++ b/web/src/pages/openidCallback/components/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #openidcallback-page { .openidcallback-card { box-sizing: border-box; @@ -40,6 +38,7 @@ svg { width: 36px; height: 36px; + path { fill: var(--text-button-secondary); } diff --git a/web/src/pages/openidCallback/style.scss b/web/src/pages/openidCallback/style.scss index 6bc0f3b3..524b04b1 100644 --- a/web/src/pages/openidCallback/style.scss +++ b/web/src/pages/openidCallback/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #openidcallback-page { @include media-breakpoint-up(lg) { padding: 100px 50px; @@ -12,6 +10,7 @@ & > .logo-container { display: none; margin-bottom: 30px; + @include media-breakpoint-up(lg) { display: flex; margin-bottom: 100px; diff --git a/web/src/pages/passwordReset/PasswordResetPage.tsx b/web/src/pages/passwordReset/PasswordResetPage.tsx index 7a4e59f6..0f0fefab 100644 --- a/web/src/pages/passwordReset/PasswordResetPage.tsx +++ b/web/src/pages/passwordReset/PasswordResetPage.tsx @@ -1,7 +1,7 @@ import './style.scss'; import dayjs from 'dayjs'; -import { ReactNode, useEffect, useRef } from 'react'; +import { type ReactNode, useEffect, useRef } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { LogoContainer } from '../../components/LogoContainer/LogoContainer'; @@ -39,7 +39,7 @@ export const PasswordResetPage = () => { useEffect(() => { const token = searchParams.get('token'); - if (token && token.length && !requestPending.current) { + if (token?.length && !requestPending.current) { requestPending.current = true; start({ token, @@ -63,7 +63,7 @@ export const PasswordResetPage = () => { }); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchParams]); + }, [searchParams, navigate, setStore, start]); return ( diff --git a/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx b/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx index 6481bcc8..3f0571b6 100644 --- a/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx +++ b/web/src/pages/passwordReset/hooks/usePasswordResetStore.tsx @@ -1,6 +1,6 @@ import { create } from 'zustand'; -import { AdminInfo, UserInfo } from '../../../shared/hooks/api/types'; +import type { AdminInfo, UserInfo } from '../../../shared/hooks/api/types'; const defaultValues: StoreValues = { loading: false, diff --git a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx index cf775acf..4ac735ca 100644 --- a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx +++ b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx @@ -2,7 +2,7 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { useI18nContext } from '../../../../i18n/i18n-react'; diff --git a/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx b/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx index f1fc8495..6348ceaa 100644 --- a/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx +++ b/web/src/pages/passwordReset/steps/EmailStep/EmailStep.tsx @@ -2,9 +2,9 @@ import './style.scss'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import { useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; diff --git a/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx b/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx index 15fc3d70..d4751ac3 100644 --- a/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx +++ b/web/src/pages/passwordReset/steps/PasswordStep/PasswordStep.tsx @@ -1,8 +1,8 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; -import { AxiosError } from 'axios'; +import type { AxiosError } from 'axios'; import { useMemo, useRef } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { z } from 'zod'; import { shallow } from 'zustand/shallow'; diff --git a/web/src/pages/passwordReset/style.scss b/web/src/pages/passwordReset/style.scss index af2a5045..efb60e78 100644 --- a/web/src/pages/passwordReset/style.scss +++ b/web/src/pages/passwordReset/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #password-reset { @include media-breakpoint-up(lg) { padding: 100px 50px; @@ -11,6 +9,7 @@ & > .logo-container { display: none; + @include media-breakpoint-up(lg) { display: flex; margin-bottom: 100px; @@ -41,12 +40,14 @@ .arrow-single { height: 36px; width: 36px; + svg { g { fill: var(--surface-icon-primary); } } } + &.variant-primary { .arrow-single { svg { @@ -76,11 +77,14 @@ margin-bottom: 35px; color: var(--text-body-primary); } + & > .message-box { width: 100%; } + & > form { width: 100%; + & > * { width: 100%; } diff --git a/web/src/pages/sessionTimeout/style.scss b/web/src/pages/sessionTimeout/style.scss index 4d21dabb..19967337 100644 --- a/web/src/pages/sessionTimeout/style.scss +++ b/web/src/pages/sessionTimeout/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #session-timeout { & > .logo-container { display: none; diff --git a/web/src/pages/token/components/TokenCard.tsx b/web/src/pages/token/components/TokenCard.tsx index 2787bfc8..7f074c34 100644 --- a/web/src/pages/token/components/TokenCard.tsx +++ b/web/src/pages/token/components/TokenCard.tsx @@ -4,7 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation, useQuery } from '@tanstack/react-query'; import dayjs from 'dayjs'; import { useMemo } from 'react'; -import { SubmitHandler, useForm } from 'react-hook-form'; +import { type SubmitHandler, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { useBreakpoint } from 'use-breakpoint'; import { z } from 'zod'; @@ -123,60 +123,58 @@ export const TokenCard = () => { } return ( - <> - -

{LL.pages.token.card.title()}

- -
- - - {openidData?.url && ( - <> -

{LL.pages.token.card.oidc.title()}

- -
- -
- - )} -
-
-
- + +

{LL.pages.token.card.title()}

+ +
+ + + {openidData?.url && ( + <> +

{LL.pages.token.card.oidc.title()}

+ +
+ +
+ + )} +
+
+
); }; diff --git a/web/src/pages/token/components/style.scss b/web/src/pages/token/components/style.scss index 1f782243..28c665e9 100644 --- a/web/src/pages/token/components/style.scss +++ b/web/src/pages/token/components/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #token-page { .token-card { box-sizing: border-box; diff --git a/web/src/pages/token/style.scss b/web/src/pages/token/style.scss index 03ad4998..b979bb87 100644 --- a/web/src/pages/token/style.scss +++ b/web/src/pages/token/style.scss @@ -1,5 +1,3 @@ -@use '@scssutils' as *; - #token-page { @include media-breakpoint-up(lg) { padding: 100px 50px; @@ -12,6 +10,7 @@ & > .logo-container { display: none; margin-bottom: 30px; + @include media-breakpoint-up(lg) { display: flex; margin-bottom: 100px; @@ -36,12 +35,14 @@ .arrow-single { height: 36px; width: 36px; + svg { g { fill: var(--surface-icon-primary); } } } + &.variant-primary { .arrow-single { svg { diff --git a/web/src/shared/components/Form/FormDevTools/FormDevTools.tsx b/web/src/shared/components/Form/FormDevTools/FormDevTools.tsx deleted file mode 100644 index 56ffa631..00000000 --- a/web/src/shared/components/Form/FormDevTools/FormDevTools.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import './style.scss'; - -import { DevTool } from '@hookform/devtools'; -import ReactDOM from 'react-dom'; -import { Control } from 'react-hook-form'; - -interface Props { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - control: Control; -} - -export const DevTools: React.FC = ({ control }) => { - const element = document.querySelector('#root'); - if (!element) return null; - return ReactDOM.createPortal( -
- -
, - element, - ); -}; diff --git a/web/src/shared/components/Form/FormDevTools/style.scss b/web/src/shared/components/Form/FormDevTools/style.scss deleted file mode 100644 index 024f2448..00000000 --- a/web/src/shared/components/Form/FormDevTools/style.scss +++ /dev/null @@ -1,23 +0,0 @@ -@use '../../../scss/base/variables/' as v; - -.dev-tools { - & > div { - z-index: 999999999999999999; - } - - p { - color: v.$white; - } - - td { - color: v.$white; - } - - code { - color: v.$white; - } -} - -.ReactQueryDevtools { - color: v.$white; -} diff --git a/web/src/shared/components/Form/FormInput/FormInput.tsx b/web/src/shared/components/Form/FormInput/FormInput.tsx index d0013889..f7f6ff93 100644 --- a/web/src/shared/components/Form/FormInput/FormInput.tsx +++ b/web/src/shared/components/Form/FormInput/FormInput.tsx @@ -1,9 +1,13 @@ import { isUndefined } from 'lodash-es'; import { useMemo } from 'react'; -import { FieldValues, useController, UseControllerProps } from 'react-hook-form'; +import { + type FieldValues, + type UseControllerProps, + useController, +} from 'react-hook-form'; import { Input } from '../../layout/Input/Input'; -import { InputFloatingErrors, InputProps } from '../../layout/Input/types'; +import type { InputFloatingErrors, InputProps } from '../../layout/Input/types'; interface Props extends Omit { controller: UseControllerProps; @@ -34,7 +38,7 @@ export const FormInput = ({ }, [error, isDirty, isSubmitted, isTouched]); const floatingErrorsData = useMemo((): InputFloatingErrors | undefined => { - if (floatingErrors && floatingErrors.title && error && error.types && isInvalid) { + if (floatingErrors?.title && error && error.types && isInvalid) { let errors: string[] = []; for (const val of Object.values(error.types)) { if (typeof val === 'string') { @@ -44,7 +48,7 @@ export const FormInput = ({ errors = [...errors, ...val]; } } - if (floatingErrors.errorMessages && floatingErrors.errorMessages.length) { + if (floatingErrors.errorMessages?.length) { errors = [...errors, ...floatingErrors.errorMessages]; } return { diff --git a/web/src/shared/components/Form/FormSelect/FormSelect.tsx b/web/src/shared/components/Form/FormSelect/FormSelect.tsx index a8234f8d..45f5dbe1 100644 --- a/web/src/shared/components/Form/FormSelect/FormSelect.tsx +++ b/web/src/shared/components/Form/FormSelect/FormSelect.tsx @@ -1,20 +1,19 @@ import { isUndefined } from 'lodash-es'; import { useMemo } from 'react'; -import { FieldValues, useController, UseControllerProps } from 'react-hook-form'; - import { - Select, - SelectOption, - SelectProps, - SelectValue, -} from '../../layout/Select/Select'; + type FieldValues, + type UseControllerProps, + useController, +} from 'react-hook-form'; + +import { Select } from '../../layout/Select/Select'; +import type { SelectProps } from '../../layout/Select/types'; -interface Props - extends Omit, 'onChange'> { +interface Props extends SelectProps { controller: UseControllerProps; } -export const FormSelect = ({ +export const FormSelect = ({ controller, ...rest }: Props) => { @@ -34,20 +33,15 @@ export const FormSelect = ({ return false; }, [error, isDirty, isSubmitted, isTouched]); - const isValid = useMemo( - () => !isInvalid && (isTouched || isDirty || isSubmitted), - [isDirty, isInvalid, isSubmitted, isTouched], - ); - return ( { )} {!networksAvailable && ( - + )} ); diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss index d785fd04..46c6450b 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/ConfigureDeviceCard/style.scss @@ -1,5 +1,5 @@ #configure-device-card { - .message-box { + .message-box-old { margin-bottom: 20px; } diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx index 3bc17525..9e552124 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx +++ b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/QuickGuideCard.tsx @@ -9,7 +9,7 @@ import { ButtonStyleVariant, } from '../../../../../../shared/components/layout/Button/types'; import { Card } from '../../../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../../../shared/components/layout/MessageBox/MessageBoxOld'; export const QuickGuideCard = () => { const { LL } = useI18nContext(); @@ -19,7 +19,7 @@ export const QuickGuideCard = () => { return (

{cardLL.title()}

- +

{cardLL.steps.wireguard.content()}

diff --git a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss index 9b38196d..0a5b3b17 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/components/QuickGuideCard/style.scss @@ -9,7 +9,7 @@ margin-bottom: 20px; } - & > .message-box { + & > .message-box-old { margin-bottom: 10px; } diff --git a/web/src/pages/enrollment/steps/DeviceStep/style.scss b/web/src/pages/enrollment/steps/DeviceStep/style.scss index 7e9f171d..b7b8a726 100644 --- a/web/src/pages/enrollment/steps/DeviceStep/style.scss +++ b/web/src/pages/enrollment/steps/DeviceStep/style.scss @@ -8,7 +8,7 @@ padding: 0 25px 0 25px; } - & > .message-box { + & > .message-box-old { margin-bottom: 25px; .message { diff --git a/web/src/pages/main/style.scss b/web/src/pages/main/style.scss index 7a45a6e1..aca7c3e7 100644 --- a/web/src/pages/main/style.scss +++ b/web/src/pages/main/style.scss @@ -28,7 +28,7 @@ width: auto; } - .message-box { + .message-box-old { margin-bottom: 20px; } diff --git a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx index fc70c4fc..7c79510d 100644 --- a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx +++ b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx @@ -2,24 +2,27 @@ import './style.scss'; import { useQuery } from '@tanstack/react-query'; import type { AxiosError } from 'axios'; -import parse from 'html-react-parser'; -import { useState } from 'react'; +import { useMemo, useState } from 'react'; +import QRCode from 'react-qr-code'; import { useBreakpoint } from 'use-breakpoint'; - import { useI18nContext } from '../../../i18n/i18n-react'; -import { ActionButton } from '../../../shared/components/layout/ActionButton/ActionButton'; -import { ActionButtonVariant } from '../../../shared/components/layout/ActionButton/types'; import { BigInfoBox } from '../../../shared/components/layout/BigInfoBox/BigInfoBox'; import { Button } from '../../../shared/components/layout/Button/Button'; -import { ButtonStyleVariant } from '../../../shared/components/layout/Button/types'; +import { + ButtonSize, + ButtonStyleVariant, +} from '../../../shared/components/layout/Button/types'; import { Card } from '../../../shared/components/layout/Card/Card'; -import { Input } from '../../../shared/components/layout/Input/Input'; import { LoaderSpinner } from '../../../shared/components/layout/LoaderSpinner/LoaderSpinner'; -import { MessageBox } from '../../../shared/components/layout/MessageBox/MessageBox'; import { MessageBoxType } from '../../../shared/components/layout/MessageBox/types'; -import SvgIconDownload from '../../../shared/components/svg/IconDownload'; import { deviceBreakpoints } from '../../../shared/constants'; +import { CopyField } from '../../../shared/defguard-ui/components/Layout/CopyField/CopyField'; +import { MessageBox } from '../../../shared/defguard-ui/components/Layout/MessageBox/MessageBox'; +import { MessageBoxStyleVariant } from '../../../shared/defguard-ui/components/Layout/MessageBox/types'; +import { useToaster } from '../../../shared/defguard-ui/hooks/toasts/useToaster'; +import { isPresent } from '../../../shared/defguard-ui/utils/isPresent'; import { useApi } from '../../../shared/hooks/api/useApi'; +import { useClipboard } from '../../../shared/hooks/useClipboard'; type ErrorResponse = { error: string; @@ -30,6 +33,8 @@ export const OpenIDCallbackCard = () => { const { breakpoint } = useBreakpoint(deviceBreakpoints); const { LL } = useI18nContext(); const [error, setError] = useState(null); + const { writeToClipboard } = useClipboard(); + const toaster = useToaster(); const { isLoading, data } = useQuery( [], @@ -78,6 +83,18 @@ export const OpenIDCallbackCard = () => { }, ); + const qrData = useMemo(() => { + if (data) { + return btoa( + JSON.stringify({ + url: data.url, + token: data.token, + }), + ); + } + return undefined; + }, [data]); + if (isLoading) { return (
@@ -107,8 +124,247 @@ export const OpenIDCallbackCard = () => { return (

{LL.pages.oidcLogin.card.title()}

+

+ Please enter the provided Instance URL and Token into your Defguard Client. You + can scan the QR code or copy and paste the token manually. +

-
+ + {isPresent(data) && ( + <> + + + + )} + {isPresent(qrData) && ( +
+
+ +
+
+ )} +
+

+ Scan the QR code with your installed Defguard app. If you haven't installed it + yet, use your device's app store or the link below. +

+
+
+ {/*

1. {LL.pages.oidcLogin.card.steps.first()}

@@ -144,8 +401,9 @@ export const OpenIDCallbackCard = () => { { - // This should never be undefined, but just in case - navigator.clipboard.writeText(data?.token || ''); + if (data) { + writeToClipboard(data.token); + } }} />
@@ -157,7 +415,7 @@ export const OpenIDCallbackCard = () => { disabled={true} /> -
+
*/} ); }; diff --git a/web/src/pages/openidCallback/components/style.scss b/web/src/pages/openidCallback/components/style.scss index 06aaacb8..309025e3 100644 --- a/web/src/pages/openidCallback/components/style.scss +++ b/web/src/pages/openidCallback/components/style.scss @@ -1,11 +1,15 @@ #openidcallback-page { .openidcallback-card { box-sizing: border-box; - padding: 50px 40px; + padding: var(--spacing-m) var(--spacing-s); width: 100%; display: flex; flex-direction: column; - gap: 20px; + gap: var(--spacing-m); + + @include media-breakpoint-up(lg) { + padding: var(--spacing-l) var(--spacing-m); + } .steps { display: flex; @@ -17,7 +21,7 @@ } p { - @include typography(openidcallback-steps); + @include typography(app-body-2); color: var(--text-body-primary); } @@ -32,7 +36,7 @@ width: 334px; span { - @include typography(client-download-button); + @include typography(app-button-l); } svg { @@ -58,7 +62,7 @@ width: 198px; span { - @include typography(client-download-button); + @include typography(app-button-l); } } @@ -95,6 +99,40 @@ margin-bottom: 15px; text-align: left; } + + h3 { + @include typography(app-body-2); + } + + .row { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 0 var(--spacing-s); + column-gap: var(--spacing-s); + + a { + display: flex; + text-decoration: none; + + .btn { + text-decoration: none; + } + } + } + + .qr { + padding: var(--spacing-m) 0; + } + + .qr-description { + color: var(--text-body-tertiary); + text-align: center; + max-width: 485px; + @include typography(app-input); + } } .loader-container { diff --git a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx index 4ac735ca..d841d7d7 100644 --- a/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx +++ b/web/src/pages/passwordReset/steps/CodeStep/CodeStep.tsx @@ -15,7 +15,7 @@ import { ButtonStyleVariant, } from '../../../../shared/components/layout/Button/types'; import { Card } from '../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../shared/components/layout/MessageBox/MessageBoxOld'; import { MessageBoxType } from '../../../../shared/components/layout/MessageBox/types'; type FormFields = { @@ -64,7 +64,7 @@ export const CodeStep = () => {

{LL.pages.resetPassword.steps.securityCode.title()}

- { />
- diff --git a/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx b/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx index d49ac1af..a625d85f 100644 --- a/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx +++ b/web/src/pages/passwordReset/steps/LinkSentStep/LinkSentStep.tsx @@ -15,7 +15,7 @@ import { ButtonStyleVariant, } from '../../../../shared/components/layout/Button/types'; import { Card } from '../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../shared/components/layout/MessageBox/MessageBoxOld'; import { MessageBoxType } from '../../../../shared/components/layout/MessageBox/types'; import { routes } from '../../../../shared/routes'; import { usePasswordResetStore } from '../../hooks/usePasswordResetStore'; @@ -45,7 +45,7 @@ export const LinkSentStep = () => { />
- diff --git a/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx b/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx index 86e0d8fb..6be8f737 100644 --- a/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx +++ b/web/src/pages/passwordReset/steps/SuccessStep/SuccessStep.tsx @@ -15,7 +15,7 @@ import { ButtonStyleVariant, } from '../../../../shared/components/layout/Button/types'; import { Card } from '../../../../shared/components/layout/Card/Card'; -import { MessageBox } from '../../../../shared/components/layout/MessageBox/MessageBox'; +import { MessageBoxOld } from '../../../../shared/components/layout/MessageBox/MessageBoxOld'; import { MessageBoxType } from '../../../../shared/components/layout/MessageBox/types'; import { routes } from '../../../../shared/routes'; import { usePasswordResetStore } from '../../hooks/usePasswordResetStore'; @@ -45,7 +45,7 @@ export const SuccessStep = () => { /> - diff --git a/web/src/pages/passwordReset/style.scss b/web/src/pages/passwordReset/style.scss index efb60e78..9ed8f44b 100644 --- a/web/src/pages/passwordReset/style.scss +++ b/web/src/pages/passwordReset/style.scss @@ -78,7 +78,7 @@ color: var(--text-body-primary); } - & > .message-box { + & > .message-box-old { width: 100%; } diff --git a/web/src/shared/components/layout/MessageBox/MessageBox.tsx b/web/src/shared/components/layout/MessageBox/MessageBoxOld.tsx similarity index 95% rename from web/src/shared/components/layout/MessageBox/MessageBox.tsx rename to web/src/shared/components/layout/MessageBox/MessageBoxOld.tsx index bb369426..92083b0e 100644 --- a/web/src/shared/components/layout/MessageBox/MessageBox.tsx +++ b/web/src/shared/components/layout/MessageBox/MessageBoxOld.tsx @@ -26,7 +26,7 @@ interface Props extends ComponentPropsWithoutRef<'div'> { /** * Styled box with message. */ -export const MessageBox = ({ +export const MessageBoxOld = ({ message, className, dismissId, @@ -38,7 +38,7 @@ export const MessageBox = ({ const dismissible = !isUndefined(dismissId); const getClassName = useMemo(() => { - return classNames('message-box', className, type.valueOf()); + return classNames('message-box-old', className, type.valueOf()); }, [className, type]); const getIcon = useMemo(() => { diff --git a/web/src/shared/components/layout/MessageBox/style.scss b/web/src/shared/components/layout/MessageBox/style.scss index d684d70b..702d9013 100644 --- a/web/src/shared/components/layout/MessageBox/style.scss +++ b/web/src/shared/components/layout/MessageBox/style.scss @@ -1,4 +1,4 @@ -.message-box { +.message-box-old { height: auto; min-height: 57px; width: 100%; @@ -47,6 +47,7 @@ .message { box-sizing: border-box; padding: 17px 0; + p, span, b, @@ -80,6 +81,7 @@ & > circle { fill: var(--surface-positive-primary); } + & > g { & > rect { fill: var(--surface-positive-accent); @@ -92,14 +94,17 @@ &.warning { background-color: var(--surface-important-accent); + .message { color: var(--text-important); } + .icon-container { & > svg { & > circle { fill: var(--surface-important); } + & > rect { fill: var(--surface-important-accent); } @@ -109,6 +114,7 @@ &.error { background-color: var(--surface-alert-accent); + .message { color: var(--text-alert); } @@ -119,6 +125,7 @@ & > circle { fill: var(--surface-alert-primary); } + & > path { fill: var(--surface-alert-accent); } @@ -129,15 +136,18 @@ &.info { background-color: var(--surface-info-modal); + .message { color: var(--text-body-secondary); } + & > .icon-container { & > svg { & > g { & > circle { fill: var(--surface-icon-primary); } + & > rect { fill: var(--surface-button); } diff --git a/web/src/shared/defguard-ui b/web/src/shared/defguard-ui index cad0546f..920e920d 160000 --- a/web/src/shared/defguard-ui +++ b/web/src/shared/defguard-ui @@ -1 +1 @@ -Subproject commit cad0546f8d1b448b12186103783635e4bff24da9 +Subproject commit 920e920da026faa9db54fe0cf77c8c70870abb3e diff --git a/web/src/shared/hooks/api/utils.ts b/web/src/shared/hooks/api/utils.ts index 0278cd06..fa8a1621 100644 --- a/web/src/shared/hooks/api/utils.ts +++ b/web/src/shared/hooks/api/utils.ts @@ -1,5 +1,3 @@ -import { useEffect, useRef } from 'react'; - // biome-ignore lint/suspicious/noExplicitAny: Doesn't care about the type export const removeNulls = (obj: any) => { return JSON.parse(JSON.stringify(obj), (_, value) => { @@ -7,25 +5,3 @@ export const removeNulls = (obj: any) => { return value; }); }; - -/** -Under normal circumstances, useEffect should run only once when passed an empty dependency array. -However, in dev mode with react strict mode enabled, everything is rendered twice for debugging purposes. -This also causes useEffect to run twice, which is not always desirable. -This custom hook ensures that the effect runs only once in dev mode as well. -*/ - -// biome-ignore lint/suspicious/noConfusingVoidType: Should work like this -export default function useEffectOnce(fn: () => void | (() => void)) { - const isMounted = useRef(false); - useEffect(() => { - if (isMounted.current) { - return; - } - - const callback = fn(); - isMounted.current = true; - - return callback; - }, [fn]); -} diff --git a/web/src/shared/hooks/useClipboard.tsx b/web/src/shared/hooks/useClipboard.tsx new file mode 100644 index 00000000..964a8b4c --- /dev/null +++ b/web/src/shared/hooks/useClipboard.tsx @@ -0,0 +1,32 @@ +import { useCallback } from 'react'; + +import { useToaster } from '../defguard-ui/hooks/toasts/useToaster'; + +export const useClipboard = () => { + const toaster = useToaster(); + + const writeToClipboard = useCallback( + async (content: string, customMessage?: string) => { + if (window.isSecureContext) { + try { + await navigator.clipboard.writeText(content); + if (customMessage) { + toaster.success(customMessage); + } else { + toaster.success('Content copied to clipboard'); + } + } catch (e) { + toaster.error('Writing to clipboard failed !'); + console.error(e); + } + } else { + toaster.warning('Cannot access clipboard in insecure contexts'); + } + }, + [toaster], + ); + + return { + writeToClipboard, + }; +}; diff --git a/web/src/shared/scss/_base.scss b/web/src/shared/scss/_base.scss index 48ce86b4..92774b75 100644 --- a/web/src/shared/scss/_base.scss +++ b/web/src/shared/scss/_base.scss @@ -68,4 +68,4 @@ strong { ol, ul { padding-inline-start: 30px; -} \ No newline at end of file +} diff --git a/web/src/shared/scss/index.scss b/web/src/shared/scss/index.scss index 7a834a7f..8d5bd0f0 100644 --- a/web/src/shared/scss/index.scss +++ b/web/src/shared/scss/index.scss @@ -1,2 +1,2 @@ @forward './base'; -@forward './effects'; \ No newline at end of file +@forward './effects'; From d317328f16b06c9338cba7b1b8c02229ec9240bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Thu, 24 Jul 2025 10:17:30 +0200 Subject: [PATCH 10/11] fix runs-on in gh workflow lint ui --- .github/workflows/lint-web.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-web.yml b/.github/workflows/lint-web.yml index c5d05731..ca0db67a 100644 --- a/.github/workflows/lint-web.yml +++ b/.github/workflows/lint-web.yml @@ -16,7 +16,7 @@ on: jobs: lint-web: - runs-on: self-hosted + runs-on: [self-hosted, Linux, X64] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 From 6bd463f92183b106d04dd53058b557664d950de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Thu, 24 Jul 2025 10:38:31 +0200 Subject: [PATCH 11/11] check text --- web/src/i18n/en/index.ts | 2 +- .../pages/openidCallback/components/OpenIDCallbackCard.tsx | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/web/src/i18n/en/index.ts b/web/src/i18n/en/index.ts index d35e2425..a840cbbd 100644 --- a/web/src/i18n/en/index.ts +++ b/web/src/i18n/en/index.ts @@ -166,7 +166,7 @@ If you have any questions, please consult your assigned admin.All necessary info steps: { wireguard: { content: - 'Download and install WireGuard client on your computer or app on phone.', + 'Download and install WireGuard client on your computer or app on a mobile device.', button: 'Download WireGuard', }, downloadConfig: 'Download provided configuration file to your device.', diff --git a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx index 7c79510d..73736332 100644 --- a/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx +++ b/web/src/pages/openidCallback/components/OpenIDCallbackCard.tsx @@ -18,7 +18,6 @@ import { MessageBoxType } from '../../../shared/components/layout/MessageBox/typ import { deviceBreakpoints } from '../../../shared/constants'; import { CopyField } from '../../../shared/defguard-ui/components/Layout/CopyField/CopyField'; import { MessageBox } from '../../../shared/defguard-ui/components/Layout/MessageBox/MessageBox'; -import { MessageBoxStyleVariant } from '../../../shared/defguard-ui/components/Layout/MessageBox/types'; import { useToaster } from '../../../shared/defguard-ui/hooks/toasts/useToaster'; import { isPresent } from '../../../shared/defguard-ui/utils/isPresent'; import { useApi } from '../../../shared/hooks/api/useApi'; @@ -124,15 +123,11 @@ export const OpenIDCallbackCard = () => { return (

{LL.pages.oidcLogin.card.title()}

+

Please enter the provided Instance URL and Token into your Defguard Client. You can scan the QR code or copy and paste the token manually.

- - {isPresent(data) && ( <>