From 3b24d44d99255e7c1653a093257e33aa9d21a0b9 Mon Sep 17 00:00:00 2001 From: Pavel Jankoski Date: Tue, 25 Jun 2024 00:31:44 +0200 Subject: [PATCH 1/2] console: Remove logic that prefills gateway and device ID --- CHANGELOG.md | 2 ++ .../containers/dev-eui-component/index.js | 23 ++----------------- .../device-onboarding-form/messages.js | 1 - .../claiming-form-section/index.js | 3 --- .../registration-form-section/index.js | 3 --- .../gateway-provisioning-form/index.js | 19 +-------------- .../identity-server-form/index.js | 1 - .../basic-settings-form/index.js | 1 + .../gateway-general-settings/messages.js | 2 ++ pkg/webui/lib/field-description-messages.js | 16 +++++++------ pkg/webui/locales/en.json | 8 +++---- pkg/webui/locales/ja.json | 4 ++-- 12 files changed, 23 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e98964c392..45e6728d0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ For details about compatibility between different releases, see the **Commitment ### Changed +- Gateway ID and device ID are not autogenerated and prefilled anymore. + ### Deprecated ### Removed diff --git a/pkg/webui/console/containers/dev-eui-component/index.js b/pkg/webui/console/containers/dev-eui-component/index.js index e88df9cbff..6d357e86e3 100644 --- a/pkg/webui/console/containers/dev-eui-component/index.js +++ b/pkg/webui/console/containers/dev-eui-component/index.js @@ -18,7 +18,7 @@ import classnames from 'classnames' import { defineMessages } from 'react-intl' import Input from '@ttn-lw/components/input' -import Form, { useFormContext } from '@ttn-lw/components/form' +import Form from '@ttn-lw/components/form' import Message from '@ttn-lw/lib/components/message' @@ -44,7 +44,6 @@ const m = defineMessages({ const DevEUIComponent = props => { const { name, required, disabled, autoFocus } = props - const { values, setFieldValue, touched } = useFormContext() const dispatch = useDispatch() const appId = useSelector(selectSelectedApplicationId) @@ -53,9 +52,6 @@ const DevEUIComponent = props => { const [devEUIGenerated, setDevEUIGenerated] = useState(false) const [errorMessage, setErrorMessage] = useState(undefined) const applicationDevEUICounter = useSelector(selectApplicationDevEUICount) - const idTouched = touched?.ids?.device_id || touched?.target_device_id - const hasEuiId = - /eui-\d{16}/.test(values?.target_device_id) || /eui-\d{16}/.test(values?.ids?.device_id) const indicatorContent = errorMessage || { ...sharedMessages.used, @@ -76,24 +72,11 @@ const DevEUIComponent = props => { return result.dev_eui }, [appId, dispatch, fetchDevEUICounter, promisifiedIssueDevEUI]) - const handleIdPrefill = useCallback( - eventOrEui => { - const value = typeof eventOrEui === 'string' ? eventOrEui : eventOrEui.target.value - if (value.length === 16 && (!idTouched || hasEuiId)) { - const generatedId = `eui-${value.toLowerCase()}` - setFieldValue('target_device_id', generatedId) - setFieldValue('ids.device_id', generatedId) - } - }, - [hasEuiId, idTouched, setFieldValue], - ) - const handleGenerate = useCallback(async () => { try { const result = await handleDevEUIRequest() setDevEUIGenerated(true) setErrorMessage(undefined) - handleIdPrefill(result) return result } catch (error) { if (getBackendErrorName(error) === 'global_eui_limit_reached') { @@ -101,7 +84,7 @@ const DevEUIComponent = props => { } else setErrorMessage(m.unknownError) setDevEUIGenerated(true) } - }, [handleDevEUIRequest, handleIdPrefill]) + }, [handleDevEUIRequest]) const devEUIGenerateDisabled = applicationDevEUICounter === env.devEUIConfig.applicationLimit || @@ -117,7 +100,6 @@ const DevEUIComponent = props => { max={8} component={Input.Generate} tooltipId={tooltipIds.DEV_EUI} - onBlur={handleIdPrefill} onGenerateValue={handleGenerate} actionDisable={devEUIGenerateDisabled} required={required} @@ -136,7 +118,6 @@ const DevEUIComponent = props => { required={required} component={Input} tooltipId={tooltipIds.DEV_EUI} - onBlur={handleIdPrefill} disabled={disabled} autoFocus={autoFocus} /> diff --git a/pkg/webui/console/containers/device-onboarding-form/messages.js b/pkg/webui/console/containers/device-onboarding-form/messages.js index 922f343007..0e1b7999f2 100644 --- a/pkg/webui/console/containers/device-onboarding-form/messages.js +++ b/pkg/webui/console/containers/device-onboarding-form/messages.js @@ -37,7 +37,6 @@ export default defineMessages({ singleRegistration: 'View registered end device', multipleRegistration: 'Register another end device of this type', createSuccess: 'End device registered', - deviceIdDescription: 'This value is automatically prefilled using the DevEUI', onboardingDisabled: 'Device onboarding can only be performed on deployments that have Network Server, Application Server and Join Server activated. Please use the CLI to register devices on individual components.', pingSlotDataRateTitle: 'Ping slot data rate', diff --git a/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/claiming-form-section/index.js b/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/claiming-form-section/index.js index bf38c296b7..c57c9d42b3 100644 --- a/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/claiming-form-section/index.js +++ b/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/claiming-form-section/index.js @@ -22,8 +22,6 @@ import DevEUIComponent from '@console/containers/dev-eui-component' import tooltipIds from '@ttn-lw/lib/constants/tooltip-ids' import sharedMessages from '@ttn-lw/lib/shared-messages' -import m from '../../messages' - const initialValues = { authenticated_identifiers: { dev_eui: '', @@ -57,7 +55,6 @@ const DeviceClaimingFormSection = () => { component={Input} inputRef={idInputRef} tooltipId={tooltipIds.DEVICE_ID} - description={m.deviceIdDescription} /> ) diff --git a/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/registration-form-section/index.js b/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/registration-form-section/index.js index 711f257071..358a6403b6 100644 --- a/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/registration-form-section/index.js +++ b/pkg/webui/console/containers/device-onboarding-form/provisioning-form-section/registration-form-section/index.js @@ -27,8 +27,6 @@ import sharedMessages from '@ttn-lw/lib/shared-messages' import { parseLorawanMacVersion, generate16BytesKey } from '@console/lib/device-utils' import { checkFromState, mayEditApplicationDeviceKeys } from '@console/lib/feature-checks' -import messages from '../../messages' - import { initialValues } from './validation-schema' const devAddrEncoder = dev_addr => ({ ids: { dev_addr }, session: { dev_addr } }) @@ -177,7 +175,6 @@ const DeviceRegistrationFormSection = () => { component={Input} inputRef={idInputRef} tooltipId={tooltipIds.DEVICE_ID} - description={messages.deviceIdDescription} /> ) diff --git a/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/index.js b/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/index.js index a803a827fe..312b12c014 100644 --- a/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/index.js +++ b/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/index.js @@ -25,8 +25,6 @@ import useDebounce from '@ttn-lw/lib/hooks/use-debounce' import GatewayRegistrationFormSection from './gateway-registration-form-section' -const euiIdRegexp = /eui-\d{16}/ - // Empty strings will be interpreted as zero value (00 fill) by the backend // For this reason, they need to be transformed to undefined instead, // so that the value will be properly stripped when sent to the backend. @@ -34,9 +32,7 @@ const gatewayEuiEncoder = value => (value === '' ? undefined : value) const gatewayEuiDecoder = value => (value === undefined ? '' : value) const GatewayProvisioningFormSection = () => { - const { touched, setFieldValue, values, setFieldTouched } = useFormContext() - const idTouched = touched?.ids?.gateway_id - const hasEuiId = euiIdRegexp.test(values.ids.gateway_id) + const { setFieldValue, values, setFieldTouched } = useFormContext() const isEuiMac = useMemo(() => values.ids.eui?.length === 12, [values.ids.eui]) const debouncedEui = useDebounce(values.ids.eui, 3000) const isDebouncedEuiMac = useMemo(() => debouncedEui?.length === 12, [debouncedEui]) @@ -50,21 +46,9 @@ const GatewayProvisioningFormSection = () => { } }, [isDebouncedEuiMac, isEuiMac, setFieldTouched, showMacConvert]) - // Prefill the gateway ID after the EUI is entered. - const handleEuiBlur = useCallback( - event => { - const val = event.target.value - if (val.length === 16 && (!idTouched || hasEuiId)) { - setFieldValue('ids.gateway_id', `eui-${val.toLowerCase()}`) - } - }, - [hasEuiId, idTouched, setFieldValue], - ) - const handleConvertMacToEui = useCallback(() => { const euiValue = `${values.ids.eui.substring(0, 6)}FFFE${values.ids.eui.substring(6)}` setFieldValue('ids.eui', euiValue) - setFieldValue('ids.gateway_id', `eui-${euiValue.toLowerCase()}`) }, [setFieldValue, values.ids.eui]) return ( @@ -79,7 +63,6 @@ const GatewayProvisioningFormSection = () => { placeholder={sharedMessages.gatewayEUI} component={Input} tooltipId={tooltipIds.GATEWAY_EUI} - onBlur={handleEuiBlur} encode={gatewayEuiEncoder} decode={gatewayEuiDecoder} autoFocus diff --git a/pkg/webui/console/views/device-general-settings/identity-server-form/index.js b/pkg/webui/console/views/device-general-settings/identity-server-form/index.js index 0cec5907c4..9e0fe572d3 100644 --- a/pkg/webui/console/views/device-general-settings/identity-server-form/index.js +++ b/pkg/webui/console/views/device-general-settings/identity-server-form/index.js @@ -199,7 +199,6 @@ const IdentityServerForm = React.memo(props => { title={sharedMessages.devID} name="ids.device_id" placeholder={sharedMessages.deviceIdPlaceholder} - description={sharedMessages.deviceIdDescription} required disabled component={Input} diff --git a/pkg/webui/console/views/gateway-general-settings/basic-settings-form/index.js b/pkg/webui/console/views/gateway-general-settings/basic-settings-form/index.js index 6d56cf74c8..29da469cd7 100644 --- a/pkg/webui/console/views/gateway-general-settings/basic-settings-form/index.js +++ b/pkg/webui/console/views/gateway-general-settings/basic-settings-form/index.js @@ -272,6 +272,7 @@ const BasicSettingsForm = React.memo(props => { entityId={gtwId} entityName={gateway.name} message={m.deleteGateway} + defaultMessage={m.deleteGatewayDefaultMessage} onApprove={onGatewayDelete} shouldConfirm={shouldConfirmDelete} mayPurge={mayPurge} diff --git a/pkg/webui/console/views/gateway-general-settings/messages.js b/pkg/webui/console/views/gateway-general-settings/messages.js index e4bbe33e52..ce09e6959d 100644 --- a/pkg/webui/console/views/gateway-general-settings/messages.js +++ b/pkg/webui/console/views/gateway-general-settings/messages.js @@ -30,6 +30,8 @@ const messages = defineMessages({ 'Administrative contact information for this gateway. Typically used to indicate who to contact with administrative questions about the gateway.', techContactDescription: 'Technical contact information for this gateway. Typically used to indicate who to contact with technical/security questions about the gateway.', + deleteGatewayDefaultMessage: + 'This will PERMANENTLY DELETE THE ENTITY ITSELF AND ALL ASSOCIATED ENTITIES, including collaborator associations. It will also NOT BE POSSIBLE TO REUSE THE ENTITY ID until purged by an admin but the EUI can be reregistered later with a different ID.', }) export default messages diff --git a/pkg/webui/lib/field-description-messages.js b/pkg/webui/lib/field-description-messages.js index 61f178304e..21f6897010 100644 --- a/pkg/webui/lib/field-description-messages.js +++ b/pkg/webui/lib/field-description-messages.js @@ -20,6 +20,8 @@ import TOOLTIP_IDS from '@ttn-lw/lib/constants/tooltip-ids' import sharedMessages from './shared-messages' const m = defineMessages({ + idLocation: + 'Enter a value using lowercase letters, numbers, and dashes. You can choose this freely.', freqPlanDescription: 'A frequency plan defines data rates that your end device or gateway is setup to use. It is important that gateways and end devices within reach use the same frequency plan to be able to communicate.', freqPlanLocation: @@ -43,9 +45,8 @@ const m = defineMessages({ 'An end device specific encryption key used to derive the FNwkSIntKey, SNwkSIntKey, NwkSEncKey in LoRaWAN 1.1. When a LoRaWAN 1.1 capable device connects to a LoRaWAN 1.0x Network Server which does not support dual root keys (NwkKey and AppKey), the NwkKey value is used as the AppKey value.', nwkKeyLocation: 'It is usually pre-provisioned by the end device manufacturer, but some end devices also allow using a user-defined value.', - devIdDescription: 'A unique, human-readable identifier for your end device.', - devIdLocation: - 'We prefill this value using the previously entered DevEUI but you can use any other unique value you want. End device IDs can not be reused by multiple end devices within the same application.', + devIdDescription: + 'A mandatory identifier for your end device that must be unique within the application and cannot be changed after creation. It is used to reference your end device e.g. in events, webhooks and API requests.', joinServerDescription: "The Join Server's role is to store root keys, generate session keys, and to send those securely to the Network Server and Application Server of choice. The device contains the same root keys, which can be provisioned as part of assembly, distribution or upon installation.", joinServerLocation: @@ -109,7 +110,8 @@ const m = defineMessages({ 'The data rate used for the second reception window used by this end device to receive downlinks.', rx2FrequencyDescription: 'The frequency used for the second reception window used by this end device to receive downlinks.', - gatewayIdDescription: 'A unique identifier for your gateway.', + gatewayIdDescription: + 'A mandatory identifier for your gateway that must be unique per network and cannot be changed after creation. It is used to reference your end device e.g. in events, webhooks and API requests.', gatewayEuiDescription: 'A 64 bit extended unique identifier for your gateway.', gatewayEuiLocation: 'It should be provided to you by the manufacturer, or printed on the gateway packaging.', @@ -248,7 +250,7 @@ const descriptions = Object.freeze({ }, [TOOLTIP_IDS.DEVICE_ID]: { description: m.devIdDescription, - location: m.devIdLocation, + location: m.idLocation, glossaryId: GLOSSARY_IDS.DEVICE_ID, }, [TOOLTIP_IDS.JOIN_SERVER]: { @@ -338,8 +340,8 @@ const descriptions = Object.freeze({ absence: sharedMessages.absenceContactManufacturer, }, [TOOLTIP_IDS.GATEWAY_ID]: { - description: sharedMessages.absenceContactManufacturer, - location: m.gatewayIdLocation, + description: m.gatewayIdDescription, + location: m.idLocation, glossaryId: GLOSSARY_IDS.GATEWAY_ID, }, [TOOLTIP_IDS.GATEWAY_EUI]: { diff --git a/pkg/webui/locales/en.json b/pkg/webui/locales/en.json index f81cb36f0f..861c6ad35f 100644 --- a/pkg/webui/locales/en.json +++ b/pkg/webui/locales/en.json @@ -474,7 +474,6 @@ "console.containers.device-onboarding-form.messages.singleRegistration": "View registered end device", "console.containers.device-onboarding-form.messages.multipleRegistration": "Register another end device of this type", "console.containers.device-onboarding-form.messages.createSuccess": "End device registered", - "console.containers.device-onboarding-form.messages.deviceIdDescription": "This value is automatically prefilled using the DevEUI", "console.containers.device-onboarding-form.messages.onboardingDisabled": "Device onboarding can only be performed on deployments that have Network Server, Application Server and Join Server activated. Please use the CLI to register devices on individual components.", "console.containers.device-onboarding-form.messages.pingSlotDataRateTitle": "Ping slot data rate", "console.containers.device-onboarding-form.messages.rx2DataRateIndexTitle": "Rx2 data rate", @@ -817,6 +816,7 @@ "console.views.gateway-general-settings.messages.disablePacketBrokerForwarding": "Disable forwarding uplink messages received from this gateway to the Packet Broker", "console.views.gateway-general-settings.messages.adminContactDescription": "Administrative contact information for this gateway. Typically used to indicate who to contact with administrative questions about the gateway.", "console.views.gateway-general-settings.messages.techContactDescription": "Technical contact information for this gateway. Typically used to indicate who to contact with technical/security questions about the gateway.", + "console.views.gateway-general-settings.messages.deleteGatewayDefaultMessage": "This will PERMANENTLY DELETE THE ENTITY ITSELF AND ALL ASSOCIATED ENTITIES, including collaborator associations. It will also NOT BE POSSIBLE TO REUSE THE ENTITY ID until purged by an admin but the EUI can be reregistered later with a different ID.", "console.views.gateway-overview.index.downloadGlobalConf": "Download global_conf.json", "console.views.gateway-overview.index.globalConf": "Global configuration", "console.views.gateway-overview.index.globalConfFailed": "Failed to download global_conf.json", @@ -882,6 +882,7 @@ "lib.errors.status-code-messages.501": "Not implemented", "lib.errors.status-code-messages.503": "Service unavailable", "lib.errors.status-code-messages.504": "Gateway timeout", + "lib.field-description-messages.idLocation": "Enter a value using lowercase letters, numbers, and dashes. You can choose this freely.", "lib.field-description-messages.freqPlanDescription": "A frequency plan defines data rates that your end device or gateway is setup to use. It is important that gateways and end devices within reach use the same frequency plan to be able to communicate.", "lib.field-description-messages.freqPlanLocation": "Your end device or gateway manufacturer should provide information about the applicable frequency plan for a particular device. In some cases they are printed on the device itself but they should always be in the hardware manual or data sheet.", "lib.field-description-messages.freqPlanAbsence": "Contact the manufacturer or reseller. Using an incorrect frequency plan will prevent traffic between devices.", @@ -894,8 +895,7 @@ "lib.field-description-messages.appKeyLocation": "It is usually pre-provisioned by the end device manufacturer, but can also be created by the user.", "lib.field-description-messages.nwkKeyDescription": "An end device specific encryption key used to derive the FNwkSIntKey, SNwkSIntKey, NwkSEncKey in LoRaWAN 1.1. When a LoRaWAN 1.1 capable device connects to a LoRaWAN 1.0x Network Server which does not support dual root keys (NwkKey and AppKey), the NwkKey value is used as the AppKey value.", "lib.field-description-messages.nwkKeyLocation": "It is usually pre-provisioned by the end device manufacturer, but some end devices also allow using a user-defined value.", - "lib.field-description-messages.devIdDescription": "A unique, human-readable identifier for your end device.", - "lib.field-description-messages.devIdLocation": "We prefill this value using the previously entered DevEUI but you can use any other unique value you want. End device IDs can not be reused by multiple end devices within the same application.", + "lib.field-description-messages.devIdDescription": "A mandatory identifier for your end device that must be unique within the application and cannot be changed after creation. It is used to reference your end device e.g. in events, webhooks and API requests.", "lib.field-description-messages.joinServerDescription": "The Join Server's role is to store root keys, generate session keys, and to send those securely to the Network Server and Application Server of choice. The device contains the same root keys, which can be provisioned as part of assembly, distribution or upon installation.", "lib.field-description-messages.joinServerLocation": "Contact your manufacturer or reseller to find out if your end device is pre-provisioned on an external Join Server. If not, you may use the local Join Server, or provision the end device on our Global Join Server so that you can transfer it without lock-in.", "lib.field-description-messages.joinServerAbsence": "If the end device is pre-provisioned, you will need the keys from the manufacturer to activate it.", @@ -931,7 +931,7 @@ "lib.field-description-messages.frameCounterWidthAbsence": "Contact your manufacturer or reseller. Most devices use 32 bit counters. Selecting the wrong value will produce errors once the Up or Down frame counter exceeds 16 bits and rolls over.", "lib.field-description-messages.rx2DataRateIndexDescription": "The data rate used for the second reception window used by this end device to receive downlinks.", "lib.field-description-messages.rx2FrequencyDescription": "The frequency used for the second reception window used by this end device to receive downlinks.", - "lib.field-description-messages.gatewayIdDescription": "A unique identifier for your gateway.", + "lib.field-description-messages.gatewayIdDescription": "A mandatory identifier for your gateway that must be unique per network and cannot be changed after creation. It is used to reference your end device e.g. in events, webhooks and API requests.", "lib.field-description-messages.gatewayEuiDescription": "A 64 bit extended unique identifier for your gateway.", "lib.field-description-messages.gatewayEuiLocation": "It should be provided to you by the manufacturer, or printed on the gateway packaging.", "lib.field-description-messages.gatewayEuiAbsence": "Some gateways do not use EUIs. In that case, you can continue without EUI. If you are unsure, we recommend contacting the manufacturer or reseller.", diff --git a/pkg/webui/locales/ja.json b/pkg/webui/locales/ja.json index 5bd1a0d445..197eb7627b 100644 --- a/pkg/webui/locales/ja.json +++ b/pkg/webui/locales/ja.json @@ -474,7 +474,6 @@ "console.containers.device-onboarding-form.messages.singleRegistration": "登録されたエンドデバイスを表示", "console.containers.device-onboarding-form.messages.multipleRegistration": "このタイプのエンドデバイスをもう1台登録", "console.containers.device-onboarding-form.messages.createSuccess": "エンドデバイス登録済み", - "console.containers.device-onboarding-form.messages.deviceIdDescription": "この値は、DevEUIを使用して自動的にプリフィルドされます", "console.containers.device-onboarding-form.messages.onboardingDisabled": "デバイスのオンボーディングは、Network Server、Application Server、Join Serverが有効になっているデプロイメントでのみ実行可能です。個々のコンポーネントにデバイスを登録するには、CLIを使用してください", "console.containers.device-onboarding-form.messages.pingSlotDataRateTitle": "Pingスロットのデータレート", "console.containers.device-onboarding-form.messages.rx2DataRateIndexTitle": "Rx2 データレート", @@ -817,6 +816,7 @@ "console.views.gateway-general-settings.messages.disablePacketBrokerForwarding": "このゲートウェイから受信したアップリンクメッセージをPacket Brokerに転送しないようにします", "console.views.gateway-general-settings.messages.adminContactDescription": "このゲートウェイの管理連絡先情報。通常、ゲートウェイに関する管理的な質問をする人を指すために使用されます。", "console.views.gateway-general-settings.messages.techContactDescription": "このゲートウェイの技術連絡先情報。通常、ゲートウェイに関する技術的/セキュリティ的な質問をする人を指すために使用されます。", + "console.views.gateway-general-settings.messages.deleteGatewayDefaultMessage": "", "console.views.gateway-overview.index.downloadGlobalConf": "global_conf.json のダウンロード", "console.views.gateway-overview.index.globalConf": "グローバル設定", "console.views.gateway-overview.index.globalConfFailed": "global_conf.json のダウンロードに失敗しました", @@ -882,6 +882,7 @@ "lib.errors.status-code-messages.501": "未実装", "lib.errors.status-code-messages.503": "サービス利用不可", "lib.errors.status-code-messages.504": "ゲートウェイのタイムアウト", + "lib.field-description-messages.idLocation": "", "lib.field-description-messages.freqPlanDescription": "周波数プランは、エンドデバイスやゲートウェイが使用するように設定されたデータレートを定義します。ゲートウェイとエンドデバイスが通信できるようにするためには、同じ周波数プランを使用することが重要です", "lib.field-description-messages.freqPlanLocation": "エンドデバイスやゲートウェイのメーカーは、特定のデバイスに適用される周波数プランに関する情報を提供するはずです。場合によっては、デバイス自体に印刷されていることもありますが、常にハードウェアマニュアルまたはデータシートに記載されているはずです", "lib.field-description-messages.freqPlanAbsence": "メーカーまたは再販業者にお問い合わせください。不正な周波数プランを使用すると、機器間のトラフィックが妨げられます", @@ -895,7 +896,6 @@ "lib.field-description-messages.nwkKeyDescription": "LoRaWAN 1.1 の FNwkSIntKey、SNwkSIntKey、NwkSEncKey の導出に使用するエンドデバイス固有の暗号化キーです。LoRaWAN 1.1 対応デバイスが、デュアルルート鍵(NwkKey と AppKey)をサポートしない LoRaWAN 1.0x ネットワークサーバに接続する場合、NwkKey 値は AppKey 値として使用されます", "lib.field-description-messages.nwkKeyLocation": "通常、エンドデバイスのメーカーがあらかじめ用意しているものですが、エンドデバイスによっては、ユーザー定義の値を使用することも可能です", "lib.field-description-messages.devIdDescription": "エンドデバイスのための、人間が読めるユニークな識別子です", - "lib.field-description-messages.devIdLocation": "この値は、以前に入力されたDevEUIを使用してプレフィルしますが、他のユニークな値を使用することができます。エンドデバイスIDは、同じアプリケーション内の複数のエンドデバイスで再利用することはできません", "lib.field-description-messages.joinServerDescription": "Join Serverの役割は、ルートキーの保存、セッションキーの生成、およびそれらを選択したネットワークサーバーとアプリケーションサーバーに安全に送信することである。デバイスには同じルート鍵が含まれており、組み立て、配布、インストール時にプロビジョニングすることができます", "lib.field-description-messages.joinServerLocation": "エンドデバイスが外部Join Serverにあらかじめプロビジョニングされているかどうかについては、メーカーまたは再販業者にお問い合わせください。そうでない場合は、ローカルJoin Serverを使用するか、エンドデバイスを当社のGlobal Join Serverでプロビジョニングして、ロックインせずに転送できるようにします", "lib.field-description-messages.joinServerAbsence": "エンドデバイスがプリプロビジョニングされている場合は、アクティベーションのためにメーカーからのキーが必要です", From 9466fef84a89fa24b33dd26dba99daa552a9d373 Mon Sep 17 00:00:00 2001 From: Pavel Jankoski Date: Thu, 4 Jul 2024 13:36:10 +0200 Subject: [PATCH 2/2] console: Fix e2e tests --- .../devices/onboarding/claiming.spec.js | 4 -- .../onboarding/manual-registration.spec.js | 18 +++++---- .../devices/onboarding/qr-scan.spec.js | 2 +- .../repository-registration.spec.js | 37 +++++-------------- cypress/e2e/console/gateways/create.spec.js | 9 +++-- cypress/e2e/smoke/gateways/create.js | 1 + 6 files changed, 27 insertions(+), 44 deletions(-) diff --git a/cypress/e2e/console/devices/onboarding/claiming.spec.js b/cypress/e2e/console/devices/onboarding/claiming.spec.js index 0e6e855dee..90a4e2f06d 100644 --- a/cypress/e2e/console/devices/onboarding/claiming.spec.js +++ b/cypress/e2e/console/devices/onboarding/claiming.spec.js @@ -81,8 +81,6 @@ describe('End device repository claiming', () => { // Provision first device using claiming flow. cy.findByLabelText('DevEUI').type(device1.devEui) cy.findByLabelText('Claim authentication code').type(device1.cac) - cy.findByLabelText('End device ID').should('have.value', `eui-${device1.devEui.toLowerCase()}`) - cy.findByLabelText('End device ID').clear() cy.findByLabelText('End device ID').type(device1.id) cy.findByLabelText('Register another end device of this type').check() cy.findByRole('button', { name: 'Register end device' }).click() @@ -97,8 +95,6 @@ describe('End device repository claiming', () => { // Provision second device using claiming flow. cy.findByLabelText('DevEUI').type(device2.devEui) cy.findByLabelText('Claim authentication code').type(device2.cac) - cy.findByLabelText('End device ID').should('have.value', `eui-${device2.devEui.toLowerCase()}`) - cy.findByLabelText('End device ID').clear() cy.findByLabelText('End device ID').type(device2.id) cy.findByLabelText('View registered end device').check() cy.findByRole('button', { name: 'Register end device' }).click() diff --git a/cypress/e2e/console/devices/onboarding/manual-registration.spec.js b/cypress/e2e/console/devices/onboarding/manual-registration.spec.js index a4feeb4fe8..a4102e2157 100644 --- a/cypress/e2e/console/devices/onboarding/manual-registration.spec.js +++ b/cypress/e2e/console/devices/onboarding/manual-registration.spec.js @@ -124,6 +124,7 @@ describe('End device manual create', () => { cy.findByLabelText('LoRaWAN version').selectOption(device.lorawan_version) cy.findByLabelText('JoinEUI').type(`${device.join_eui}{enter}`) cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByLabelText('AppKey') .parents('[data-test-id="form-field"]') .findByRole('button', { name: /Generate/ }) @@ -165,10 +166,7 @@ describe('End device manual create', () => { cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) cy.findByLabelText('AppKey').type(device.app_key) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${device.dev_eui.toLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLocaleLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() @@ -201,6 +199,7 @@ describe('End device manual create', () => { cy.findByLabelText('JoinEUI').type(device.join_eui) cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByLabelText('AppKey').type(device.app_key) cy.findByRole('button', { name: 'Register end device' }).click() @@ -234,6 +233,7 @@ describe('End device manual create', () => { cy.findByLabelText('JoinEUI').type(device.join_eui) cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() @@ -265,6 +265,7 @@ describe('End device manual create', () => { cy.findByLabelText('JoinEUI').type(device.join_eui) cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByLabelText('AppKey').type(device.app_key) cy.findByRole('button', { name: 'Register end device' }).click() @@ -300,6 +301,7 @@ describe('End device manual create', () => { cy.findByLabelText('JoinEUI').type(device.join_eui) cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByLabelText('AppKey').type(device.app_key) cy.findByRole('button', { name: 'Register end device' }).click() @@ -332,6 +334,7 @@ describe('End device manual create', () => { cy.findByLabelText('JoinEUI').type(device.join_eui) cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByLabelText('AppKey').type(device.app_key) cy.findByRole('button', { name: 'Register end device' }).click() @@ -366,6 +369,7 @@ describe('End device manual create', () => { cy.findByLabelText('JoinEUI').type(device.join_eui) cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByLabelText('AppKey').type(device.app_key) cy.findByRole('button', { name: 'Register end device' }).click() @@ -402,6 +406,7 @@ describe('End device manual create', () => { cy.findByLabelText('JoinEUI').type(device.join_eui) cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(device.dev_eui) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLowerCase()}`) cy.findByLabelText('AppKey').type(device.app_key) cy.findByLabelText('NwkKey').type(device.nwk_key) @@ -592,10 +597,7 @@ describe('End device manual create', () => { cy.findByLabelText('FNwkSIntKey').type(device.f_nwk_s_int_key) cy.findByLabelText('SNwkSIntKey').type(device.f_nwk_s_int_key) cy.findByLabelText('NwkSEncKey').type(device.f_nwk_s_int_key) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${device.dev_eui.toLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${device.dev_eui.toLocaleLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() diff --git a/cypress/e2e/console/devices/onboarding/qr-scan.spec.js b/cypress/e2e/console/devices/onboarding/qr-scan.spec.js index f9d21593a0..9caf84f108 100644 --- a/cypress/e2e/console/devices/onboarding/qr-scan.spec.js +++ b/cypress/e2e/console/devices/onboarding/qr-scan.spec.js @@ -161,7 +161,7 @@ describe('Device onboarding with QR scan', () => { cy.findByLabelText('DevEUI').should('have.value', devEui).should('be.disabled') cy.findByRole('button', { name: 'Reset' }).should('be.disabled') cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should('have.value', `eui-${device.devEui}`) + cy.findByLabelText('End device ID').type(`eui-${device.devEui.toLocaleLowerCase()}`) // Reset QR data. cy.findByRole('button', { name: /Reset QR code data/g }).click() diff --git a/cypress/e2e/console/devices/onboarding/repository-registration.spec.js b/cypress/e2e/console/devices/onboarding/repository-registration.spec.js index e8d84e26da..af313a436f 100644 --- a/cypress/e2e/console/devices/onboarding/repository-registration.spec.js +++ b/cypress/e2e/console/devices/onboarding/repository-registration.spec.js @@ -135,10 +135,7 @@ describe('End device repository manual registration', () => { cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(devEui) cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${devEui.toLocaleLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${devEui.toLocaleLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() @@ -193,10 +190,7 @@ describe('End device repository manual registration', () => { cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(devEui) cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${devEui.toLocaleLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${devEui.toLocaleLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() @@ -222,10 +216,7 @@ describe('End device repository manual registration', () => { cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(devEui) cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${devEui.toLocaleLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${devEui.toLocaleLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() @@ -288,10 +279,7 @@ describe('End device repository manual registration', () => { cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(devEui) cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${devEui.toLocaleLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${devEui.toLocaleLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() @@ -340,10 +328,7 @@ describe('End device repository manual registration', () => { cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(devEui) cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${devEui.toLocaleLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${devEui.toLocaleLowerCase()}`) cy.findByRole('button', { name: 'Register end device' }).click() @@ -369,10 +354,8 @@ describe('End device repository manual registration', () => { cy.findByRole('button', { name: 'Confirm' }).click() cy.findByLabelText('DevEUI').type(devEui1) cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${devEui1.toLocaleLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${devEui1.toLocaleLowerCase()}`) + cy.findByLabelText('Register another end device of this type').check() cy.findByRole('button', { name: 'Register end device' }).click() @@ -386,10 +369,8 @@ describe('End device repository manual registration', () => { // End device registration. cy.findByLabelText('DevEUI').type(devEui2) cy.findByLabelText('AppKey').type(generateHexValue(32)) - cy.findByLabelText('End device ID').should( - 'have.value', - `eui-${devEui2.toLocaleLowerCase()}`, - ) + cy.findByLabelText('End device ID').type(`eui-${devEui2.toLocaleLowerCase()}`) + cy.findByLabelText('View registered end device').check() cy.findByRole('button', { name: 'Register end device' }).click() diff --git a/cypress/e2e/console/gateways/create.spec.js b/cypress/e2e/console/gateways/create.spec.js index bc9ca5843d..60d285bb93 100644 --- a/cypress/e2e/console/gateways/create.spec.js +++ b/cypress/e2e/console/gateways/create.spec.js @@ -52,7 +52,7 @@ describe('Gateway create', () => { cy.findByLabelText('Gateway EUI').type(gateway.eui) cy.findByLabelText('Gateway EUI').blur() - cy.findByLabelText('Gateway ID').should('have.value', `eui-${gateway.eui}`) + cy.findByLabelText('Gateway ID').type(`eui-${gateway.eui}`) cy.findByLabelText('Gateway name').type('Test Gateway') cy.findByText('Frequency plan') .parents('div[data-test-id="form-field"]') @@ -78,7 +78,7 @@ describe('Gateway create', () => { cy.contains('Convert MAC to EUI').should('not.exist') const gatewayEui = `${gatewayMac.substring(0, 6)}fffe${gatewayMac.substring(6)}` - cy.findByLabelText('Gateway ID').should('have.value', `eui-${gatewayEui}`) + cy.findByLabelText('Gateway ID').type(`eui-${gatewayEui}`) }) it('succeeds showing modal when generating API keys for CUPS and LNS', () => { @@ -89,7 +89,7 @@ describe('Gateway create', () => { cy.findByLabelText('Gateway EUI').type(gateway.eui) cy.findByLabelText('Gateway EUI').blur() - cy.findByLabelText('Gateway ID').should('have.value', `eui-${gateway.eui}`) + cy.findByLabelText('Gateway ID').type(`eui-${gateway.eui}`) cy.findByLabelText('Gateway name').type('Test Gateway') cy.findByText('Frequency plan') .parents('div[data-test-id="form-field"]') @@ -129,6 +129,7 @@ describe('Gateway create', () => { } cy.findByLabelText('Gateway EUI').type(gateway.eui) + cy.findByLabelText('Gateway ID').type(`eui-${gateway.eui}`) cy.findByText('Frequency plan') .parents('div[data-test-id="form-field"]') .find('input') @@ -153,6 +154,7 @@ describe('Gateway create', () => { } cy.findByLabelText('Gateway EUI').type(gateway.eui) + cy.findByLabelText('Gateway ID').type(`eui-${gateway.eui}`) cy.findByText('Frequency plan') .parents('div[data-test-id="form-field"]') .find('input') @@ -192,6 +194,7 @@ describe('Gateway create', () => { } cy.findByLabelText('Gateway EUI').type(gateway.eui) + cy.findByLabelText('Gateway ID').type(`eui-${gateway.eui}`) cy.findByTestId('key-value-map').should('not.exist') cy.findByRole('button', { name: 'Register gateway' }).click() diff --git a/cypress/e2e/smoke/gateways/create.js b/cypress/e2e/smoke/gateways/create.js index 250b0b8465..27b010328b 100644 --- a/cypress/e2e/smoke/gateways/create.js +++ b/cypress/e2e/smoke/gateways/create.js @@ -40,6 +40,7 @@ const gatewayCreate = defineSmokeTest('succeeds creating gateway', () => { cy.findByRole('link', { name: /Register gateway/ }).click() cy.findByLabelText('Gateway EUI').type(gateway.eui) cy.findByLabelText('Gateway name').type(gateway.name) + cy.findByLabelText('Gateway ID').type(`eui-${gateway.eui}`) cy.findByText('Frequency plan') .parents('div[data-test-id="form-field"]') .find('input')