Have got logout working
This commit is contained in:
parent
01c6e9de87
commit
b7e0269e9d
9
assets/js/controllers/logout.js
Normal file
9
assets/js/controllers/logout.js
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
export default class LogoutController extends Controller {
|
||||||
|
async logout(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
await fetch(`/logout`, { method: 'POST' });
|
||||||
|
window.location.href = '/login';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,8 +3,10 @@ import { Application } from "@hotwired/stimulus";
|
||||||
import ToastController from "./controllers/toast";
|
import ToastController from "./controllers/toast";
|
||||||
import PostlistController from "./controllers/postlist";
|
import PostlistController from "./controllers/postlist";
|
||||||
import PosteditController from "./controllers/postedit";
|
import PosteditController from "./controllers/postedit";
|
||||||
|
import LogoutController from "./controllers/logout";
|
||||||
|
|
||||||
window.Stimulus = Application.start()
|
window.Stimulus = Application.start()
|
||||||
Stimulus.register("toast", ToastController);
|
Stimulus.register("toast", ToastController);
|
||||||
Stimulus.register("postlist", PostlistController);
|
Stimulus.register("postlist", PostlistController);
|
||||||
Stimulus.register("postedit", PosteditController);
|
Stimulus.register("postedit", PosteditController);
|
||||||
|
Stimulus.register("logout", LogoutController);
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,21 @@ func (lh *LoginHandler) Login(c fiber.Ctx) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lh *LoginHandler) Logout(c fiber.Ctx) error {
|
||||||
|
sess := session.FromContext(c)
|
||||||
|
sess.Destroy()
|
||||||
|
return c.Redirect().To("/login")
|
||||||
|
}
|
||||||
|
|
||||||
func (lh *LoginHandler) DoLogin(c fiber.Ctx) error {
|
func (lh *LoginHandler) DoLogin(c fiber.Ctx) error {
|
||||||
var req struct {
|
var req struct {
|
||||||
Username string `form:"username"`
|
Username string `form:"username"`
|
||||||
Password string `form:"password"`
|
Password string `form:"password"`
|
||||||
LoginChallenge string `form:"_login_challenge"`
|
LoginChallenge string `form:"_login_challenge"`
|
||||||
}
|
}
|
||||||
|
if err := c.Bind().Body(&req); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).SendString("Failed to parse request body")
|
||||||
|
}
|
||||||
|
|
||||||
if req.Username == "" || req.Password == "" {
|
if req.Username == "" || req.Password == "" {
|
||||||
return c.Status(fiber.StatusBadRequest).SendString("Username and password are required")
|
return c.Status(fiber.StatusBadRequest).SendString("Username and password are required")
|
||||||
|
|
@ -43,7 +52,7 @@ func (lh *LoginHandler) DoLogin(c fiber.Ctx) error {
|
||||||
sess := session.FromContext(c)
|
sess := session.FromContext(c)
|
||||||
|
|
||||||
challenge, _ := sess.Get("_login_challenge").(string)
|
challenge, _ := sess.Get("_login_challenge").(string)
|
||||||
if challenge == req.LoginChallenge {
|
if challenge != req.LoginChallenge {
|
||||||
return c.Redirect().To("/login")
|
return c.Redirect().To("/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
21
main.go
21
main.go
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"flag"
|
||||||
"html"
|
"html"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
|
|
@ -29,6 +30,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
flagUser := flag.String("user", "", "select user to perform operation on")
|
||||||
|
flagPasswd := flag.String("passwd", "", "change password for user")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
cfg, err := config.LoadConfig()
|
cfg, err := config.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
@ -43,9 +48,20 @@ func main() {
|
||||||
authSvc := auth.New(dbp)
|
authSvc := auth.New(dbp)
|
||||||
publisherSvc := publisher.New(dbp)
|
publisherSvc := publisher.New(dbp)
|
||||||
publisherQueue := publisher.NewQueue(publisherSvc)
|
publisherQueue := publisher.NewQueue(publisherSvc)
|
||||||
publisherQueue.Start(context.Background())
|
|
||||||
postService := posts.New(dbp, publisherQueue)
|
postService := posts.New(dbp, publisherQueue)
|
||||||
|
|
||||||
|
// CLI tools
|
||||||
|
if *flagPasswd != "" && *flagUser != "" {
|
||||||
|
user, err := authSvc.SetPassword(context.Background(), *flagUser, *flagPasswd)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Printf("Password changed for user %s\n", user.Username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
publisherQueue.Start(context.Background())
|
||||||
|
|
||||||
fiberTemplate := fiber_html.New("./views", ".html")
|
fiberTemplate := fiber_html.New("./views", ".html")
|
||||||
fiberTemplate.Funcmap["sub"] = func(x, y int) int { return x - y }
|
fiberTemplate.Funcmap["sub"] = func(x, y int) int { return x - y }
|
||||||
fiberTemplate.Funcmap["markdown"] = func() func(s string) template.HTML {
|
fiberTemplate.Funcmap["markdown"] = func() func(s string) template.HTML {
|
||||||
|
|
@ -108,7 +124,8 @@ func main() {
|
||||||
ph := handlers.PostsHandler{PostService: postService}
|
ph := handlers.PostsHandler{PostService: postService}
|
||||||
|
|
||||||
app.Get("/login", lh.Login)
|
app.Get("/login", lh.Login)
|
||||||
app.Post("/login", lh.Login)
|
app.Post("/login", lh.DoLogin)
|
||||||
|
app.Post("/logout", lh.Logout)
|
||||||
|
|
||||||
siteGroup := app.Group("/sites/:siteID", middleware.AuthUser(authSvc), middleware.RequiresSite(dbp))
|
siteGroup := app.Group("/sites/:siteID", middleware.AuthUser(authSvc), middleware.RequiresSite(dbp))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,13 @@ func (s *Service) Login(ctx context.Context, username, password string) (models.
|
||||||
func (s *Service) GetUser(ctx context.Context, userID int64) (models.User, error) {
|
func (s *Service) GetUser(ctx context.Context, userID int64) (models.User, error) {
|
||||||
return s.db.SelectUserByID(ctx, userID)
|
return s.db.SelectUserByID(ctx, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) SetPassword(ctx context.Context, username, password string) (models.User, error) {
|
||||||
|
user, err := s.db.SelectUserByUsername(ctx, username)
|
||||||
|
if err != nil {
|
||||||
|
return models.User{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
user.SetPassword(password)
|
||||||
|
return user, s.db.SaveUser(ctx, &user)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,17 @@
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
|
<div class="nav-item dropdown">
|
||||||
<button class="btn btn-outline-success" type="submit">Search</button>
|
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
{{ .user.Username }}
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-end">
|
||||||
|
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||||
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
<li><a class="dropdown-item" href="#" data-controller="logout" data-action="logout#logout">Logout</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,15 @@
|
||||||
<div class="text-center mb-3">
|
<div class="text-center mb-3">
|
||||||
<h3>Weiro Login</h3>
|
<h3>Weiro Login</h3>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="_login_challenge" value="{{ .challenge }}">
|
|
||||||
<form action="/login" method="post">
|
<form action="/login" method="post">
|
||||||
|
<input type="hidden" name="_login_challenge" value="{{ .challenge }}">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label for="login_username" class="form-label">Login</label>
|
<label for="username" class="form-label">Login</label>
|
||||||
<input type="email" class="form-control" id="login_username">
|
<input type="text" class="form-control" name="username" id="username">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="login_password" class="form-label">Password</label>
|
<label for="password" class="form-label">Password</label>
|
||||||
<input type="password" class="form-control" id="login_password">
|
<input type="password" class="form-control" name="password" id="password">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3 text-end">
|
<div class="mb-3 text-end">
|
||||||
<input type="submit" class="btn btn-primary" value="Login">
|
<input type="submit" class="btn btn-primary" value="Login">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue