-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Daniel Kastl <[email protected]>
- Loading branch information
Showing
8 changed files
with
209 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// configHandler.ts | ||
|
||
import { getFormValues } from './formHandler'; | ||
import { buildProtobuf } from './protobufBuilder'; | ||
import { generateQRCode } from './qrCodeGenerator'; | ||
import { toUrlSafeBase64 } from './utils'; | ||
|
||
/** | ||
* Generate a QR code and URL based on the form values. | ||
*/ | ||
export async function generateConfig(): Promise<void> { | ||
const formValues = getFormValues(); | ||
|
||
// Validate channel name length | ||
const byteLength = new TextEncoder().encode(formValues.channelName).length; | ||
if (byteLength > 12) { | ||
alert(`Channel name must be less than or equal to 12 bytes (current byte length: ${byteLength}).`); | ||
return; | ||
} | ||
|
||
// Generate the protobuf binary data for the form values | ||
const channelSet = buildProtobuf(formValues); | ||
const binaryData = channelSet.toBinary(); // Binary data from Protobuf | ||
|
||
// Convert to URL-safe Base64 string | ||
const base64 = toUrlSafeBase64(binaryData); | ||
|
||
// Update the URL hash with the generated configuration | ||
window.location.hash = `#${base64}`; | ||
|
||
// Create the Meshtastic URL | ||
const meshtasticUrl = `https://meshtastic.org/e/#${base64}`; | ||
console.log("Generated Meshtastic URL:", meshtasticUrl); | ||
|
||
// Update the generated URL in the input field | ||
const urlField = document.getElementById('generatedUrl') as HTMLInputElement; | ||
urlField.value = meshtasticUrl; | ||
|
||
// Generate the QR code from the URL | ||
await generateQRCode(meshtasticUrl); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// loadConfigurationFromHash.ts | ||
|
||
import { Protobuf } from "@meshtastic/js"; | ||
import { populateForm } from './formHandler'; | ||
import { determinePskType } from "./pskHandler"; | ||
import { fromUrlSafeBase64 } from './utils'; | ||
|
||
/** | ||
* Load the configuration from the hash and populate the form. | ||
* @param {string} hash - The URL-safe Base64 configuration string. | ||
*/ | ||
export function loadConfigurationFromHash(hash: string): void { | ||
try { | ||
const binaryData = fromUrlSafeBase64(hash); | ||
const channelSet = Protobuf.AppOnly.ChannelSet.fromBinary(binaryData); | ||
|
||
// Extract the channel settings from the Protobuf message | ||
const channelSettings = channelSet.settings[0]; | ||
|
||
// Determine PSK type based on the length of the PSK | ||
const pskType = determinePskType(channelSettings.psk.length); | ||
|
||
const formValues = { | ||
channelName: channelSettings.name, | ||
pskType: pskType, // Derived from PSK length | ||
psk: new TextDecoder().decode(channelSettings.psk), | ||
uplinkEnabled: channelSettings.uplinkEnabled, | ||
downlinkEnabled: channelSettings.downlinkEnabled, | ||
positionPrecision: channelSettings.moduleSettings?.positionPrecision || 0, | ||
isClientMuted: channelSettings.moduleSettings?.isClientMuted || false, | ||
region: channelSet.loraConfig.region, | ||
modemPreset: channelSet.loraConfig.modemPreset, | ||
hopLimit: channelSet.loraConfig.hopLimit, | ||
ignoreMqtt: channelSet.loraConfig.ignoreMqtt, | ||
configOkToMqtt: channelSet.loraConfig.configOkToMqtt, | ||
}; | ||
|
||
// Populate the form with these values using formHandler | ||
populateForm(formValues); | ||
} catch (error) { | ||
console.error("Error loading configuration from URL hash:", error); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// pskHandler.ts | ||
|
||
import { generateConfig } from './configHandler'; | ||
|
||
/** | ||
* Generate a PSK (Pre-Shared Key) for the given PSK type. | ||
* @param pskType | ||
* @returns | ||
*/ | ||
export function generatePSK(pskType: string): string { | ||
const pskBytes = new Uint8Array(getPskLengthFromType(pskType)); | ||
|
||
if (pskBytes.length === 0) { | ||
return ''; // No encryption | ||
} | ||
|
||
window.crypto.getRandomValues(pskBytes); | ||
return Array.from(pskBytes).map(b => ('0' + b.toString(16)).slice(-2)).join(''); | ||
} | ||
|
||
/** | ||
* Handle the change event on the PSK type select element. | ||
* Enable or disable the PSK input field based on the selected PSK type. | ||
*/ | ||
export function handlePSKTypeChange(): void { | ||
const pskType = (document.getElementById('pskType') as HTMLSelectElement).value; | ||
const pskField = document.getElementById('psk') as HTMLInputElement; | ||
|
||
if (pskType === 'none') { | ||
pskField.value = ''; | ||
pskField.disabled = true; | ||
} else { | ||
pskField.disabled = false; | ||
handleGeneratePSK(); | ||
} | ||
|
||
// Re-generate config when PSK type changes | ||
generateConfig(); | ||
} | ||
|
||
/** | ||
* Handle the click event on the "Generate PSK" button. | ||
* Generate a PSK based on the selected PSK type and set the value in the input field. | ||
*/ | ||
export function handleGeneratePSK(): void { | ||
const pskType = (document.getElementById('pskType') as HTMLSelectElement).value; | ||
const psk = generatePSK(pskType); | ||
(document.getElementById('psk') as HTMLInputElement).value = psk; | ||
|
||
// Re-generate config when PSK is generated | ||
generateConfig(); | ||
} | ||
|
||
/** | ||
* Determine the PSK type based on the PSK length. | ||
* @param pskLength - The length of the PSK string. | ||
* @returns {string} - 'none', 'aes128', or 'aes256' | ||
*/ | ||
export function determinePskType(pskLength: number): string { | ||
if (pskLength === 32) { // AES-128 (16 bytes * 2 hex chars per byte) | ||
return 'aes128'; | ||
} else if (pskLength === 64) { // AES-256 (32 bytes * 2 hex chars per byte) | ||
return 'aes256'; | ||
} else { | ||
return 'none'; | ||
} | ||
} | ||
|
||
/** | ||
* Get the PSK byte length based on the PSK type. | ||
* @param {string} pskType - 'none', 'aes128', or 'aes256' | ||
* @returns {number} - The expected byte length for the PSK | ||
*/ | ||
export function getPskLengthFromType(pskType: string): number { | ||
if (pskType === 'aes128') { | ||
return 16; // AES-128: 16 bytes | ||
} else if (pskType === 'aes256') { | ||
return 32; // AES-256: 32 bytes | ||
} else { | ||
return 0; // No encryption | ||
} | ||
} |
Oops, something went wrong.