feat: get account read
This commit is contained in:
parent
990d6d30b9
commit
0475f9cdd1
4 changed files with 185 additions and 63 deletions
|
@ -29,7 +29,7 @@ func BasicAuth(ctx *gin.Context) {
|
|||
auth := service.NewAuthService()
|
||||
username, password, ok := ctx.Request.BasicAuth()
|
||||
if !ok {
|
||||
ctx.Status(403)
|
||||
ctx.Status(401)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ func BasicAuth(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
if !ok {
|
||||
ctx.Status(403)
|
||||
ctx.Status(401)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -38,19 +38,49 @@ func authentication(group *gin.RouterGroup) {
|
|||
})
|
||||
})
|
||||
|
||||
group.GET("/read", func(ctx *gin.Context) {
|
||||
auth := service.NewAuthService()
|
||||
username, password, ok := ctx.Request.BasicAuth()
|
||||
if !ok {
|
||||
ctx.Status(401)
|
||||
return
|
||||
}
|
||||
|
||||
ok, err := auth.VerifyToken(username, password)
|
||||
if err != nil {
|
||||
ctx.JSON(500, gin.H{
|
||||
"ok": 0,
|
||||
"errno": "internal server error!",
|
||||
})
|
||||
}
|
||||
|
||||
if !ok {
|
||||
ctx.JSON(401, gin.H{
|
||||
"ok": 0,
|
||||
"errno": "unauthorized",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(200, gin.H{
|
||||
"ok": 1,
|
||||
"username": username,
|
||||
})
|
||||
})
|
||||
|
||||
group.PATCH("/update", func(ctx *gin.Context) {
|
||||
auth := service.NewAuthService()
|
||||
old := ctx.PostForm("password")
|
||||
new := ctx.PostForm("new_password")
|
||||
username, _, ok := ctx.Request.BasicAuth()
|
||||
if !ok {
|
||||
ctx.Status(403)
|
||||
ctx.Status(401)
|
||||
return
|
||||
}
|
||||
|
||||
ok, err := auth.Verify(username, old)
|
||||
if err != nil || !ok {
|
||||
ctx.Status(403)
|
||||
ctx.Status(401)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -65,14 +95,13 @@ func authentication(group *gin.RouterGroup) {
|
|||
|
||||
group.DELETE("/delete", func(ctx *gin.Context) {
|
||||
auth := service.NewAuthService()
|
||||
pass := ctx.PostForm("password")
|
||||
username, _, ok := ctx.Request.BasicAuth()
|
||||
username, password, ok := ctx.Request.BasicAuth()
|
||||
if !ok {
|
||||
ctx.Status(403)
|
||||
ctx.Status(401)
|
||||
return
|
||||
}
|
||||
|
||||
ok, err := auth.Verify(username, pass)
|
||||
ok, err := auth.VerifyToken(username, password)
|
||||
if err != nil {
|
||||
ctx.Status(500)
|
||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||
|
@ -80,7 +109,7 @@ func authentication(group *gin.RouterGroup) {
|
|||
}
|
||||
|
||||
if !ok {
|
||||
ctx.Status(403)
|
||||
ctx.Status(401)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
|
|||
import { AuthState, useAuthStore } from "../../store/auth";
|
||||
|
||||
import "./settings.scss";
|
||||
import { DynamicIcon } from "lucide-react/dynamic";
|
||||
|
||||
function Settings() {
|
||||
const auth = useAuthStore();
|
||||
|
@ -31,9 +32,9 @@ function Settings() {
|
|||
|
||||
return (
|
||||
<div className="ka-settings">
|
||||
<h2>General</h2>
|
||||
<h2 className="ka-title">General</h2>
|
||||
|
||||
<ChangePassword auth={auth} />
|
||||
<AccountSetting auth={auth} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -46,64 +47,114 @@ function SettingBox({ children }: { children: React.ReactNode }) {
|
|||
);
|
||||
}
|
||||
|
||||
function ChangePassword({ auth }: { auth: AuthState }) {
|
||||
function AccountSetting({ auth }: { auth: AuthState }) {
|
||||
const orRef = useRef<HTMLInputElement>(null);
|
||||
const pwRef = useRef<HTMLInputElement>(null);
|
||||
const ckRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
return (
|
||||
<SettingBox>
|
||||
<h4>Change Password</h4>
|
||||
<span>If you change your password, you will need to log in again.</span>
|
||||
<h4>Account Setting</h4>
|
||||
<span>You can modify your account. This is a sensitive option. Please reconsider if you want to change your account information.</span>
|
||||
<hr className="line" />
|
||||
<form className="box-col" id="pw-change">
|
||||
<input type="password" ref={orRef} placeholder="Password" required />
|
||||
<input type="password" ref={pwRef} placeholder="New Password" required />
|
||||
<input type="password" ref={ckRef} placeholder="Check Password" required />
|
||||
<div className="box-row">
|
||||
<div className="box-col">
|
||||
<h6>Change Password</h6>
|
||||
<span>If you change your password, you will need to log in again.</span>
|
||||
</div>
|
||||
|
||||
<button type="submit" className="danger" onClick={ev => {
|
||||
ev.preventDefault();
|
||||
const origin = orRef.current?.value;
|
||||
const password = pwRef.current?.value;
|
||||
const check = ckRef.current?.value;
|
||||
<form className="box-col" id="pw-change">
|
||||
<PasswordInput placeholder="Password" ref={orRef} />
|
||||
<PasswordInput placeholder="New Password" ref={pwRef} />
|
||||
<PasswordInput placeholder="Check Password" ref={ckRef} />
|
||||
|
||||
if (!origin || !password || !check) {
|
||||
return;
|
||||
}
|
||||
<button type="submit" className="danger" onClick={ev => {
|
||||
ev.preventDefault();
|
||||
const origin = orRef.current?.value;
|
||||
const password = pwRef.current?.value;
|
||||
const check = ckRef.current?.value;
|
||||
|
||||
if (origin === "" || password === "" || check === "") {
|
||||
alert("You must need to write all inputs");
|
||||
return;
|
||||
}
|
||||
|
||||
if (password !== check) {
|
||||
alert("New password is not matches!");
|
||||
return;
|
||||
}
|
||||
|
||||
const form = new URLSearchParams();
|
||||
form.append("password", origin);
|
||||
form.append("new_password", password);
|
||||
|
||||
fetch("/api/auth/update", {
|
||||
body: form,
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Authorization": `Basic ${auth.token}`
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.status !== 200) {
|
||||
alert(`${res.status} ${res.statusText}`);
|
||||
if (!origin || !password || !check) {
|
||||
return;
|
||||
}
|
||||
|
||||
alert("password changed!");
|
||||
document.location.href = "/logout";
|
||||
});
|
||||
}}>Change Password</button>
|
||||
</form>
|
||||
if (origin === "" || password === "" || check === "") {
|
||||
alert("You must need to write all inputs");
|
||||
return;
|
||||
}
|
||||
|
||||
if (password !== check) {
|
||||
alert("New password is not matches!");
|
||||
return;
|
||||
}
|
||||
|
||||
const form = new URLSearchParams();
|
||||
form.append("password", origin);
|
||||
form.append("new_password", password);
|
||||
|
||||
fetch("/api/auth/update", {
|
||||
body: form,
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Authorization": `Basic ${auth.token}`
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.status !== 200) {
|
||||
alert(`${res.status} ${res.statusText}`);
|
||||
return;
|
||||
}
|
||||
|
||||
alert("password changed!");
|
||||
document.location.href = "/logout";
|
||||
});
|
||||
}}>Change Password</button>
|
||||
</form>
|
||||
</div>
|
||||
<div className="box-row">
|
||||
<div className="box-col">
|
||||
<h6>Delete Account</h6>
|
||||
<span>You can delete account. This action is irreversible. Please proceed with caution.</span>
|
||||
</div>
|
||||
|
||||
<form className="box-col">
|
||||
<button type="submit" className="danger" onClick={ev => {
|
||||
ev.preventDefault();
|
||||
|
||||
fetch("/api/auth/delete", {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Authorization": `Basic ${auth.token}`
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.status !== 200) {
|
||||
alert(`${res.status} ${res.statusText}`);
|
||||
return;
|
||||
}
|
||||
|
||||
alert("Your account has been deactivated and removed");
|
||||
document.location.href = "/logout";
|
||||
});
|
||||
}}>Remove Account</button>
|
||||
</form>
|
||||
</div>
|
||||
</SettingBox>
|
||||
);
|
||||
}
|
||||
|
||||
function PasswordInput({ placeholder, ref }: { placeholder: string; ref: React.RefObject<HTMLInputElement | null> }) {
|
||||
const [show, setShow] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="input-pass">
|
||||
<input type={!show ? "password" : "text"} ref={ref} placeholder={placeholder} required />
|
||||
<a className="pw-btn" onClick={ev => {
|
||||
ev.preventDefault();
|
||||
setShow(!show);
|
||||
}}>
|
||||
<DynamicIcon name={show ? "eye-off" : "eye"} size={17} />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Settings;
|
||||
|
|
|
@ -3,7 +3,13 @@
|
|||
height: 100%;
|
||||
display: flex;
|
||||
margin: 1rem 0;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.ka-title {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.setting-box {
|
||||
width: 100%;
|
||||
|
@ -18,24 +24,60 @@
|
|||
.box-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 0 2rem;
|
||||
margin: 1rem 0;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
@media (max-width: 640px) {
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.box-col {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
min-width: 300px;
|
||||
margin: 1rem 0;
|
||||
min-width: 350px;
|
||||
flex-direction: column;
|
||||
|
||||
@media (max-width: 640px) {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#pw-change {
|
||||
input {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pw-change {
|
||||
.input-pass {
|
||||
height: 40;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
border-radius: 25px 0 0 25px;
|
||||
}
|
||||
|
||||
.pw-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 0 25px 25px 0;
|
||||
background-color: var(--nav-color);
|
||||
}
|
||||
|
||||
button {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue