added chaging of password
This commit is contained in:
@@ -24,11 +24,6 @@ func hashPassword(password string) ([]byte, error) {
|
||||
return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
}
|
||||
|
||||
// validates a password against the password-rules
|
||||
func ValidatePassword(password string) bool {
|
||||
return len(password) >= 12 && len(password) <= 64
|
||||
}
|
||||
|
||||
func Get() (map[string]User, error) {
|
||||
if users, hit := c.Get("users"); !hit {
|
||||
refresh()
|
||||
@@ -41,7 +36,7 @@ func Get() (map[string]User, error) {
|
||||
|
||||
type UserAdd struct {
|
||||
UserName string `json:"userName" validate:"required" db:"userName"`
|
||||
Password string `json:"password" validate:"required,min=8"`
|
||||
Password string `json:"password" validate:"required,min=12"`
|
||||
Admin bool `json:"admin" db:"admin"`
|
||||
}
|
||||
|
||||
@@ -70,6 +65,36 @@ func Add(user UserAdd) error {
|
||||
}
|
||||
}
|
||||
|
||||
type UserChangePassword struct {
|
||||
UserName string `json:"userName" validate:"required" db:"userName"`
|
||||
Password string `json:"password" validate:"required,min=12"`
|
||||
}
|
||||
|
||||
func ChangePassword(user UserChangePassword) error {
|
||||
// try to hash teh password
|
||||
if hash, err := hashPassword(user.Password); err != nil {
|
||||
return err
|
||||
} else {
|
||||
execStruct := struct {
|
||||
UserName string `db:"userName"`
|
||||
Password []byte `db:"password"`
|
||||
TokenID string `db:"tokenID"`
|
||||
}{
|
||||
UserName: user.UserName,
|
||||
Password: hash,
|
||||
TokenID: uuid.NewString(),
|
||||
}
|
||||
|
||||
if _, err := db.DB.NamedExec("UPDATE USERS SET tokenID = :tokenID, password = :password WHERE name = :userName", execStruct); err != nil {
|
||||
return err
|
||||
} else {
|
||||
refresh()
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
// get the usersRaw from the database
|
||||
var usersRaw []User
|
||||
|
||||
@@ -84,7 +84,9 @@ func init() {
|
||||
"events": postEvent,
|
||||
"users": postUser,
|
||||
},
|
||||
"PATCH": {},
|
||||
"PATCH": {
|
||||
"users/password": patchPassword,
|
||||
},
|
||||
"DELETE": {
|
||||
"event": deleteEvent,
|
||||
},
|
||||
|
||||
@@ -34,3 +34,29 @@ func postUser(args HandlerArgs) responseMessage {
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
func patchPassword(args HandlerArgs) responseMessage {
|
||||
response := responseMessage{}
|
||||
// parse the body
|
||||
var body users.UserChangePassword
|
||||
|
||||
if err := args.C.BodyParser(&body); err != nil {
|
||||
response.Status = fiber.StatusBadRequest
|
||||
|
||||
logger.Log().Msgf("can't parse body: %v", err)
|
||||
} else {
|
||||
body.UserName = args.User.UserName
|
||||
|
||||
if err := validate.Struct(body); err != nil {
|
||||
response.Status = fiber.StatusBadRequest
|
||||
|
||||
logger.Info().Msgf("invalid body: %v", err)
|
||||
} else if err := users.ChangePassword(body); err != nil {
|
||||
response.Status = fiber.StatusInternalServerError
|
||||
|
||||
logger.Error().Msgf("can't update password: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
77
client/src/app/account/page.tsx
Normal file
77
client/src/app/account/page.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
"use client";
|
||||
|
||||
import { apiCall, vaidatePassword as validatePassword } from "@/lib";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CardBody,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
Form,
|
||||
Input,
|
||||
} from "@nextui-org/react";
|
||||
import { FormEvent, useState } from "react";
|
||||
|
||||
export default function Account() {
|
||||
const [password, setPassword] = useState("");
|
||||
const errors = validatePassword(password);
|
||||
|
||||
async function changePassword(e: FormEvent<HTMLFormElement>) {
|
||||
const data = Object.fromEntries(new FormData(e.currentTarget));
|
||||
|
||||
const result = await apiCall("PATCH", "users/password", undefined, data);
|
||||
|
||||
if (result.ok) {
|
||||
setPassword("");
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="text-center text-4xl">Account</h2>
|
||||
<div>
|
||||
<Card className="max-w-md">
|
||||
<CardHeader>
|
||||
<h3 className="text-2xl">Change Password</h3>
|
||||
</CardHeader>
|
||||
|
||||
<Form
|
||||
validationBehavior="native"
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
changePassword(e);
|
||||
}}
|
||||
>
|
||||
<CardBody>
|
||||
<Input
|
||||
isRequired
|
||||
label="Password"
|
||||
name="password"
|
||||
variant="bordered"
|
||||
value={password}
|
||||
onValueChange={setPassword}
|
||||
isInvalid={password.length > 0 && errors.length > 0}
|
||||
errorMessage={
|
||||
<ul>
|
||||
{errors.map((e, ii) => (
|
||||
<li key={ii}>{e}</li>
|
||||
))}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
</CardBody>
|
||||
<CardFooter>
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
isDisabled={errors.length > 0}
|
||||
>
|
||||
Change password
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Form>
|
||||
</Card>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -80,3 +80,13 @@ export class DateFormatter {
|
||||
return this.formatter.format(dt);
|
||||
}
|
||||
}
|
||||
|
||||
export function vaidatePassword(password: string): string[] {
|
||||
const errors = [];
|
||||
|
||||
if (password.length < 1) {
|
||||
errors.push("Password must be 16 characters or more");
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user