Add password modification.

This commit is contained in:
yoan 2024-08-28 14:36:11 +08:00
parent cf0f82793a
commit c3665cb1bb
6 changed files with 194 additions and 7 deletions

View File

@ -18,6 +18,7 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
- [安装](#安装) - [安装](#安装)
- [二进制文件](#二进制文件) - [二进制文件](#二进制文件)
- [Docker 安装](#docker-安装) - [Docker 安装](#docker-安装)
- [默认账号:](#默认账号)
- [概念](#概念) - [概念](#概念)
- [域名](#域名) - [域名](#域名)
- [dns 服务商授权信息](#dns-服务商授权信息) - [dns 服务商授权信息](#dns-服务商授权信息)
@ -37,19 +38,18 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
./certimate serve ./certimate serve
``` ```
然后在浏览器中访问 http://127.0.0.1:8090 即可访问 Certimate 管理页面。
### Docker 安装 ### Docker 安装
```bash ```bash
git clone git@github.com:usual2970/certimate.git && cd certimate/docker && docker-compose up -d git clone git@github.com:usual2970/certimate.git && cd certimate/docker && docker compose up -d
``` ```
配置 然后在浏览器中访问 http://127.0.0.1:8090 即可访问 Certimate 管理页面。
默认账号: ### 默认账号:
```bash ```bash
用户名admin@certimate.fun 用户名admin@certimate.fun

View File

@ -30,7 +30,7 @@ func deploy(ctx context.Context, record *models.Record) error {
currRecord, err := app.GetApp().Dao().FindRecordById("domains", record.Id) currRecord, err := app.GetApp().Dao().FindRecordById("domains", record.Id)
history := NewHistory(record) history := NewHistory(record)
defer history.commit() defer history.commit()
da
// ############1.检查域名配置 // ############1.检查域名配置
history.record(checkPhase, "开始检查", nil) history.record(checkPhase, "开始检查", nil)

View File

@ -41,6 +41,10 @@ export default function Dashboard() {
getPb().authStore.clear(); getPb().authStore.clear();
navigate("/login"); navigate("/login");
}; };
const handleSettingClick = () => {
navigate("/setting/password");
};
return ( return (
<> <>
<ConfigProvider> <ConfigProvider>
@ -160,11 +164,15 @@ export default function Dashboard() {
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="end"> <DropdownMenuContent align="end">
<DropdownMenuLabel>My Account</DropdownMenuLabel> <DropdownMenuLabel></DropdownMenuLabel>
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuItem onClick={handleSettingClick}>
</DropdownMenuItem>
<DropdownMenuItem onClick={handleLogoutClick}> <DropdownMenuItem onClick={handleLogoutClick}>
Logout 退
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>

View File

@ -0,0 +1,21 @@
import { Toaster } from "@/components/ui/toaster";
import { Outlet } from "react-router-dom";
const SettingLayout = () => {
return (
<div>
<Toaster />
<div className="text-muted-foreground"></div>
<div className="w-full sm:w-[35em] mt-10 flex flex-col p-3">
{/* <div className="text-muted-foreground">
<span className="transition-all text-sm bg-gray-400 px-3 py-1 rounded-sm text-white cursor-pointer">
</span>
</div> */}
<Outlet />
</div>
</div>
);
};
export default SettingLayout;

View File

@ -0,0 +1,146 @@
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { useToast } from "@/components/ui/use-toast";
import { getErrMessage } from "@/lib/error";
import { getPb } from "@/repository/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { z } from "zod";
const formSchema = z
.object({
oldPassword: z.string().min(10, {
message: "密码至少10个字符",
}),
newPassword: z.string().min(10, {
message: "密码至少10个字符",
}),
confirmPassword: z.string().min(10, {
message: "密码至少10个字符",
}),
})
.refine((data) => data.newPassword === data.confirmPassword, {
message: "两次密码不一致",
path: ["confirmPassword"],
});
const Password = () => {
const { toast } = useToast();
const navigate = useNavigate();
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
oldPassword: "",
newPassword: "",
confirmPassword: "",
},
});
const onSubmit = async (values: z.infer<typeof formSchema>) => {
try {
await getPb().admins.authWithPassword(
getPb().authStore.model?.email,
values.oldPassword
);
} catch (e) {
const message = getErrMessage(e);
form.setError("oldPassword", { message });
}
try {
await getPb().admins.update(getPb().authStore.model?.id, {
password: values.newPassword,
passwordConfirm: values.confirmPassword,
});
getPb().authStore.clear();
toast({
title: "修改密码成功",
description: "请重新登录",
});
setTimeout(() => {
navigate("/login");
}, 500);
} catch (e) {
const message = getErrMessage(e);
toast({
title: "修改密码失败",
description: message,
variant: "destructive",
});
}
};
return (
<>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="oldPassword"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormControl>
<Input placeholder="当前密码" {...field} type="password" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="newPassword"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormControl>
<Input placeholder="newPassword" {...field} type="password" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="confirmPassword"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormControl>
<Input
placeholder="confirmPassword"
{...field}
type="password"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit"></Button>
</div>
</form>
</Form>
</>
);
};
export default Password;

View File

@ -7,6 +7,8 @@ import Access from "./pages/access/Access";
import History from "./pages/history/History"; import History from "./pages/history/History";
import Login from "./pages/login/Login"; import Login from "./pages/login/Login";
import LoginLayout from "./pages/LoginLayout"; import LoginLayout from "./pages/LoginLayout";
import Password from "./pages/setting/Password";
import SettingLayout from "./pages/SettingLayout";
export const router = createHashRouter([ export const router = createHashRouter([
{ {
@ -29,6 +31,16 @@ export const router = createHashRouter([
path: "/history", path: "/history",
element: <History />, element: <History />,
}, },
{
path: "/setting",
element: <SettingLayout />,
children: [
{
path: "/setting/password",
element: <Password />,
},
],
},
], ],
}, },
{ {