forked from NotNet/gluestick
hack together change password page
not a modal yet
This commit is contained in:
parent
dac227c937
commit
33e680a43f
4 changed files with 126 additions and 1 deletions
29
src/actions/changePassword.ts
Normal file
29
src/actions/changePassword.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
"use server";
|
||||
|
||||
import { getUser } from "@/auth/auth";
|
||||
import { getUserInfo, setPassword, validateUser } from "@/ldap";
|
||||
import { ActionResponse } from ".";
|
||||
import { PasswordUpdateSchema, passwordUpdateSchema } from "@/schemas";
|
||||
|
||||
export default async function changePassword(
|
||||
data: PasswordUpdateSchema
|
||||
): Promise<ActionResponse> {
|
||||
const user = await getUser();
|
||||
if (user == null) return { ok: false, error: "noUser" };
|
||||
|
||||
const userInfo = await getUserInfo(user);
|
||||
if (userInfo == null) {
|
||||
return { ok: false, error: "notRegisteredYet" };
|
||||
}
|
||||
|
||||
const { password, newPassword } = passwordUpdateSchema.parse(data);
|
||||
|
||||
const passwordMatches = await validateUser(user.username!, password);
|
||||
if (!passwordMatches) {
|
||||
return { ok: false, error: "incorrectPassword" };
|
||||
}
|
||||
|
||||
await setPassword(user.username!, newPassword);
|
||||
|
||||
return { ok: true };
|
||||
}
|
|
@ -18,6 +18,7 @@ import MigaduIcon from "@/components/icons/MigaduIcon";
|
|||
import { AboutMeSchema, aboutMeSchema } from "@/schemas";
|
||||
import update from "@/actions/update";
|
||||
import { toFormikValidationSchema } from "zod-formik-adapter";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function AboutMe({
|
||||
info,
|
||||
|
@ -30,6 +31,7 @@ export default function AboutMe({
|
|||
const [globalError, setGlobalError] = React.useState<string | null>(null);
|
||||
const [madeProfileChanges, setMadeChanges] = React.useState(false);
|
||||
const [madePasswordChanges, setMadePasswordChanges] = React.useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
const initialValues: AboutMeSchema = {
|
||||
username: info.username,
|
||||
|
@ -120,7 +122,14 @@ export default function AboutMe({
|
|||
/>
|
||||
|
||||
<div className={styles.multiButtons}>
|
||||
<button type="button">Change password</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
router.push("/me/change-password");
|
||||
}}
|
||||
>
|
||||
Change password
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
|
|
76
src/app/me/change-password/ChangePasswordForm.tsx
Normal file
76
src/app/me/change-password/ChangePasswordForm.tsx
Normal file
|
@ -0,0 +1,76 @@
|
|||
"use client";
|
||||
|
||||
import changePassword from "@/actions/changePassword";
|
||||
import Input from "@/components/Input";
|
||||
import PrettyForm from "@/components/PrettyForm";
|
||||
import { PasswordUpdateSchema, passwordUpdateSchema } from "@/schemas";
|
||||
import { Form, Formik, FormikHelpers } from "formik";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React from "react";
|
||||
import { toFormikValidationSchema } from "zod-formik-adapter";
|
||||
|
||||
export default function ChangePasswordForm({
|
||||
onSuccess
|
||||
}: {
|
||||
onSuccess?: () => void;
|
||||
}) {
|
||||
const [globalError, setGlobalError] = React.useState<string | null>(null);
|
||||
const router = useRouter();
|
||||
|
||||
const initialValues: PasswordUpdateSchema = {
|
||||
password: "",
|
||||
newPassword: "",
|
||||
confirmPassword: ""
|
||||
};
|
||||
|
||||
async function handleFormSubmit(
|
||||
data: PasswordUpdateSchema,
|
||||
helpers: FormikHelpers<PasswordUpdateSchema>
|
||||
) {
|
||||
helpers.setSubmitting(true);
|
||||
setGlobalError(null);
|
||||
const res = await changePassword(data);
|
||||
|
||||
if (!res.ok) {
|
||||
setGlobalError(res.error!); // should probably make this more human readable :trolley:
|
||||
} else {
|
||||
if (onSuccess == null) {
|
||||
console.log("changed password :3");
|
||||
router.push("/me");
|
||||
} else {
|
||||
onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
helpers.setSubmitting(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<PrettyForm globalError={globalError}>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
validationSchema={toFormikValidationSchema(passwordUpdateSchema)}
|
||||
>
|
||||
{({ isSubmitting }) => (
|
||||
<Form>
|
||||
<Input type="password" name="password" label="Current Password" />
|
||||
<Input type="password" name="newPassword" label="New Password" />
|
||||
<Input
|
||||
type="password"
|
||||
name="confirmPassword"
|
||||
label="Confirm New Password"
|
||||
hint="Re-enter your new password. Better safe than sorry!"
|
||||
/>
|
||||
|
||||
<button type="submit" disabled={isSubmitting}>
|
||||
Change Password
|
||||
</button>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</PrettyForm>
|
||||
</>
|
||||
);
|
||||
}
|
11
src/app/me/change-password/page.tsx
Normal file
11
src/app/me/change-password/page.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import ChangePasswordForm from "./ChangePasswordForm";
|
||||
|
||||
export default function ChangePassword() {
|
||||
return (
|
||||
// fuck it im lazy
|
||||
<div style={{ maxWidth: "400px", margin: "2rem auto" }}>
|
||||
<h1>Change Password</h1>
|
||||
<ChangePasswordForm />
|
||||
</div>
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue