优化登录验证码锁定交互
This commit is contained in:
@@ -3,6 +3,8 @@ import { describe, it } from "node:test";
|
||||
import {
|
||||
buildCaptchaImageUrl,
|
||||
buildSendMobileCodeRequest,
|
||||
isImageCaptchaLocked,
|
||||
resolveImageCaptchaInteractionState,
|
||||
resolveLoginErrorMessage,
|
||||
} from "./loginSms.ts";
|
||||
|
||||
@@ -63,4 +65,46 @@ describe("login sms api helpers", () => {
|
||||
"网络错误",
|
||||
);
|
||||
});
|
||||
|
||||
it("locks image captcha while sms countdown is active", () => {
|
||||
assert.equal(isImageCaptchaLocked(60), true);
|
||||
assert.equal(isImageCaptchaLocked(1), true);
|
||||
assert.equal(isImageCaptchaLocked(0), false);
|
||||
});
|
||||
|
||||
it("resolves captcha field and refresh button interaction state", () => {
|
||||
assert.deepEqual(
|
||||
resolveImageCaptchaInteractionState({
|
||||
smsSending: false,
|
||||
smsCountdown: 60,
|
||||
}),
|
||||
{
|
||||
disabled: true,
|
||||
clearable: false,
|
||||
refreshDisabled: true,
|
||||
},
|
||||
);
|
||||
assert.deepEqual(
|
||||
resolveImageCaptchaInteractionState({
|
||||
smsSending: false,
|
||||
smsCountdown: 0,
|
||||
}),
|
||||
{
|
||||
disabled: false,
|
||||
clearable: true,
|
||||
refreshDisabled: false,
|
||||
},
|
||||
);
|
||||
assert.deepEqual(
|
||||
resolveImageCaptchaInteractionState({
|
||||
smsSending: true,
|
||||
smsCountdown: 0,
|
||||
}),
|
||||
{
|
||||
disabled: true,
|
||||
clearable: false,
|
||||
refreshDisabled: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,6 +10,17 @@ export interface CaptchaImageUrlOptions {
|
||||
cacheBust?: number | string;
|
||||
}
|
||||
|
||||
export interface ImageCaptchaInteractionParams {
|
||||
smsSending: boolean;
|
||||
smsCountdown: number;
|
||||
}
|
||||
|
||||
export interface ImageCaptchaInteractionState {
|
||||
disabled: boolean;
|
||||
clearable: boolean;
|
||||
refreshDisabled: boolean;
|
||||
}
|
||||
|
||||
function trimEndSlash(value: string): string {
|
||||
return value.replace(/\/+$/, "");
|
||||
}
|
||||
@@ -39,6 +50,23 @@ export function createCaptchaRandomStr(): string {
|
||||
return `${Date.now()}${Math.random().toString(36).slice(2, 10)}`;
|
||||
}
|
||||
|
||||
export function isImageCaptchaLocked(smsCountdown: number): boolean {
|
||||
return smsCountdown > 0;
|
||||
}
|
||||
|
||||
export function resolveImageCaptchaInteractionState({
|
||||
smsSending,
|
||||
smsCountdown,
|
||||
}: ImageCaptchaInteractionParams): ImageCaptchaInteractionState {
|
||||
const disabled = smsSending || isImageCaptchaLocked(smsCountdown);
|
||||
|
||||
return {
|
||||
disabled,
|
||||
clearable: !disabled,
|
||||
refreshDisabled: disabled,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildCaptchaImageUrl(
|
||||
randomStr: string,
|
||||
options: CaptchaImageUrlOptions = {},
|
||||
|
||||
Reference in New Issue
Block a user