Fix BanUnbanForm floating promises and add submit guards
This commit is contained in:
@@ -29,54 +29,59 @@ export function BanUnbanForm({ jailNames, onBan, onUnban }: BanUnbanFormProps):
|
||||
const [unbanJail, setUnbanJail] = useState("");
|
||||
const [formError, setFormError] = useState<string | null>(null);
|
||||
const [formSuccess, setFormSuccess] = useState<string | null>(null);
|
||||
const [isBanning, setIsBanning] = useState(false);
|
||||
const [isUnbanning, setIsUnbanning] = useState(false);
|
||||
|
||||
const handleBan = (): void => {
|
||||
const formatErrorMessage = (err: unknown): string =>
|
||||
err instanceof ApiError
|
||||
? `${String(err.status)}: ${err.body}`
|
||||
: err instanceof Error
|
||||
? err.message
|
||||
: String(err);
|
||||
|
||||
const handleBan = async (): Promise<void> => {
|
||||
setFormError(null);
|
||||
setFormSuccess(null);
|
||||
if (!banIpVal.trim() || !banJail) {
|
||||
setFormError("Both IP address and jail are required.");
|
||||
return;
|
||||
}
|
||||
onBan(banJail, banIpVal.trim())
|
||||
.then(() => {
|
||||
setFormSuccess(`${banIpVal.trim()} banned in ${banJail}.`);
|
||||
setBanIpVal("");
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
const msg =
|
||||
err instanceof ApiError
|
||||
? `${String(err.status)}: ${err.body}`
|
||||
: err instanceof Error
|
||||
? err.message
|
||||
: String(err);
|
||||
setFormError(msg);
|
||||
});
|
||||
|
||||
setIsBanning(true);
|
||||
try {
|
||||
const ip = banIpVal.trim();
|
||||
await onBan(banJail, ip);
|
||||
setFormSuccess(`${ip} banned in ${banJail}.`);
|
||||
setBanIpVal("");
|
||||
} catch (err: unknown) {
|
||||
setFormError(formatErrorMessage(err));
|
||||
} finally {
|
||||
setIsBanning(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnban = (fromAllJails: boolean): void => {
|
||||
const handleUnban = async (fromAllJails: boolean): Promise<void> => {
|
||||
setFormError(null);
|
||||
setFormSuccess(null);
|
||||
if (!unbanIpVal.trim()) {
|
||||
setFormError("IP address is required.");
|
||||
return;
|
||||
}
|
||||
const jail = fromAllJails ? undefined : unbanJail || undefined;
|
||||
onUnban(unbanIpVal.trim(), jail)
|
||||
.then(() => {
|
||||
const scope = jail ?? "all jails";
|
||||
setFormSuccess(`${unbanIpVal.trim()} unbanned from ${scope}.`);
|
||||
setUnbanIpVal("");
|
||||
setUnbanJail("");
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
const msg =
|
||||
err instanceof ApiError
|
||||
? `${String(err.status)}: ${err.body}`
|
||||
: err instanceof Error
|
||||
? err.message
|
||||
: String(err);
|
||||
setFormError(msg);
|
||||
});
|
||||
|
||||
setIsUnbanning(true);
|
||||
try {
|
||||
const ip = unbanIpVal.trim();
|
||||
const jail = fromAllJails ? undefined : unbanJail || undefined;
|
||||
await onUnban(ip, jail);
|
||||
const scope = jail ?? "all jails";
|
||||
setFormSuccess(`${ip} unbanned from ${scope}.`);
|
||||
setUnbanIpVal("");
|
||||
setUnbanJail("");
|
||||
} catch (err: unknown) {
|
||||
setFormError(formatErrorMessage(err));
|
||||
} finally {
|
||||
setIsUnbanning(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -130,7 +135,9 @@ export function BanUnbanForm({ jailNames, onBan, onUnban }: BanUnbanFormProps):
|
||||
</Select>
|
||||
</Field>
|
||||
</div>
|
||||
<Button appearance="primary" icon={<LockClosedRegular />} onClick={handleBan}>
|
||||
<Button appearance="primary" icon={<LockClosedRegular />} onClick={() => {
|
||||
void handleBan();
|
||||
}} disabled={isBanning}>
|
||||
Ban
|
||||
</Button>
|
||||
</div>
|
||||
@@ -167,10 +174,14 @@ export function BanUnbanForm({ jailNames, onBan, onUnban }: BanUnbanFormProps):
|
||||
</Select>
|
||||
</Field>
|
||||
</div>
|
||||
<Button appearance="secondary" icon={<LockOpenRegular />} onClick={() => { handleUnban(false); }}>
|
||||
<Button appearance="secondary" icon={<LockOpenRegular />} onClick={() => {
|
||||
void handleUnban(false);
|
||||
}} disabled={isUnbanning}>
|
||||
Unban
|
||||
</Button>
|
||||
<Button appearance="outline" icon={<LockOpenRegular />} onClick={() => { handleUnban(true); }}>
|
||||
<Button appearance="outline" icon={<LockOpenRegular />} onClick={() => {
|
||||
void handleUnban(true);
|
||||
}} disabled={isUnbanning}>
|
||||
Unban from All Jails
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user