mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-06 08:43:36 +02:00
Clarify repeater interaction button re: passwords and ACLs
This commit is contained in:
+19
-19
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -13,7 +13,7 @@
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<script type="module" crossorigin src="/assets/index-w8xAO9M9.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DkHyTtP0.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DZ67iE5i.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -264,6 +264,7 @@ export function ConfigModal({
|
||||
<Input
|
||||
id="private-key"
|
||||
type="password"
|
||||
autoComplete="off"
|
||||
value={privateKey}
|
||||
onChange={(e) => setPrivateKey(e.target.value)}
|
||||
placeholder="64-character hex private key"
|
||||
|
||||
@@ -104,14 +104,12 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
e.preventDefault();
|
||||
const trimmed = text.trim();
|
||||
|
||||
// For repeater mode, allow empty password via "."
|
||||
// For repeater mode, empty password means guest login
|
||||
if (isRepeaterMode) {
|
||||
if (sending || disabled) return;
|
||||
// "." means empty password
|
||||
const password = trimmed === '.' ? '' : trimmed;
|
||||
setSending(true);
|
||||
try {
|
||||
await onSend(password);
|
||||
await onSend(trimmed);
|
||||
setText('');
|
||||
} catch (err) {
|
||||
console.error('Failed to request telemetry:', err);
|
||||
@@ -156,10 +154,8 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
[handleSubmit]
|
||||
);
|
||||
|
||||
// For repeater mode, enable submit if there's text OR if it's just "." for empty password
|
||||
const canSubmit = isRepeaterMode
|
||||
? text.trim().length > 0 || text === '.'
|
||||
: text.trim().length > 0;
|
||||
// For repeater mode, always allow submit (empty = guest login)
|
||||
const canSubmit = isRepeaterMode ? true : text.trim().length > 0;
|
||||
|
||||
// Show character counter for messages (not repeater mode or raw)
|
||||
const showCharCounter = !isRepeaterMode && limits !== null;
|
||||
@@ -170,12 +166,13 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
<Input
|
||||
ref={inputRef}
|
||||
type={isRepeaterMode ? 'password' : 'text'}
|
||||
autoComplete={isRepeaterMode ? 'off' : undefined}
|
||||
value={text}
|
||||
onChange={(e) => setText(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
placeholder={
|
||||
placeholder ||
|
||||
(isRepeaterMode ? 'Enter password (or . for none)...' : 'Type a message...')
|
||||
(isRepeaterMode ? 'Enter password for admin login...' : 'Type a message...')
|
||||
}
|
||||
disabled={disabled || sending}
|
||||
className="flex-1 min-w-0"
|
||||
@@ -187,10 +184,12 @@ export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(fu
|
||||
>
|
||||
{sending
|
||||
? isRepeaterMode
|
||||
? 'Fetching...'
|
||||
? 'Logging in...'
|
||||
: 'Sending...'
|
||||
: isRepeaterMode
|
||||
? 'Fetch'
|
||||
? text.trim()
|
||||
? 'Log in with password'
|
||||
: 'Log in as guest/use repeater ACLs'
|
||||
: 'Send'}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* regress if the code is modified:
|
||||
*
|
||||
* 1. Repeater messages should NOT have sender parsed from text (colons are common in CLI output)
|
||||
* 2. Password field "." should convert to empty string (for repeaters with no password)
|
||||
* 2. Empty password field = guest login, password field with text = password login
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
@@ -91,42 +91,40 @@ describe('Repeater message sender parsing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Repeater password handling', () => {
|
||||
describe('Repeater login behavior', () => {
|
||||
/**
|
||||
* The "." password convention allows users to specify an empty password
|
||||
* for repeaters that don't require authentication. Without this, users
|
||||
* couldn't submit an empty password through the form.
|
||||
* Repeater login has two modes:
|
||||
* - Empty password field = guest login (uses repeater's ACL permissions)
|
||||
* - Password in field = admin login attempt
|
||||
*/
|
||||
|
||||
it('"." converts to empty password', () => {
|
||||
it('empty input results in empty password (guest login)', () => {
|
||||
// This is the logic in MessageInput.tsx handleSubmit
|
||||
const trimmed = '.';
|
||||
const password = trimmed === '.' ? '' : trimmed;
|
||||
|
||||
expect(password).toBe('');
|
||||
});
|
||||
|
||||
it('normal password is passed through unchanged', () => {
|
||||
const trimmed: string = 'mySecretPassword';
|
||||
const password = trimmed === '.' ? '' : trimmed;
|
||||
|
||||
expect(password).toBe('mySecretPassword');
|
||||
});
|
||||
|
||||
it('"." with surrounding whitespace still works after trim', () => {
|
||||
// In MessageInput, text.trim() is called before the check
|
||||
const text = ' . ';
|
||||
const text = '';
|
||||
const trimmed = text.trim();
|
||||
const password = trimmed === '.' ? '' : trimmed;
|
||||
|
||||
expect(password).toBe('');
|
||||
// Empty string is passed directly to onSend
|
||||
expect(trimmed).toBe('');
|
||||
});
|
||||
|
||||
it('".." is NOT converted (only single dot)', () => {
|
||||
const trimmed: string = '..';
|
||||
const password = trimmed === '.' ? '' : trimmed;
|
||||
it('password is passed through unchanged', () => {
|
||||
const text = 'mySecretPassword';
|
||||
const trimmed = text.trim();
|
||||
|
||||
// Double dot is passed through as-is (it's a valid password)
|
||||
expect(password).toBe('..');
|
||||
expect(trimmed).toBe('mySecretPassword');
|
||||
});
|
||||
|
||||
it('whitespace-only input is treated as empty (guest login)', () => {
|
||||
const text = ' ';
|
||||
const trimmed = text.trim();
|
||||
|
||||
expect(trimmed).toBe('');
|
||||
});
|
||||
|
||||
it('password with surrounding whitespace is trimmed', () => {
|
||||
const text = ' secret123 ';
|
||||
const trimmed = text.trim();
|
||||
|
||||
expect(trimmed).toBe('secret123');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user