mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 05:29:51 +00:00
Add password modification.
This commit is contained in:
parent
cf0f82793a
commit
c3665cb1bb
@ -18,6 +18,7 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
|
||||
- [安装](#安装)
|
||||
- [二进制文件](#二进制文件)
|
||||
- [Docker 安装](#docker-安装)
|
||||
- [默认账号:](#默认账号)
|
||||
- [概念](#概念)
|
||||
- [域名](#域名)
|
||||
- [dns 服务商授权信息](#dns-服务商授权信息)
|
||||
@ -37,19 +38,18 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
|
||||
./certimate serve
|
||||
```
|
||||
|
||||
然后在浏览器中访问 http://127.0.0.1:8090 即可访问 Certimate 管理页面。
|
||||
|
||||
### Docker 安装
|
||||
|
||||
```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
|
||||
用户名:admin@certimate.fun
|
||||
|
@ -30,7 +30,7 @@ func deploy(ctx context.Context, record *models.Record) error {
|
||||
currRecord, err := app.GetApp().Dao().FindRecordById("domains", record.Id)
|
||||
history := NewHistory(record)
|
||||
defer history.commit()
|
||||
|
||||
da
|
||||
// ############1.检查域名配置
|
||||
history.record(checkPhase, "开始检查", nil)
|
||||
|
||||
|
@ -41,6 +41,10 @@ export default function Dashboard() {
|
||||
getPb().authStore.clear();
|
||||
navigate("/login");
|
||||
};
|
||||
|
||||
const handleSettingClick = () => {
|
||||
navigate("/setting/password");
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<ConfigProvider>
|
||||
@ -160,11 +164,15 @@ export default function Dashboard() {
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
||||
<DropdownMenuLabel>账户</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<DropdownMenuItem onClick={handleSettingClick}>
|
||||
设置
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem onClick={handleLogoutClick}>
|
||||
Logout
|
||||
退出
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
21
ui/src/pages/SettingLayout.tsx
Normal file
21
ui/src/pages/SettingLayout.tsx
Normal 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;
|
146
ui/src/pages/setting/Password.tsx
Normal file
146
ui/src/pages/setting/Password.tsx
Normal 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;
|
@ -7,6 +7,8 @@ import Access from "./pages/access/Access";
|
||||
import History from "./pages/history/History";
|
||||
import Login from "./pages/login/Login";
|
||||
import LoginLayout from "./pages/LoginLayout";
|
||||
import Password from "./pages/setting/Password";
|
||||
import SettingLayout from "./pages/SettingLayout";
|
||||
|
||||
export const router = createHashRouter([
|
||||
{
|
||||
@ -29,6 +31,16 @@ export const router = createHashRouter([
|
||||
path: "/history",
|
||||
element: <History />,
|
||||
},
|
||||
{
|
||||
path: "/setting",
|
||||
element: <SettingLayout />,
|
||||
children: [
|
||||
{
|
||||
path: "/setting/password",
|
||||
element: <Password />,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user