diff --git a/internal/routes/auth.go b/internal/routes/auth.go new file mode 100644 index 0000000..269c46d --- /dev/null +++ b/internal/routes/auth.go @@ -0,0 +1,88 @@ +package routes + +import ( + "fmt" + "os" + + "git.wh64.net/devproje/kuma-archive/internal/service" + "github.com/gin-gonic/gin" +) + +func authentication(group *gin.RouterGroup) { + group.POST("/login", func(ctx *gin.Context) { + auth := service.NewAuthService() + username := ctx.PostForm("username") + password := ctx.PostForm("password") + + acc, err := auth.Read(username) + if err != nil { + ctx.JSON(401, gin.H{ + "ok": 0, + "errno": "username or password not invalid", + }) + return + } + + ok, err := auth.Verify(username, password) + if err != nil || !ok { + ctx.JSON(401, gin.H{ + "ok": 0, + "errno": "username or password not invalid", + }) + return + } + + ctx.JSON(200, gin.H{ + "ok": 1, + "token": auth.Token(acc.Username, acc.Password), + }) + }) + + 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) + return + } + + ok, err := auth.Verify(username, old) + if err != nil || !ok { + ctx.Status(403) + return + } + + if err = auth.Update(username, new); err != nil { + ctx.Status(500) + _, _ = fmt.Fprintln(os.Stderr, err) + return + } + + ctx.Status(200) + }) + + group.GET("/check", func(ctx *gin.Context) { + auth := service.NewAuthService() + username, password, ok := ctx.Request.BasicAuth() + if !ok { + ctx.Status(401) + return + } + + validate, err := auth.VerifyToken(username, password) + if err != nil { + ctx.Status(500) + fmt.Fprintln(os.Stderr, err) + return + } + + if !validate { + ctx.Status(401) + return + } + + ctx.Status(200) + }) +} diff --git a/internal/routes/mod.go b/internal/routes/mod.go index e4bbf79..8faee9f 100644 --- a/internal/routes/mod.go +++ b/internal/routes/mod.go @@ -89,36 +89,7 @@ func New(app *gin.Engine, version *service.Version, apiOnly bool) { }) auth := api.Group("/auth") - { - auth.POST("/login", func(ctx *gin.Context) { - auth := service.NewAuthService() - username := ctx.PostForm("username") - password := ctx.PostForm("password") - - acc, err := auth.Read(username) - if err != nil { - ctx.JSON(401, gin.H{ - "ok": 0, - "errno": "username or password not invalid", - }) - return - } - - ok, err := auth.Verify(username, password) - if err != nil || !ok { - ctx.JSON(401, gin.H{ - "ok": 0, - "errno": "username or password not invalid", - }) - return - } - - ctx.JSON(200, gin.H{ - "ok": 1, - "token": auth.Token(acc.Username, acc.Password), - }) - }) - } + authentication(auth) api.GET("/version", func(ctx *gin.Context) { ctx.String(200, "%s", version.String()) @@ -139,5 +110,4 @@ func New(app *gin.Engine, version *service.Version, apiOnly bool) { app.GET("favicon.ico", func(ctx *gin.Context) { ctx.File("/web/assets/favicon.ico") }) - } diff --git a/internal/service/auth.go b/internal/service/auth.go index f53af92..6ea4b33 100644 --- a/internal/service/auth.go +++ b/internal/service/auth.go @@ -146,6 +146,19 @@ func (s *AuthService) Verify(username, password string) (bool, error) { return false, nil } +func (s *AuthService) VerifyToken(username, encryptPw string) (bool, error) { + account, err := s.Read(username) + if err != nil { + return false, err + } + + if encryptPw == account.Password { + return true, nil + } + + return false, nil +} + func (s *AuthService) Token(username, password string) string { raw := fmt.Sprintf("%s:%s", username, password) return base64.StdEncoding.EncodeToString([]byte(raw)) diff --git a/src/App.tsx b/src/App.tsx index 036bddf..7d0c0f7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,6 +12,7 @@ import NotFound from "./components/notfound"; import Login from "./components/login"; import { useAuthStore } from "./store/auth"; import Logout from "./components/logout"; +import Settings from "./components/settings"; function App() { return ( @@ -19,6 +20,7 @@ function App() { } />} /> } /> + } />} /> } />} /> @@ -67,6 +69,18 @@ function View() { function Header() { const auth = useAuthStore(); + const [isAuth, setAuth] = useState(false); + + useEffect(() => { + if (auth.token === null) { + return; + } + + auth.checkToken(auth.token).then((ok) => { + if (ok) + setAuth(true); + }); + }, [auth, isAuth]); return (