import { state, property, customElement } from "lit/decorators.js";
import { str, msg, localized } from "@lit/localize";
import debounce from "lodash/fp/debounce";
import { when } from "lit/directives/when.js";
import type { ZxcvbnResult } from "@zxcvbn-ts/core";
import type { ViewState } from "@/utils/APIRouter";
import LiteElement, { html } from "@/utils/LiteElement";
import PasswordService from "@/utils/PasswordService";
import type { Input as BtrixInput } from "@/components/ui/input";
const { PASSWORD_MINLENGTH, PASSWORD_MAXLENGTH, PASSWORD_MIN_SCORE } =
PasswordService;
@localized()
@customElement("btrix-reset-password")
export class ResetPassword extends LiteElement {
@property({ type: Object })
viewState!: ViewState;
@state()
private pwStrengthResults: null | ZxcvbnResult = null;
@state()
private serverError?: string;
@state()
private isSubmitting: boolean = false;
protected firstUpdated() {
PasswordService.setOptions();
}
render() {
let formError;
if (this.serverError) {
formError = html`
${this.serverError}
`;
}
return html`
`;
}
private renderPasswordStrength = () => html`
`;
private onPasswordInput = debounce(150)(async (e: InputEvent) => {
const { value } = e.target as BtrixInput;
if (!value || value.length < 4) {
this.pwStrengthResults = null;
return;
}
this.pwStrengthResults = await PasswordService.checkStrength(value);
}) as any;
async onSubmit(event: SubmitEvent) {
event.preventDefault();
this.isSubmitting = true;
const formData = new FormData(event.target as HTMLFormElement);
const password = formData.get("password") as string;
const resp = await fetch("/api/auth/reset-password", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
token: this.viewState.params.token,
password,
}),
});
switch (resp.status) {
case 200:
// TODO show toast notification
this.navTo("/log-in");
break;
case 400:
case 422:
const { detail } = await resp.json();
if (detail === "reset_password_bad_token") {
// TODO password validation details
this.serverError = msg(
"Password reset email is not valid. Request a new password reset email"
);
} else if (detail.code && detail.code === "invalid_password") {
this.serverError = msg(
"Invalid password. Must be between 8 and 64 characters"
);
}
break;
default:
this.serverError = msg("Something unexpected went wrong");
break;
}
this.isSubmitting = false;
}
}