diff --git a/frontend/src/components/FinalMaskForm.tsx b/frontend/src/components/FinalMaskForm.tsx
index 682eee75..d8973f64 100644
--- a/frontend/src/components/FinalMaskForm.tsx
+++ b/frontend/src/components/FinalMaskForm.tsx
@@ -424,8 +424,19 @@ function UdpMaskItem({
const type = getFieldValue([...absolutePath, 'type']) as string | undefined;
if (type === 'mkcp-aes128gcm' || type === 'salamander') {
return (
-
-
+
+
+
+
+
+ }
+ onClick={() => form.setFieldValue(
+ [...absolutePath, 'settings', 'password'],
+ RandomUtil.randomLowerAndNum(16),
+ )}
+ />
+
);
}
diff --git a/frontend/src/pages/inbounds/InboundFormModal.tsx b/frontend/src/pages/inbounds/InboundFormModal.tsx
index f0b62c9f..3295bb63 100644
--- a/frontend/src/pages/inbounds/InboundFormModal.tsx
+++ b/frontend/src/pages/inbounds/InboundFormModal.tsx
@@ -26,7 +26,7 @@ import {
DeleteOutlined,
MinusOutlined,
PlusOutlined,
- SyncOutlined,
+ ReloadOutlined,
} from '@ant-design/icons';
import { HttpUtil, NumberFormatter, RandomUtil, SizeFormatter, Wireguard } from '@/utils';
@@ -762,6 +762,18 @@ export default function InboundFormModal({
security: 'tls',
hysteriaSettings: HysteriaStreamSettingsSchema.parse({}),
tlsSettings: tls,
+ // Hysteria2 needs an obfs wrapper on the FinalMask side; seed
+ // it with salamander + a random password so the listener boots
+ // with a usable default. Re-selecting Hysteria from another
+ // protocol re-runs this and refreshes the password — that's
+ // intentional, the form was already being reset.
+ finalmask: {
+ tcp: [],
+ udp: [{
+ type: 'salamander',
+ settings: { password: RandomUtil.randomLowerAndNum(16) },
+ }],
+ },
});
} else {
const current = form.getFieldValue('streamSettings') as { network?: string } | undefined;
@@ -1048,16 +1060,13 @@ export default function InboundFormModal({
<>
{protocol === Protocols.WIREGUARD && (
<>
-
- Secret key{' '}
-
- >
- }
- >
-
+
+
+
+
+
+ } onClick={regenInboundWg} />
+
@@ -1106,19 +1115,16 @@ export default function InboundFormModal({
)}
-
- Secret key{' '}
- regenWgPeerKeypair(field.name)}
- />
- >
- }
- >
-
+
+
+
+
+
+ }
+ onClick={() => regenWgPeerKeypair(field.name)}
+ />
+
@@ -1362,25 +1368,22 @@ export default function InboundFormModal({
/>
{isSSWith2022 && (
-
- Password{' '}
- {
- const method = form.getFieldValue(['settings', 'method']);
- form.setFieldValue(
- ['settings', 'password'],
- RandomUtil.randomShadowsocksPassword(method as string),
- );
- }}
- />
- >
- }
- >
-
+
+
+
+
+
+ }
+ onClick={() => {
+ const method = form.getFieldValue(['settings', 'method']);
+ form.setFieldValue(
+ ['settings', 'password'],
+ RandomUtil.randomShadowsocksPassword(method as string),
+ );
+ }}
+ />
+
)}
@@ -2759,27 +2762,24 @@ export default function InboundFormModal({
options={Object.values(UTLS_FINGERPRINT).map((fp) => ({ value: fp, label: fp }))}
/>
-
- Target{' '}
-
- >
- }
- >
-
+
+
+
+
+
+ } onClick={randomizeRealityTarget} />
+
-
- SNI{' '}
-
- >
- }
- >
-
+
+
+
+
+
+ } onClick={randomizeRealityTarget} />
+
-
- Short IDs{' '}
-
- >
- }
- >
-
+
+
+
+
+
+ } onClick={randomizeShortIds} />
+