diff --git a/internal/webserver/controller.go b/internal/webserver/controller.go
index 22392702..5a404ef5 100644
--- a/internal/webserver/controller.go
+++ b/internal/webserver/controller.go
@@ -1,12 +1,6 @@
package webserver
import (
- "errors"
- "fmt"
- "log"
-
- "github.com/gofiber/fiber/v2"
- jwtware "github.com/gofiber/jwt/v3"
"github.com/spf13/afero"
"github.com/svera/coreander/v3/internal/index"
"github.com/svera/coreander/v3/internal/metadata"
@@ -14,21 +8,15 @@ import (
"github.com/svera/coreander/v3/internal/webserver/controller/document"
"github.com/svera/coreander/v3/internal/webserver/controller/highlight"
"github.com/svera/coreander/v3/internal/webserver/controller/user"
- "github.com/svera/coreander/v3/internal/webserver/infrastructure"
- "github.com/svera/coreander/v3/internal/webserver/jwtclaimsreader"
"github.com/svera/coreander/v3/internal/webserver/model"
"gorm.io/gorm"
)
type Controllers struct {
- Auth *auth.Controller
- Users *user.Controller
- Highlights *highlight.Controller
- Documents *document.Controller
- AllowIfNotLoggedInMiddleware func(c *fiber.Ctx) error
- AlwaysRequireAuthenticationMiddleware func(c *fiber.Ctx) error
- ConfigurableAuthenticationMiddleware func(c *fiber.Ctx) error
- ErrorHandler func(c *fiber.Ctx, err error) error
+ Auth *auth.Controller
+ Users *user.Controller
+ Highlights *highlight.Controller
+ Documents *document.Controller
}
func SetupControllers(cfg Config, db *gorm.DB, metadataReaders map[string]metadata.Reader, idx *index.BleveIndexer, sender Sender, appFs afero.Fs) Controllers {
@@ -58,99 +46,10 @@ func SetupControllers(cfg Config, db *gorm.DB, metadataReaders map[string]metada
UploadDocumentMaxSize: cfg.UploadDocumentMaxSize,
}
- authController := auth.NewController(usersRepository, sender, authCfg, printers)
- usersController := user.NewController(usersRepository, usersCfg)
- highlightsController := highlight.NewController(highlightsRepository, usersRepository, sender, cfg.WordsPerMinute, idx)
- documentsController := document.NewController(highlightsRepository, sender, idx, metadataReaders, appFs, documentsCfg)
-
- emailSendingConfigured := true
- if _, ok := sender.(*infrastructure.NoEmail); ok {
- emailSendingConfigured = false
- }
-
- supportedLanguages := getSupportedLanguages()
-
- forbidden := func(c *fiber.Ctx) error {
- return c.Status(fiber.StatusForbidden).Render("auth/login", fiber.Map{
- "Lang": chooseBestLanguage(c, supportedLanguages),
- "Title": "Login",
- "Version": c.App().Config().AppName,
- "EmailSendingConfigured": emailSendingConfigured,
- "SupportedLanguages": supportedLanguages,
- }, "layout")
- }
-
return Controllers{
- Auth: authController,
- Users: usersController,
- Highlights: highlightsController,
- Documents: documentsController,
- AllowIfNotLoggedInMiddleware: jwtware.New(jwtware.Config{
- SigningKey: cfg.JwtSecret,
- SigningMethod: "HS256",
- TokenLookup: "cookie:coreander",
- SuccessHandler: func(c *fiber.Ctx) error {
- return fiber.ErrForbidden
- },
- ErrorHandler: func(c *fiber.Ctx, err error) error {
- return c.Next()
- },
- }),
- AlwaysRequireAuthenticationMiddleware: jwtware.New(jwtware.Config{
- SigningKey: cfg.JwtSecret,
- SigningMethod: "HS256",
- TokenLookup: "cookie:coreander",
- SuccessHandler: func(c *fiber.Ctx) error {
- c.Locals("Session", jwtclaimsreader.SessionData(c))
- return c.Next()
- },
- ErrorHandler: func(c *fiber.Ctx, err error) error {
- return forbidden(c)
- },
- }),
- ConfigurableAuthenticationMiddleware: jwtware.New(jwtware.Config{
- SigningKey: cfg.JwtSecret,
- SigningMethod: "HS256",
- TokenLookup: "cookie:coreander",
- SuccessHandler: func(c *fiber.Ctx) error {
- c.Locals("Session", jwtclaimsreader.SessionData(c))
- return c.Next()
- },
- ErrorHandler: func(c *fiber.Ctx, err error) error {
- err = c.Next()
- if cfg.RequireAuth {
- return forbidden(c)
- }
- return err
- },
- }),
- ErrorHandler: func(c *fiber.Ctx, err error) error {
- // Status code defaults to 500
- code := fiber.StatusInternalServerError
- // Retrieve the custom status code if it's a *fiber.Error
- var e *fiber.Error
- if errors.As(err, &e) {
- code = e.Code
- }
-
- // Send custom error page
- err = c.Status(code).Render(
- fmt.Sprintf("errors/%d", code),
- fiber.Map{
- "Lang": chooseBestLanguage(c, supportedLanguages),
- "Title": "Coreander",
- "Session": jwtclaimsreader.SessionData(c),
- "Version": c.App().Config().AppName,
- },
- "layout")
-
- if err != nil {
- log.Println(err)
- // In case the Render fails
- return c.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
- }
-
- return nil
- },
+ Auth: auth.NewController(usersRepository, sender, authCfg, printers),
+ Users: user.NewController(usersRepository, usersCfg),
+ Highlights: highlight.NewController(highlightsRepository, usersRepository, sender, cfg.WordsPerMinute, idx),
+ Documents: document.NewController(highlightsRepository, sender, idx, metadataReaders, appFs, documentsCfg),
}
}
diff --git a/internal/webserver/controller/auth/edit-password.go b/internal/webserver/controller/auth/edit-password.go
index d7a68097..6913c396 100644
--- a/internal/webserver/controller/auth/edit-password.go
+++ b/internal/webserver/controller/auth/edit-password.go
@@ -3,7 +3,7 @@ package auth
import "github.com/gofiber/fiber/v2"
func (a *Controller) EditPassword(c *fiber.Ctx) error {
- if _, err := a.validateRecoveryAccess(c, c.Query("id")); err != nil {
+ if _, err := a.validateRecoveryAccess(c.Query("id")); err != nil {
return err
}
diff --git a/internal/webserver/controller/auth/login.go b/internal/webserver/controller/auth/login.go
index ccbff48e..1eb1ad66 100644
--- a/internal/webserver/controller/auth/login.go
+++ b/internal/webserver/controller/auth/login.go
@@ -5,16 +5,13 @@ import (
"strings"
"github.com/gofiber/fiber/v2"
- "github.com/svera/coreander/v3/internal/webserver/controller"
"github.com/svera/coreander/v3/internal/webserver/infrastructure"
)
func (a *Controller) Login(c *fiber.Ctx) error {
resetPassword := fmt.Sprintf(
- "%s://%s%s/%s/reset-password",
- c.Protocol(),
- a.config.Hostname,
- controller.UrlPort(c.Protocol(), a.config.Port),
+ "%s/%s/reset-password",
+ c.Locals("fqdn").(string),
c.Params("lang"),
)
diff --git a/internal/webserver/controller/auth/request.go b/internal/webserver/controller/auth/request.go
index b8661a1b..b8dd9e96 100644
--- a/internal/webserver/controller/auth/request.go
+++ b/internal/webserver/controller/auth/request.go
@@ -7,7 +7,6 @@ import (
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
- "github.com/svera/coreander/v3/internal/webserver/controller"
"github.com/svera/coreander/v3/internal/webserver/infrastructure"
)
@@ -31,10 +30,8 @@ func (a *Controller) Request(c *fiber.Ctx) error {
}
recoveryLink := fmt.Sprintf(
- "%s://%s%s/%s/reset-password?id=%s",
- c.Protocol(),
- a.config.Hostname,
- controller.UrlPort(c.Protocol(), a.config.Port),
+ "%s/%s/reset-password?id=%s",
+ c.Locals("fqdn"),
c.Params("lang"),
user.RecoveryUUID,
)
diff --git a/internal/webserver/controller/auth/update-password.go b/internal/webserver/controller/auth/update-password.go
index c533d2b0..72c2040a 100644
--- a/internal/webserver/controller/auth/update-password.go
+++ b/internal/webserver/controller/auth/update-password.go
@@ -10,7 +10,7 @@ import (
)
func (a *Controller) UpdatePassword(c *fiber.Ctx) error {
- user, err := a.validateRecoveryAccess(c, c.FormValue("id"))
+ user, err := a.validateRecoveryAccess(c.FormValue("id"))
if err != nil {
return err
}
@@ -36,7 +36,7 @@ func (a *Controller) UpdatePassword(c *fiber.Ctx) error {
return c.Redirect(fmt.Sprintf("/%s/login", c.Params("lang")))
}
-func (a *Controller) validateRecoveryAccess(c *fiber.Ctx, recoveryUuid string) (*model.User, error) {
+func (a *Controller) validateRecoveryAccess(recoveryUuid string) (*model.User, error) {
if _, ok := a.sender.(*infrastructure.NoEmail); ok {
return &model.User{}, fiber.ErrNotFound
}
diff --git a/internal/webserver/controller/controller.go b/internal/webserver/controller/controller.go
deleted file mode 100644
index 8338f241..00000000
--- a/internal/webserver/controller/controller.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package controller
-
-import "fmt"
-
-const (
- defaultHttpPort = 80
- defaultHttpsPort = 443
-)
-
-func UrlPort(protocol string, port int) string {
- urlPort := fmt.Sprintf(":%d", port)
- if (port == defaultHttpPort && protocol == "http") ||
- (port == defaultHttpsPort && protocol == "https") {
- urlPort = ""
- }
- return urlPort
-}
diff --git a/internal/webserver/controller/document/delete.go b/internal/webserver/controller/document/delete.go
index 9a4be8b7..91cb3a48 100644
--- a/internal/webserver/controller/document/delete.go
+++ b/internal/webserver/controller/document/delete.go
@@ -6,17 +6,9 @@ import (
"path/filepath"
"github.com/gofiber/fiber/v2"
- "github.com/svera/coreander/v3/internal/webserver/jwtclaimsreader"
- "github.com/svera/coreander/v3/internal/webserver/model"
)
func (d *Controller) Delete(c *fiber.Ctx) error {
- session := jwtclaimsreader.SessionData(c)
-
- if session.Role != model.RoleAdmin {
- return fiber.ErrForbidden
- }
-
if c.FormValue("slug") == "" {
return fiber.ErrBadRequest
}
diff --git a/internal/webserver/controller/document/upload.go b/internal/webserver/controller/document/upload.go
index f7c80a45..47355698 100644
--- a/internal/webserver/controller/document/upload.go
+++ b/internal/webserver/controller/document/upload.go
@@ -9,34 +9,14 @@ import (
"os"
"path/filepath"
"slices"
- "strings"
"github.com/gofiber/fiber/v2"
- "github.com/svera/coreander/v3/internal/webserver/controller"
- "github.com/svera/coreander/v3/internal/webserver/model"
"github.com/valyala/fasthttp"
)
func (d *Controller) UploadForm(c *fiber.Ctx) error {
- var session model.User
- if val, ok := c.Locals("Session").(model.User); ok {
- session = val
- }
-
- if session.Role != model.RoleAdmin {
- return fiber.ErrForbidden
- }
-
- upload := fmt.Sprintf(
- "%s://%s%s/%s/upload",
- c.Protocol(),
- d.config.Hostname,
- controller.UrlPort(c.Protocol(), d.config.Port),
- c.Params("lang"),
- )
-
msg := ""
- if ref := string(c.Request().Header.Referer()); strings.HasPrefix(ref, upload) {
+ if c.Params("success") != "" {
msg = "Document uploaded successfully."
}
@@ -48,12 +28,6 @@ func (d *Controller) UploadForm(c *fiber.Ctx) error {
}
func (d *Controller) Upload(c *fiber.Ctx) error {
- session := c.Locals("Session").(model.User)
-
- if session.Role != model.RoleAdmin {
- return fiber.ErrForbidden
- }
-
file, err := c.FormFile("filename")
if err != nil {
if errors.Is(err, fasthttp.ErrMissingFile) {
@@ -105,7 +79,7 @@ func (d *Controller) Upload(c *fiber.Ctx) error {
return internalServerErrorStatus
}
- return c.Redirect(fmt.Sprintf("/%s/upload", c.Params("lang")))
+ return c.Redirect(fmt.Sprintf("/%s/upload?success=1", c.Params("lang")))
}
func fileToBytes(fileHeader *multipart.FileHeader) ([]byte, error) {
diff --git a/internal/webserver/controller/user/controller.go b/internal/webserver/controller/user/controller.go
index 35cd13d5..6e4741a4 100644
--- a/internal/webserver/controller/user/controller.go
+++ b/internal/webserver/controller/user/controller.go
@@ -1,7 +1,6 @@
package user
import (
- "github.com/gofiber/fiber/v2"
"github.com/svera/coreander/v3/internal/result"
"github.com/svera/coreander/v3/internal/webserver/model"
)
@@ -34,25 +33,3 @@ func NewController(repository usersRepository, usersCfg Config) *Controller {
config: usersCfg,
}
}
-
-// New renders the new user form
-func (u *Controller) New(c *fiber.Ctx) error {
- var session model.User
- if val, ok := c.Locals("Session").(model.User); ok {
- session = val
- }
-
- if session.Role != model.RoleAdmin {
- return fiber.ErrForbidden
- }
-
- user := model.User{
- WordsPerMinute: u.config.WordsPerMinute,
- }
- return c.Render("users/new", fiber.Map{
- "Title": "Add user",
- "MinPasswordLength": u.config.MinPasswordLength,
- "User": user,
- "Errors": map[string]string{},
- }, "layout")
-}
diff --git a/internal/webserver/controller/user/create.go b/internal/webserver/controller/user/create.go
index 090b0957..5482c6b2 100644
--- a/internal/webserver/controller/user/create.go
+++ b/internal/webserver/controller/user/create.go
@@ -11,15 +11,6 @@ import (
// Create gathers information coming from the new user form and creates a new user
func (u *Controller) Create(c *fiber.Ctx) error {
- var session model.User
- if val, ok := c.Locals("Session").(model.User); ok {
- session = val
- }
-
- if session.Role != model.RoleAdmin {
- return fiber.ErrForbidden
- }
-
role, _ := strconv.Atoi(c.FormValue("role"))
user := model.User{
Name: c.FormValue("name"),
diff --git a/internal/webserver/controller/user/delete.go b/internal/webserver/controller/user/delete.go
index f4691106..27ec0bf7 100644
--- a/internal/webserver/controller/user/delete.go
+++ b/internal/webserver/controller/user/delete.go
@@ -4,18 +4,11 @@ import (
"fmt"
"github.com/gofiber/fiber/v2"
- "github.com/svera/coreander/v3/internal/webserver/jwtclaimsreader"
"github.com/svera/coreander/v3/internal/webserver/model"
)
// Delete removes a user from the database
func (u *Controller) Delete(c *fiber.Ctx) error {
- session := jwtclaimsreader.SessionData(c)
-
- if session.Role != model.RoleAdmin {
- return fiber.ErrForbidden
- }
-
user, err := u.repository.FindByUuid(c.FormValue("uuid"))
if err != nil {
return fiber.ErrNotFound
diff --git a/internal/webserver/controller/user/list.go b/internal/webserver/controller/user/list.go
index b76c103e..703c4f38 100644
--- a/internal/webserver/controller/user/list.go
+++ b/internal/webserver/controller/user/list.go
@@ -10,15 +10,6 @@ import (
// List list all users registered in the database
func (u *Controller) List(c *fiber.Ctx) error {
- var session model.User
- if val, ok := c.Locals("Session").(model.User); ok {
- session = val
- }
-
- if session.Role != model.RoleAdmin {
- return fiber.ErrForbidden
- }
-
page, err := strconv.Atoi(c.Query("page"))
if err != nil {
page = 1
diff --git a/internal/webserver/controller/user/new.go b/internal/webserver/controller/user/new.go
new file mode 100644
index 00000000..a0a022be
--- /dev/null
+++ b/internal/webserver/controller/user/new.go
@@ -0,0 +1,19 @@
+package user
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/svera/coreander/v3/internal/webserver/model"
+)
+
+// New renders the new user form
+func (u *Controller) New(c *fiber.Ctx) error {
+ user := model.User{
+ WordsPerMinute: u.config.WordsPerMinute,
+ }
+ return c.Render("users/new", fiber.Map{
+ "Title": "Add user",
+ "MinPasswordLength": u.config.MinPasswordLength,
+ "User": user,
+ "Errors": map[string]string{},
+ }, "layout")
+}
diff --git a/internal/webserver/embedded/translations/es.yml b/internal/webserver/embedded/translations/es.yml
index ba1d781d..3ccc0ddc 100644
--- a/internal/webserver/embedded/translations/es.yml
+++ b/internal/webserver/embedded/translations/es.yml
@@ -76,6 +76,7 @@
"A reset password request for Coreander has been received. You can proceed by clicking in the following link or pasting it in your browser": "Hemos recibido una petición para actualizar tu contraseña en Coreander. Si has sido tu, puedes continuar haciendo click en el siguiente enlace o pegándolo en tu navegador"
"If you didn't request this, you can safely disregard this email.": "Si no has sido tu, puedes ignorar este correo."
"We've received your password recovery request. If the address you introduced is registered in our system, you'll receive an email with further instructions in your inbox.": "Hemos recibido tu petición para recuperar tu contraseña. Si la dirección que has indicado está registrada en el sistema, recibiras un correo con indicaciones en tu bandeja de entrada."
+"Check your spam folder if you don't receive the recovery email after a while.": "Comprueba tu carpeta de correo no deseado si no recibes el correo de confirmación en unos momentos."
"Password recovery request": "Petición de recuperación de contraseña"
"Set new password": "Introduce tu nueva contraseña"
"Password changed successfully. Please sign in.": "Contraseña modificada con éxito. Por favor, identifícate."
@@ -114,3 +115,4 @@
"Request entity too large": "Petición demasiado grande"
"Error uploading document": "Error al subir el documento"
"Invalid file type": "Tipo de archivo no válido"
+"Upload": "Subir"
diff --git a/internal/webserver/embedded/translations/fr.yml b/internal/webserver/embedded/translations/fr.yml
index 766b7d05..e105d23d 100644
--- a/internal/webserver/embedded/translations/fr.yml
+++ b/internal/webserver/embedded/translations/fr.yml
@@ -76,6 +76,7 @@
"A reset password request for Coreander has been received. You can proceed by clicking in the following link or pasting it in your browser": "Une demande de réinitialisation du mot de passe pour Coreander a été reçue. Vous pouvez continuer en cliquant sur le lien suivant ou en le collant dans votre navigateur"
"If you didn't request this, you can safely disregard this email.": "Si vous ne l'avez pas demandé, vous pouvez ignorer cet e-mail en toute sécurité."
"We've received your password recovery request. If the address you introduced is registered in our system, you'll receive an email with further instructions in your inbox.": "Nous avons reçu votre demande de récupération de mot de passe. Si l'adresse que vous avez introduite est enregistrée dans notre système, vous recevrez un e-mail contenant des instructions supplémentaires dans votre boîte de réception."
+"Check your spam folder if you don't receive the recovery email after a while.": "Vérifiez votre dossier spam si vous ne recevez pas l'e-mail de récupération après un certain temps."
"Password recovery request": "Demande de récupération de mot de passe"
"Set new password": "Définir un nouveau mot de passe"
"Password changed successfully. Please sign in.": "Mot de passe modifié avec succès. Veuillez vous connecter."
@@ -114,3 +115,4 @@
"Request entity too large": "Entité de requête trop grande"
"Error uploading document": "Erreur lors du téléchargement du document"
"Invalid file type": "Type de fichier invalide"
+"Upload": "Télécharger"
diff --git a/internal/webserver/embedded/views/auth/request.html b/internal/webserver/embedded/views/auth/request.html
index e10113a0..50e44180 100644
--- a/internal/webserver/embedded/views/auth/request.html
+++ b/internal/webserver/embedded/views/auth/request.html
@@ -2,5 +2,6 @@
{{t .Lang "We've received your password recovery request. If the address you introduced is registered in our system, you'll receive an email with further instructions in your inbox."}} {{t .Lang "Check your spam folder if you don't receive the recovery email after a while."}}{{t .Lang "Recover password"}}
{{t .Lang "%d matches found" .Results.TotalHits }}
- {{else}} -{{t .Lang "No matches found" }}
- {{end}} + {{template "partials/searchbox" .}} ++ {{if gt .Results.TotalHits 0}} + {{t .Lang "%d matches found" .Results.TotalHits }} + {{else}} + {{t .Lang "No matches found" }} + {{end}} +
{{ template "partials/docs-list" . }} diff --git a/internal/webserver/embedded/views/upload.html b/internal/webserver/embedded/views/upload.html index 2fe560f2..af6124de 100644 --- a/internal/webserver/embedded/views/upload.html +++ b/internal/webserver/embedded/views/upload.html @@ -28,7 +28,7 @@