impr: validate username on google signup (@fehmer) (#6895)

This commit is contained in:
Christian Fehmer 2025-08-20 22:30:08 +02:00 committed by GitHub
parent 76597e6a08
commit 7d04637f7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,5 +1,4 @@
import * as Notifications from "../elements/notifications";
import { debounce } from "throttle-debounce";
import {
sendEmailVerification,
updateProfile,
@ -13,9 +12,10 @@ import * as AccountController from "../auth";
import * as CaptchaController from "../controllers/captcha-controller";
import * as Loader from "../elements/loader";
import { subscribe as subscribeToSignUpEvent } from "../observables/google-sign-up-event";
import { InputIndicator } from "../elements/input-indicator";
import AnimatedModal from "../utils/animated-modal";
import { resetIgnoreAuthCallback } from "../firebase";
import { validateWithIndicator } from "../elements/input-validation";
import { UserNameSchema } from "@monkeytype/schemas/users";
let signedInUser: UserCredential | undefined = undefined;
@ -140,55 +140,37 @@ function disableButton(): void {
$("#googleSignUpModal button").prop("disabled", true);
}
const nameInputEl = document.querySelector(
"#googleSignUpModal input"
) as HTMLInputElement;
function enableInput(): void {
$("#googleSignUpModal input").prop("disabled", false);
nameInputEl.disabled = false;
}
function disableInput(): void {
$("#googleSignUpModal input").prop("disabled", true);
nameInputEl.disabled = true;
}
const nameIndicator = new InputIndicator($("#googleSignUpModal input"), {
available: {
icon: "fa-check",
level: 1,
},
unavailable: {
icon: "fa-times",
level: -1,
},
taken: {
icon: "fa-user",
level: -1,
},
checking: {
icon: "fa-circle-notch",
spinIcon: true,
level: 0,
},
});
validateWithIndicator(nameInputEl, {
schema: UserNameSchema,
isValid: async (name: string) => {
const checkNameResponse = (
await Ape.users.getNameAvailability({
params: { name: name },
})
).status;
const checkNameDebounced = debounce(1000, async () => {
const val = $("#googleSignUpModal input").val() as string;
if (!val) return;
const response = await Ape.users.getNameAvailability({
params: { name: val },
});
if (response.status === 200) {
nameIndicator.show("available", response.body.message);
enableButton();
} else if (response.status === 422) {
nameIndicator.show("unavailable", response.body.message);
} else if (response.status === 409) {
nameIndicator.show("taken", response.body.message);
} else {
nameIndicator.show("unavailable");
Notifications.add(
"Failed to check name availability: " + response.body.message,
-1
);
}
return checkNameResponse === 200 ? true : "Name not available";
},
debounceDelay: 1000,
callback: (result) => {
if (result.status === "success") {
enableButton();
} else {
disableButton();
}
},
});
async function setup(modalEl: HTMLElement): Promise<void> {
@ -196,17 +178,6 @@ async function setup(modalEl: HTMLElement): Promise<void> {
e.preventDefault();
void apply();
});
modalEl.querySelector("input")?.addEventListener("input", () => {
disableButton();
const val = $("#googleSignUpModal input").val() as string;
if (val === "") {
nameIndicator.hide();
return;
} else {
nameIndicator.show("checking");
checkNameDebounced();
}
});
}
subscribeToSignUpEvent((signedInUser, isNewUser) => {