From 882e3e1ef4f791cc8ccd0e2e8acd603939c29dae Mon Sep 17 00:00:00 2001 From: Zack Spear Date: Tue, 26 Mar 2024 22:57:04 +0900 Subject: [PATCH] feat: server config enum message w/ ineligible support (#861) * test: serverState local components data tweaks * feat: server config enum message w/ ineligible support * refactor: config error messages * chore: lint --- .../dynamix.my.servers/include/state.php | 3 +- web/_data/serverState.ts | 79 ++++++++++-------- web/components/Registration.ce.vue | 2 +- web/composables/gql/graphql.ts | 1 + web/store/server.ts | 83 +++++++++++++++---- 5 files changed, 116 insertions(+), 52 deletions(-) diff --git a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php index ca9c3cca3..8601ec309 100644 --- a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php +++ b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php @@ -47,6 +47,7 @@ class ServerState private $connectPluginVersion; private $configErrorEnum = [ "error" => 'UNKNOWN_ERROR', + "ineligible" => 'INELIGIBLE', "invalid" => 'INVALID', "nokeyserver" => 'NO_KEY_SERVER', "withdrawn" => 'WITHDRAWN', @@ -241,7 +242,7 @@ class ServerState "caseModel" => $this->caseModel, "config" => [ 'valid' => ($this->var['configValid'] === 'yes'), - 'error' => isset($this->configErrorEnum[$this->var['configValid']]) ? $this->configErrorEnum[$this->var['configValid']] : 'UNKNOWN_ERROR', + 'error' => isset($this->configErrorEnum[$this->var['configValid']]) ? $this->configErrorEnum[$this->var['configValid']] : null, ], "connectPluginInstalled" => $this->connectPluginInstalled, "connectPluginVersion" => $this->connectPluginVersion, diff --git a/web/_data/serverState.ts b/web/_data/serverState.ts index 5ba342e8c..68dc04b05 100644 --- a/web/_data/serverState.ts +++ b/web/_data/serverState.ts @@ -24,8 +24,32 @@ import type { // return result; // } +// ENOKEYFILE +// TRIAL +// BASIC +// PLUS +// PRO +// STARTER +// UNLEASHED +// LIFETIME +// EEXPIRED +// EGUID +// EGUID1 +// ETRIAL +// ENOKEYFILE2 +// ENOKEYFILE1 +// ENOFLASH +// EBLACKLISTED +// EBLACKLISTED1 +// EBLACKLISTED2 +// ENOCONN + // '1111-1111-5GDB-123412341234' Starter.key = TkJCrVyXMLWWGKZF6TCEvf0C86UYI9KfUDSOm7JoFP19tOMTMgLKcJ6QIOt9_9Psg_t0yF-ANmzSgZzCo94ljXoPm4BESFByR0K7nyY9KVvU8szLEUcBUT3xC2adxLrAXFNxiPeK-mZqt34n16uETKYvLKL_Sr5_JziG5L5lJFBqYZCPmfLMiguFo1vp0xL8pnBH7q8bYoBnePrAcAVb9mAGxFVPEInSPkMBfC67JLHz7XY1Y_K5bYIq3go9XPtLltJ53_U4BQiMHooXUBJCKXodpqoGxq0eV0IhNEYdauAhnTsG90qmGZig0hZalQ0soouc4JZEMiYEcZbn9mBxPg -const staticGuid = '1111-1111-5GDB-123412341234'; + +const state: ServerState = 'STARTER'; +const currentFlashGuid = '1111-1111-SDFF-TEST1234ZACK'; // this is the flash drive that's been booted from +const regGuid = '1111-1111-SDFF-TEST1234ZACK'; // this guid is registered in key server +const keyfileBase64 = ''; // @todo raycast download key to base64 // const randomGuid = `1111-1111-${makeid(4)}-123412341234`; // this guid is registered in key server // const newGuid = `1234-1234-${makeid(4)}-123412341234`; // this is a new USB, not registered @@ -42,23 +66,6 @@ const oneHourFromNow = Date.now() + 60 * 60 * 1000; // 1 hour from now let expireTime = 0; let regExp: number | undefined; -// ENOKEYFILE -// TRIAL -// BASIC -// PLUS -// PRO -// EEXPIRED -// EGUID -// EGUID1 -// ETRIAL -// ENOKEYFILE2 -// ENOKEYFILE1 -// ENOFLASH -// EBLACKLISTED -// EBLACKLISTED1 -// EBLACKLISTED2 -// ENOCONN -const state: ServerState = 'TRIAL'; let regDevs = 0; let regTy = ''; switch (state) { @@ -101,10 +108,10 @@ switch (state) { break; } -const connectPluginInstalled = 'dynamix.unraid.net.staging.plg'; -// const connectPluginInstalled = ''; +// const connectPluginInstalled = 'dynamix.unraid.net.staging.plg'; +const connectPluginInstalled = ''; -const osVersion = '6.12.5'; +const osVersion = '6.12.8'; const osVersionBranch = 'stable'; // const parsedRegExp = regExp ? dayjs(regExp).format('YYYY-MM-DD') : undefined; @@ -133,21 +140,21 @@ export const serverState: Server = { apiKey: 'unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810', avatar: 'https://source.unsplash.com/300x300/?portrait', config: { - // error: 'INVALID', - valid: true, + error: null, + valid: false, }, connectPluginInstalled, description: 'DevServer9000', - deviceCount: 3, + deviceCount: 8, expireTime, flashBackupActivated: !!connectPluginInstalled, flashProduct: 'SanDisk_3.2Gen1', flashVendor: 'USB', - guid: staticGuid, + guid: currentFlashGuid, // "guid": "0781-5583-8355-81071A2B0211", inIframe: false, // keyfile: 'DUMMY_KEYFILE', - keyfile: 'TkJCrVyXMLWWGKZF6TCEvf0C86UYI9KfUDSOm7JoFP19tOMTMgLKcJ6QIOt9_9Psg_t0yF-ANmzSgZzCo94ljXoPm4BESFByR0K7nyY9KVvU8szLEUcBUT3xC2adxLrAXFNxiPeK-mZqt34n16uETKYvLKL_Sr5_JziG5L5lJFBqYZCPmfLMiguFo1vp0xL8pnBH7q8bYoBnePrAcAVb9mAGxFVPEInSPkMBfC67JLHz7XY1Y_K5bYIq3go9XPtLltJ53_U4BQiMHooXUBJCKXodpqoGxq0eV0IhNEYdauAhnTsG90qmGZig0hZalQ0soouc4JZEMiYEcZbn9mBxPg', + keyfile: keyfileBase64, lanIp: '192.168.254.36', license: '', locale: 'en_US', // en_US, ja @@ -161,7 +168,7 @@ export const serverState: Server = { regTo: 'Zack Spear', regTy, regExp, - // "regGuid": "0781-5583-8355-81071A2B0211", + regGuid, site: 'http://localhost:4321', state, theme: { @@ -173,15 +180,15 @@ export const serverState: Server = { name: 'white', textColor: '' }, - updateOsResponse: { - version: '6.12.6', - name: 'Unraid 6.12.6', - date: '2023-12-13', - isNewer: true, - isEligible: false, - changelog: 'https://docs.unraid.net/unraid-os/release-notes/6.12.6/', - sha256: '2f5debaf80549029cf6dfab0db59180e7e3391c059e6521aace7971419c9c4bf', - }, + // updateOsResponse: { + // version: '6.12.6', + // name: 'Unraid 6.12.6', + // date: '2023-12-13', + // isNewer: true, + // isEligible: false, + // changelog: 'https://docs.unraid.net/unraid-os/release-notes/6.12.6/', + // sha256: '2f5debaf80549029cf6dfab0db59180e7e3391c059e6521aace7971419c9c4bf', + // }, uptime, username: 'zspearmint', wanFQDN: '' diff --git a/web/components/Registration.ce.vue b/web/components/Registration.ce.vue index 72334f5b0..d904e2923 100644 --- a/web/components/Registration.ce.vue +++ b/web/components/Registration.ce.vue @@ -153,7 +153,7 @@ const items = computed((): RegistrationItemProps[] => { : []), ...(keyInstalled.value ? [{ - error: !!tooManyDevices.value, + error: tooManyDevices.value, label: t('Attached Storage Devices'), text: tooManyDevices.value ? t('{0} out of {1} allowed devices – upgrade your key to support more devices', [deviceCount.value, computedRegDevs.value]) diff --git a/web/composables/gql/graphql.ts b/web/composables/gql/graphql.ts index 275eb7e92..62f52d6ed 100644 --- a/web/composables/gql/graphql.ts +++ b/web/composables/gql/graphql.ts @@ -242,6 +242,7 @@ export type Config = { }; export enum ConfigErrorState { + Ineligible = 'INELIGIBLE', Invalid = 'INVALID', NoKeyServer = 'NO_KEY_SERVER', UnknownError = 'UNKNOWN_ERROR', diff --git a/web/store/server.ts b/web/store/server.ts index 547aaa428..67917f84d 100644 --- a/web/store/server.ts +++ b/web/store/server.ts @@ -5,6 +5,7 @@ import dayjs from 'dayjs'; import { defineStore, createPinia, setActivePinia } from 'pinia'; import prerelease from 'semver/functions/prerelease'; import { + ArrowPathIcon, ArrowRightOnRectangleIcon, CogIcon, GlobeAltIcon, @@ -17,7 +18,11 @@ import { useQuery } from '@vue/apollo-composable'; import { SERVER_CLOUD_FRAGMENT, SERVER_STATE_QUERY } from './server.fragment'; import { useFragment } from '~/composables/gql/fragment-masking'; import { WebguiState, WebguiUpdateIgnore } from '~/composables/services/webgui'; -import { WEBGUI_SETTINGS_MANAGMENT_ACCESS } from '~/helpers/urls'; +import { + WEBGUI_SETTINGS_MANAGMENT_ACCESS, + WEBGUI_TOOLS_REGISTRATION, + WEBGUI_TOOLS_UPDATE, +} from '~/helpers/urls'; import { useAccountStore } from '~/store/account'; import { useErrorsStore, type Error } from '~/store/errors'; import { usePurchaseStore } from '~/store/purchase'; @@ -683,24 +688,73 @@ export const useServerStore = defineStore('server', () => { }); const trialExtensionEligible = computed(() => !regGen.value || regGen.value < 2); - const tooManyDevices = computed((): Error | undefined => { - if ((deviceCount.value !== 0 && computedRegDevs.value > 0 && deviceCount.value > computedRegDevs.value) || - (!config.value?.valid && config.value?.error === 'INVALID')) { - return { - heading: 'Too Many Devices', - level: 'error', - message: 'You have exceeded the number of devices allowed for your license. Please remove a device before adding another.', - ref: 'tooManyDevices', - type: 'server', - }; + const serverConfigError = computed((): Error | undefined => { + if (!config.value?.valid && config.value?.error) { + switch (config.value?.error) { + case 'UNKNOWN_ERROR': + return { + heading: 'Unknown Error', + level: 'error', + message: 'An unknown internal error occurred.', + ref: 'configError', + type: 'server', + }; + case 'INELIGIBLE': + return { + heading: 'Ineligible for OS Version', + level: 'error', + message: 'Your License Key does not support this OS Version. OS build date greater than key expiration.', + actions: [{ + href: WEBGUI_TOOLS_REGISTRATION.toString(), + icon: CogIcon, + text: 'Learn More at Tools > Registration', + }], + ref: 'configError', + type: 'server', + }; + case 'INVALID': + return { + heading: 'Too Many Devices', + level: 'error', + message: 'You have exceeded the number of devices allowed for your license. Please remove a device before adding another or upgrade your key to support more devices.', + ref: 'configError', + type: 'server', + }; + case 'NO_KEY_SERVER': + return { + heading: 'Check Network Connection', + level: 'error', + message: 'Unable to validate your trial key. Please check your network connection.', + ref: 'configError', + type: 'server', + }; + case 'WITHDRAWN': + return { + heading: 'OS Version Withdrawn', + level: 'error', + message: 'This OS release should not be run. OS Update Required.', + actions: [{ + href: WEBGUI_TOOLS_UPDATE.toString(), + icon: ArrowPathIcon, + text: 'Check for Update', + }], + ref: 'configError', + type: 'server', + }; + } + return undefined; } - return undefined; }); - watch(tooManyDevices, (newVal, oldVal) => { + watch(serverConfigError, (newVal, oldVal) => { if (oldVal && oldVal.ref) { errorsStore.removeErrorByRef(oldVal.ref); } if (newVal) { errorsStore.setError(newVal); } }); + const tooManyDevices = computed((): boolean => { + return ((deviceCount.value !== 0 && computedRegDevs.value > 0 && deviceCount.value > computedRegDevs.value) || + (!config.value?.valid && config.value?.error === 'INVALID')); + }); + const pluginInstallFailed = computed((): Error | undefined => { if (connectPluginInstalled.value && connectPluginInstalled.value.includes('_installFailed')) { return { @@ -797,7 +851,7 @@ export const useServerStore = defineStore('server', () => { const serverErrors = computed(() => { return [ stateDataError.value, - tooManyDevices.value, + serverConfigError.value, pluginInstallFailed.value, deprecatedUnraidSSL.value, cloudError.value, @@ -1077,6 +1131,7 @@ export const useServerStore = defineStore('server', () => { stateDataError, serverErrors, tooManyDevices, + serverConfigError, // actions setServer, setUpdateOsResponse,