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()
|
auth := service.NewAuthService()
|
||||||
username, password, ok := ctx.Request.BasicAuth()
|
username, password, ok := ctx.Request.BasicAuth()
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Status(403)
|
ctx.Status(401)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ func BasicAuth(ctx *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Status(403)
|
ctx.Status(401)
|
||||||
return
|
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) {
|
group.PATCH("/update", func(ctx *gin.Context) {
|
||||||
auth := service.NewAuthService()
|
auth := service.NewAuthService()
|
||||||
old := ctx.PostForm("password")
|
old := ctx.PostForm("password")
|
||||||
new := ctx.PostForm("new_password")
|
new := ctx.PostForm("new_password")
|
||||||
username, _, ok := ctx.Request.BasicAuth()
|
username, _, ok := ctx.Request.BasicAuth()
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Status(403)
|
ctx.Status(401)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := auth.Verify(username, old)
|
ok, err := auth.Verify(username, old)
|
||||||
if err != nil || !ok {
|
if err != nil || !ok {
|
||||||
ctx.Status(403)
|
ctx.Status(401)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,14 +95,13 @@ func authentication(group *gin.RouterGroup) {
|
||||||
|
|
||||||
group.DELETE("/delete", func(ctx *gin.Context) {
|
group.DELETE("/delete", func(ctx *gin.Context) {
|
||||||
auth := service.NewAuthService()
|
auth := service.NewAuthService()
|
||||||
pass := ctx.PostForm("password")
|
username, password, ok := ctx.Request.BasicAuth()
|
||||||
username, _, ok := ctx.Request.BasicAuth()
|
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Status(403)
|
ctx.Status(401)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := auth.Verify(username, pass)
|
ok, err := auth.VerifyToken(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Status(500)
|
ctx.Status(500)
|
||||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||||
|
@ -80,7 +109,7 @@ func authentication(group *gin.RouterGroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Status(403)
|
ctx.Status(401)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
|
||||||
import { AuthState, useAuthStore } from "../../store/auth";
|
import { AuthState, useAuthStore } from "../../store/auth";
|
||||||
|
|
||||||
import "./settings.scss";
|
import "./settings.scss";
|
||||||
|
import { DynamicIcon } from "lucide-react/dynamic";
|
||||||
|
|
||||||
function Settings() {
|
function Settings() {
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
|
@ -31,9 +32,9 @@ function Settings() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ka-settings">
|
<div className="ka-settings">
|
||||||
<h2>General</h2>
|
<h2 className="ka-title">General</h2>
|
||||||
|
|
||||||
<ChangePassword auth={auth} />
|
<AccountSetting auth={auth} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -46,20 +47,26 @@ function SettingBox({ children }: { children: React.ReactNode }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ChangePassword({ auth }: { auth: AuthState }) {
|
function AccountSetting({ auth }: { auth: AuthState }) {
|
||||||
const orRef = useRef<HTMLInputElement>(null);
|
const orRef = useRef<HTMLInputElement>(null);
|
||||||
const pwRef = useRef<HTMLInputElement>(null);
|
const pwRef = useRef<HTMLInputElement>(null);
|
||||||
const ckRef = useRef<HTMLInputElement>(null);
|
const ckRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingBox>
|
<SettingBox>
|
||||||
<h4>Change Password</h4>
|
<h4>Account Setting</h4>
|
||||||
<span>If you change your password, you will need to log in again.</span>
|
<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" />
|
<hr className="line" />
|
||||||
|
<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>
|
||||||
|
|
||||||
<form className="box-col" id="pw-change">
|
<form className="box-col" id="pw-change">
|
||||||
<input type="password" ref={orRef} placeholder="Password" required />
|
<PasswordInput placeholder="Password" ref={orRef} />
|
||||||
<input type="password" ref={pwRef} placeholder="New Password" required />
|
<PasswordInput placeholder="New Password" ref={pwRef} />
|
||||||
<input type="password" ref={ckRef} placeholder="Check Password" required />
|
<PasswordInput placeholder="Check Password" ref={ckRef} />
|
||||||
|
|
||||||
<button type="submit" className="danger" onClick={ev => {
|
<button type="submit" className="danger" onClick={ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
@ -102,8 +109,52 @@ function ChangePassword({ auth }: { auth: AuthState }) {
|
||||||
});
|
});
|
||||||
}}>Change Password</button>
|
}}>Change Password</button>
|
||||||
</form>
|
</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>
|
</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;
|
export default Settings;
|
||||||
|
|
|
@ -3,7 +3,13 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.ka-title {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.setting-box {
|
.setting-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -18,24 +24,60 @@
|
||||||
.box-row {
|
.box-row {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 0 2rem;
|
margin: 1rem 0;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
margin: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-col {
|
.box-col {
|
||||||
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: 300px;
|
margin: 1rem 0;
|
||||||
|
min-width: 350px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.line {
|
.line {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pw-change {
|
#pw-change {
|
||||||
input {
|
.input-pass {
|
||||||
|
height: 40;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
margin-bottom: 10px;
|
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