aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/constants.go (renamed from controllers/constants.go)13
-rw-r--r--config/types.go32
-rw-r--r--controllers/account.go17
-rw-r--r--controllers/home.go5
-rw-r--r--controllers/login.go26
-rw-r--r--controllers/logout.go11
-rw-r--r--controllers/posts.go36
-rw-r--r--controllers/register.go17
-rw-r--r--database/database.go2
-rw-r--r--database/posts.go11
-rw-r--r--processors/preferences.go14
-rw-r--r--processors/request.go27
-rw-r--r--processors/sidebar.go11
-rw-r--r--processors/user.go2
-rw-r--r--router/routes.go3
-rw-r--r--templates/login.django3
-rw-r--r--templates/partials/navbar.django2
-rw-r--r--templates/posts.django34
-rw-r--r--templates/posts/list.django19
-rw-r--r--templates/posts/new.django4
-rw-r--r--utils/auth/auth.go45
-rw-r--r--utils/email/email.go2
22 files changed, 208 insertions, 128 deletions
diff --git a/controllers/constants.go b/config/constants.go
index 7417314..8f7a91a 100644
--- a/controllers/constants.go
+++ b/config/constants.go
@@ -1,10 +1,11 @@
-package controllers
+package config
const (
// Page titles
PT_HOME = "Home Page"
PT_LOGIN = "Login"
- PT_POSTS = "Posts"
+ PT_POST_LIST = "Posts"
+ PT_POST_NEW = "Upload New Post"
PT_PREFERENCES = "Preferences"
PT_REGISTER = "Register"
PT_404 = "Page Not Found"
@@ -13,7 +14,8 @@ const (
// Template names
TEMPLATE_HOME = "home"
TEMPLATE_LOGIN = "login"
- TEMPLATE_POSTS = "posts"
+ TEMPLATE_POST_LIST = "posts/list"
+ TEMPLATE_POST_NEW = "posts/new"
TEMPLATE_PREFERENCES = "preferences"
TEMPLATE_REGISTER = "register"
TEMPLATE_404 = "404"
@@ -22,9 +24,12 @@ const (
// URL constants for various routes
URL_HOME = "/"
URL_LOGIN = "/login"
- URL_POSTS = "/posts"
+ URL_LOGOUT = "/logout"
+ URL_POST_LIST = "/posts"
+ URL_POST_NEW = "/posts/new"
URL_PREFERENCES = "/preferences"
URL_REGISTER = "/register"
+ URL_VERIFY_EMAIL = "/account/verify"
URL_FORGOT_PASSWORD = "/account/forgot-password"
URL_RESEND_VERIFICATION = "/account/resend-verification"
diff --git a/config/types.go b/config/types.go
index 129e3d2..a66c7a4 100644
--- a/config/types.go
+++ b/config/types.go
@@ -55,3 +55,35 @@ type SMTPConfig struct {
Password string `env:"SMTP_PASSWORD" default:""`
From string `env:"EMAIL_FROM" default:""`
}
+
+type QueryParam struct {
+ Key string
+ Value string
+}
+
+type Request struct {
+ Path string
+ Method string
+ Query []QueryParam
+ Params []QueryParam
+ QueryString string
+ IP string
+ URL string
+}
+
+type SiteStats struct {
+ Posts string
+ Tags string
+ Today string
+ Storage string
+ Comments string
+}
+
+type SitePreferences struct {
+ SidebarWidth string `json:"sidebar_width"`
+ MainContentWidth string `json:"main_content_width"`
+ H1FontSize string `json:"h1_font_size"`
+ BodyFontSize string `json:"body_font_size"`
+ SmallFontSize string `json:"small_font_size"`
+ PostsPerPage int `json:"posts_per_page"`
+}
diff --git a/controllers/account.go b/controllers/account.go
index 86b3ea4..fa3e0e7 100644
--- a/controllers/account.go
+++ b/controllers/account.go
@@ -1,6 +1,7 @@
package controllers
import (
+ "imageboard/config"
"imageboard/database"
"imageboard/models"
"imageboard/utils/auth"
@@ -10,38 +11,38 @@ import (
)
func renderVerifyEmailError(ctx *fiber.Ctx, errorMsg string, statusCode int) error {
- return shortcuts.RenderWithStatus(ctx, TEMPLATE_VERIFY_EMAIL, fiber.Map{
+ return shortcuts.RenderWithStatus(ctx, config.TEMPLATE_VERIFY_EMAIL, fiber.Map{
"Error": errorMsg,
}, statusCode)
}
func VerifyEmailController(ctx *fiber.Ctx) error {
- ctx.Locals("Title", PT_VERIFY_EMAIL)
+ ctx.Locals("Title", config.PT_VERIFY_EMAIL)
if auth.IsAuthenticated(ctx) {
return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
}
token := ctx.Query("token")
if token == "" {
- return renderVerifyEmailError(ctx, ERR_VERIFY_EMAIL_MISSING_TOKEN, fiber.StatusBadRequest)
+ return renderVerifyEmailError(ctx, config.ERR_VERIFY_EMAIL_MISSING_TOKEN, fiber.StatusBadRequest)
}
emailToken, err := database.VerifyToken(token, models.EmailTokenTypeVerification)
if err != nil {
- return renderVerifyEmailError(ctx, ERR_VERIFY_EMAIL_INVALID_OR_EXPIRED_TOKEN, fiber.StatusBadRequest)
+ return renderVerifyEmailError(ctx, config.ERR_VERIFY_EMAIL_INVALID_OR_EXPIRED_TOKEN, fiber.StatusBadRequest)
}
user, err := database.GetUserByID(emailToken.UserID)
if err != nil {
- return renderVerifyEmailError(ctx, ERR_VERIFY_EMAIL_USER_NOT_FOUND, fiber.StatusInternalServerError)
+ return renderVerifyEmailError(ctx, config.ERR_VERIFY_EMAIL_USER_NOT_FOUND, fiber.StatusInternalServerError)
}
user.Activate()
if err := database.DB.Save(user).Error; err != nil {
- return renderVerifyEmailError(ctx, ERR_VERIFY_EMAIL_ACTIVATION_FAILED, fiber.StatusInternalServerError)
+ return renderVerifyEmailError(ctx, config.ERR_VERIFY_EMAIL_ACTIVATION_FAILED, fiber.StatusInternalServerError)
}
- return shortcuts.Render(ctx, TEMPLATE_VERIFY_EMAIL, fiber.Map{
- "Success": SUCCESS_VERIFY_EMAIL,
+ return shortcuts.Render(ctx, config.TEMPLATE_VERIFY_EMAIL, fiber.Map{
+ "Success": config.SUCCESS_VERIFY_EMAIL,
"Username": user.Username,
})
diff --git a/controllers/home.go b/controllers/home.go
index 186ef24..9fd0d33 100644
--- a/controllers/home.go
+++ b/controllers/home.go
@@ -1,12 +1,13 @@
package controllers
import (
+ "imageboard/config"
"imageboard/utils/shortcuts"
"github.com/gofiber/fiber/v2"
)
func HomePageController(ctx *fiber.Ctx) error {
- ctx.Locals("Title", PT_HOME)
- return shortcuts.Render(ctx, TEMPLATE_HOME, nil)
+ ctx.Locals("Title", config.PT_HOME)
+ return shortcuts.Render(ctx, config.TEMPLATE_HOME, nil)
}
diff --git a/controllers/login.go b/controllers/login.go
index 6eb4996..aa02e0c 100644
--- a/controllers/login.go
+++ b/controllers/login.go
@@ -1,6 +1,7 @@
package controllers
import (
+ "imageboard/config"
"imageboard/database"
"imageboard/session"
"imageboard/utils/auth"
@@ -15,56 +16,59 @@ type LoginForm struct {
}
func renderLoginError(ctx *fiber.Ctx, errorMsg string, statusCode int) error {
- return shortcuts.RenderWithStatus(ctx, TEMPLATE_LOGIN, fiber.Map{
+ return shortcuts.RenderWithStatus(ctx, config.TEMPLATE_LOGIN, fiber.Map{
"Error": errorMsg,
"Username": ctx.FormValue("username"), // Preserve username in form
}, statusCode)
}
func LoginPageController(ctx *fiber.Ctx) error {
- ctx.Locals("Title", PT_LOGIN)
+ ctx.Locals("Title", config.PT_LOGIN)
if auth.IsAuthenticated(ctx) {
return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
}
- return shortcuts.Render(ctx, TEMPLATE_LOGIN, nil)
+ next := ctx.Query("next")
+ return shortcuts.Render(ctx, config.TEMPLATE_LOGIN, fiber.Map{
+ "Next": next,
+ })
}
func LoginPostController(ctx *fiber.Ctx) error {
- ctx.Locals("Title", PT_LOGIN)
+ ctx.Locals("Title", config.PT_LOGIN)
var form LoginForm
var err error
if err = ctx.BodyParser(&form); err != nil {
- return renderLoginError(ctx, ERR_INVALID_FORM_DATA, fiber.StatusBadRequest)
+ return renderLoginError(ctx, config.ERR_INVALID_FORM_DATA, fiber.StatusBadRequest)
}
user, err := database.GetUserByUsername(form.Username)
if err != nil {
- return renderLoginError(ctx, ERR_USER_NOT_FOUND, fiber.StatusUnauthorized)
+ return renderLoginError(ctx, config.ERR_USER_NOT_FOUND, fiber.StatusUnauthorized)
}
if !user.CheckPassword(form.Password) {
- return renderLoginError(ctx, ERR_LOGIN_INVALID_CREDENTIALS, fiber.StatusUnauthorized)
+ return renderLoginError(ctx, config.ERR_LOGIN_INVALID_CREDENTIALS, fiber.StatusUnauthorized)
}
if !user.IsActive() {
- return renderLoginError(ctx, ERR_ACCOUNT_DISABLED, fiber.StatusForbidden)
+ return renderLoginError(ctx, config.ERR_ACCOUNT_DISABLED, fiber.StatusForbidden)
}
if !user.CanLogin() {
- return renderLoginError(ctx, ERR_ACCOUNT_UNABLE_TO_LOGIN, fiber.StatusForbidden)
+ return renderLoginError(ctx, config.ERR_ACCOUNT_UNABLE_TO_LOGIN, fiber.StatusForbidden)
}
sess, err := session.Store.Get(ctx)
if err != nil {
- return renderLoginError(ctx, ERR_SESSION_FAILED_TO_CREATE, fiber.StatusInternalServerError)
+ return renderLoginError(ctx, config.ERR_SESSION_FAILED_TO_CREATE, fiber.StatusInternalServerError)
}
sess.Set("user_id", user.ID)
sess.Set("username", user.Username)
if err := sess.Save(); err != nil {
- return renderLoginError(ctx, ERR_SESSION_FAILED_TO_SAVE, fiber.StatusInternalServerError)
+ return renderLoginError(ctx, config.ERR_SESSION_FAILED_TO_SAVE, fiber.StatusInternalServerError)
}
user.UpdateLastUserLogin(database.DB)
diff --git a/controllers/logout.go b/controllers/logout.go
index 20c280d..58ff545 100644
--- a/controllers/logout.go
+++ b/controllers/logout.go
@@ -1,8 +1,8 @@
package controllers
import (
+ "imageboard/config"
"imageboard/session"
- "imageboard/utils/auth"
"github.com/gofiber/fiber/v2"
)
@@ -10,7 +10,7 @@ import (
func LogoutController(ctx *fiber.Ctx) error {
sess, err := session.Store.Get(ctx)
if err != nil {
- return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
+ return ctx.Redirect(config.URL_HOME, fiber.StatusSeeOther)
}
if err := sess.Destroy(); err != nil {
@@ -19,5 +19,10 @@ func LogoutController(ctx *fiber.Ctx) error {
sess.Save()
}
- return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
+ next := ctx.Query("next")
+ if next != "" {
+ return ctx.Redirect(next, fiber.StatusSeeOther)
+ }
+
+ return ctx.Redirect(config.URL_HOME, fiber.StatusSeeOther)
}
diff --git a/controllers/posts.go b/controllers/posts.go
index 6fdcd26..03535c7 100644
--- a/controllers/posts.go
+++ b/controllers/posts.go
@@ -1,22 +1,38 @@
package controllers
import (
+ "imageboard/config"
+ "imageboard/database"
+ "imageboard/utils/auth"
"imageboard/utils/shortcuts"
"github.com/gofiber/fiber/v2"
)
-func PostsController(ctx *fiber.Ctx) error {
- ctx.Locals("Title", "Posts")
+func PostsPageController(ctx *fiber.Ctx) error {
+ ctx.Locals("Title", config.PT_POST_LIST)
+ preferences := ctx.Locals("Preferences")
+ prefs, ok := preferences.(config.SitePreferences)
+ if !ok {
+ return fiber.NewError(fiber.StatusInternalServerError, "Invalid preferences type")
+ }
+
+ posts, err := database.GetPosts(prefs.PostsPerPage)
- searchQuery := ctx.Query("tags", "")
+ return shortcuts.Render(ctx, config.TEMPLATE_POST_LIST, fiber.Map{
+ "Posts": posts,
+ "Error": err,
+ })
+}
- customdata := struct {
- SearchQuery string
- Posts []interface{}
- }{
- SearchQuery: searchQuery,
- Posts: []interface{}{},
+func PostsUploadPageController(ctx *fiber.Ctx) error {
+ ctx.Locals("Title", config.PT_POST_NEW)
+ if !auth.IsAuthenticated(ctx) {
+ loginURL := auth.GetLoginURLWithRedirect(ctx)
+ ctx.Set("Location", loginURL)
+ ctx.Status(fiber.StatusFound)
+ return nil
}
- return shortcuts.Render(ctx, "posts", customdata)
+
+ return shortcuts.Render(ctx, config.TEMPLATE_POST_NEW, nil)
}
diff --git a/controllers/register.go b/controllers/register.go
index acadbc5..c52d6e5 100644
--- a/controllers/register.go
+++ b/controllers/register.go
@@ -1,6 +1,7 @@
package controllers
import (
+ "imageboard/config"
"imageboard/database"
"imageboard/models"
"imageboard/utils/auth"
@@ -20,7 +21,7 @@ type RegisterForm struct {
}
func renderRegisterError(ctx *fiber.Ctx, errorMsg string, statusCode int) error {
- return shortcuts.RenderWithStatus(ctx, TEMPLATE_REGISTER, fiber.Map{
+ return shortcuts.RenderWithStatus(ctx, config.TEMPLATE_REGISTER, fiber.Map{
"Error": errorMsg,
"Username": ctx.FormValue("username"),
"Email": ctx.FormValue("email"),
@@ -28,17 +29,17 @@ func renderRegisterError(ctx *fiber.Ctx, errorMsg string, statusCode int) error
}
func RegisterPageController(ctx *fiber.Ctx) error {
- ctx.Locals("Title", PT_REGISTER)
+ ctx.Locals("Title", config.PT_REGISTER)
if auth.IsAuthenticated(ctx) {
return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
}
- return shortcuts.Render(ctx, TEMPLATE_REGISTER, nil)
+ return shortcuts.Render(ctx, config.TEMPLATE_REGISTER, nil)
}
func RegisterPostController(ctx *fiber.Ctx) error {
- ctx.Locals("Title", PT_REGISTER)
+ ctx.Locals("Title", config.PT_REGISTER)
if auth.IsAuthenticated(ctx) {
return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
@@ -46,11 +47,11 @@ func RegisterPostController(ctx *fiber.Ctx) error {
var form RegisterForm
if err := ctx.BodyParser(&form); err != nil {
- return renderRegisterError(ctx, ERR_INVALID_FORM_DATA, fiber.StatusBadRequest)
+ return renderRegisterError(ctx, config.ERR_INVALID_FORM_DATA, fiber.StatusBadRequest)
}
if form.Password != form.ConfirmPassword {
- return renderRegisterError(ctx, ERR_PASSWORD_MISMATCH, fiber.StatusBadRequest)
+ return renderRegisterError(ctx, config.ERR_PASSWORD_MISMATCH, fiber.StatusBadRequest)
}
user := &models.User{
@@ -77,7 +78,7 @@ func RegisterPostController(ctx *fiber.Ctx) error {
return renderRegisterError(ctx, "User created but failed to send verification email", fiber.StatusInternalServerError)
}
- return shortcuts.Render(ctx, TEMPLATE_REGISTER, fiber.Map{
- "Success": SUCCESS_USER_REGISTERED,
+ return shortcuts.Render(ctx, config.TEMPLATE_REGISTER, fiber.Map{
+ "Success": config.SUCCESS_USER_REGISTERED,
})
}
diff --git a/database/database.go b/database/database.go
index dedae59..0065479 100644
--- a/database/database.go
+++ b/database/database.go
@@ -31,7 +31,7 @@ func init() {
logLevel := logger.Silent
if config.Server.IsDevMode {
- logLevel = logger.Info
+ logLevel = logger.Silent
}
dialector := postgres.Open(dsn)
diff --git a/database/posts.go b/database/posts.go
new file mode 100644
index 0000000..3e949c2
--- /dev/null
+++ b/database/posts.go
@@ -0,0 +1,11 @@
+package database
+
+import "imageboard/models"
+
+func GetPosts(limit int) ([]models.Image, error) {
+ var posts []models.Image
+ if err := DB.Limit(limit).Find(&posts).Error; err != nil {
+ return nil, err
+ }
+ return posts, nil
+}
diff --git a/processors/preferences.go b/processors/preferences.go
index a96d1cb..a74d1e5 100644
--- a/processors/preferences.go
+++ b/processors/preferences.go
@@ -3,21 +3,13 @@ package processors
import (
"encoding/json"
"fmt"
+ "imageboard/config"
"github.com/gofiber/fiber/v2"
)
-type SitePreferences struct {
- SidebarWidth string `json:"sidebar_width"`
- MainContentWidth string `json:"main_content_width"`
- H1FontSize string `json:"h1_font_size"`
- BodyFontSize string `json:"body_font_size"`
- SmallFontSize string `json:"small_font_size"`
- PostsPerPage int `json:"posts_per_page"`
-}
-
func PreferencesContextProcessor(context *fiber.Ctx) error {
- defaultPreferences := SitePreferences{
+ defaultPreferences := config.SitePreferences{
SidebarWidth: "180px",
MainContentWidth: "1200px",
H1FontSize: "16px",
@@ -48,7 +40,7 @@ func PreferencesContextProcessor(context *fiber.Ctx) error {
return context.Next()
}
-func preferencesToCSS(preferences SitePreferences) string {
+func preferencesToCSS(preferences config.SitePreferences) string {
return fmt.Sprintf(`
<style>
main {
diff --git a/processors/request.go b/processors/request.go
index f4fe8d2..173b29d 100644
--- a/processors/request.go
+++ b/processors/request.go
@@ -1,36 +1,23 @@
package processors
import (
+ "imageboard/config"
+
"github.com/gofiber/fiber/v2"
)
-type QueryParam struct {
- Key string
- Value string
-}
-
-type Request struct {
- Path string
- Method string
- Query []QueryParam
- Params []QueryParam
- QueryString string
- IP string
- URL string
-}
-
func RequestContextProcessor(ctx *fiber.Ctx) error {
- queryParams := []QueryParam{}
+ queryParams := []config.QueryParam{}
for k, v := range ctx.Queries() {
- queryParams = append(queryParams, QueryParam{Key: k, Value: v})
+ queryParams = append(queryParams, config.QueryParam{Key: k, Value: v})
}
- routeParams := []QueryParam{}
+ routeParams := []config.QueryParam{}
for k, v := range ctx.AllParams() {
- routeParams = append(routeParams, QueryParam{Key: k, Value: v})
+ routeParams = append(routeParams, config.QueryParam{Key: k, Value: v})
}
- request := Request{
+ request := config.Request{
Path: ctx.Path(),
Method: ctx.Method(),
Query: queryParams,
diff --git a/processors/sidebar.go b/processors/sidebar.go
index 26138f1..6fe2fdf 100644
--- a/processors/sidebar.go
+++ b/processors/sidebar.go
@@ -2,20 +2,13 @@ package processors
import (
"fmt"
+ "imageboard/config"
"imageboard/database"
"imageboard/models"
"github.com/gofiber/fiber/v2"
)
-type SiteStats struct {
- Posts string
- Tags string
- Today string
- Storage string
- Comments string
-}
-
func SidebarContextProcessor(ctx *fiber.Ctx) error {
popularTags, popularTagsErr := database.GetPopularTags(15)
if popularTagsErr != nil || len(popularTags) == 0 {
@@ -64,7 +57,7 @@ func SidebarContextProcessor(ctx *fiber.Ctx) error {
todayCount, todayErr := database.GetTodayPostsCount()
storageSize, storageErr := database.GetTotalStorageSize()
- var stats SiteStats
+ var stats config.SiteStats
if postsErr == nil {
stats.Posts = fmt.Sprintf("%d", postsCount)
diff --git a/processors/user.go b/processors/user.go
index b875c89..e96f1f9 100644
--- a/processors/user.go
+++ b/processors/user.go
@@ -4,6 +4,7 @@ import (
"imageboard/database"
"imageboard/models"
"imageboard/session"
+ "imageboard/utils/auth"
"github.com/gofiber/fiber/v2"
)
@@ -38,6 +39,7 @@ func UserContextProcessor(ctx *fiber.Ctx) error {
ctx.Locals("User", user)
ctx.Locals("IsAuthenticated", user != nil)
+ ctx.Locals("LogoutURL", auth.GetLogoutURLWithRedirect(ctx))
return ctx.Next()
}
diff --git a/router/routes.go b/router/routes.go
index 91665df..b074103 100644
--- a/router/routes.go
+++ b/router/routes.go
@@ -11,7 +11,8 @@ func Initialize(router *fiber.App) {
main.Get("/", controllers.HomePageController)
posts := router.Group("/posts")
- posts.Get("/", controllers.PostsController)
+ posts.Get("/", controllers.PostsPageController)
+ posts.Get("/new", controllers.PostsUploadPageController)
login := router.Group("/login")
login.Get("/", controllers.LoginPageController)
diff --git a/templates/login.django b/templates/login.django
index 01c6d28..f2136fc 100644
--- a/templates/login.django
+++ b/templates/login.django
@@ -7,6 +7,9 @@
<h1>Login to {{ Appname }}</h1>
<p>Welcome back! Please enter your credentials to continue.</p>
<form action="/login" method="POST" class="ibform">
+ {% if Next %}
+ <input type="hidden" name="next" value="{{ Next }}" />
+ {% endif %}
{% if Error %}
<div class="error">{{ Error|safe }}</div>
{% endif %}
diff --git a/templates/partials/navbar.django b/templates/partials/navbar.django
index 7180e9c..2287302 100644
--- a/templates/partials/navbar.django
+++ b/templates/partials/navbar.django
@@ -13,7 +13,7 @@
{% if User %}
<a href="/account" class="user-status">{{ User.Username }}</a>
<a href="/posts/new">Upload</a>
- <a href="/logout">Logout</a>
+ <a href="{{ LogoutURL }}">Logout</a>
{% else %}
<span class="user-status">Guest</span>
<a href="/login">Login</a>
diff --git a/templates/posts.django b/templates/posts.django
deleted file mode 100644
index 111c959..0000000
--- a/templates/posts.django
+++ /dev/null
@@ -1,34 +0,0 @@
-{% extends 'layouts/main.django' %}
-{% include 'partials/search.django' %}
-{% block content %}
- <h2>{{ Title }}</h2>
-
- <div class="posts-grid">
- {% if Posts %}
- {% for post in Posts %}
- <div class="post-cell">
- <img src="/uploads/thumbnails/{{ post.FileName }}" alt="{{ post.Title }}" class="post-img" />
- <div class="post-title">
- {% if post.Title %}
- {{ post.Title }}
- {% else %}
- Post #{{ post.ID }}
- {% endif %}
- </div>
- <div class="post-info">{{ post.Tags|length }} tags</div>
- </div>
- {% endfor %}
- {% else %}
- <div class="empty-state">
- <h3>NO POSTS FOUND!</h3>
- <p>Be the first to share something awesome!</p>
- <input type="button" value="UPLOAD IMAGE" onclick="location.href='/upload'" />
- </div>
- {% endif %}
- </div>
-
- <p class="center">
- <input type="button" value="UPLOAD IMAGE" onclick="location.href='/upload'" />
- </p>
- <button class="secondary" onclick="location.href='/tags'">BROWSE TAGS</button>
-{% endblock %}
diff --git a/templates/posts/list.django b/templates/posts/list.django
new file mode 100644
index 0000000..d4f933b
--- /dev/null
+++ b/templates/posts/list.django
@@ -0,0 +1,19 @@
+{% extends 'layouts/main.django' %}
+{% include 'partials/search.django' %}
+{% block content %}
+ {% if Error %}
+ <div class="centered-main">
+ <div class="error">{{ Error }}</div>
+ </div>
+ {% endif %}
+ {% if Posts %}
+ Will Show posts here
+ {% else %}
+ <div class="centered-main">
+ <h1>No Posts Available</h1>
+ <p>
+ It seems there are no posts available at the moment. Check back later or <a href="/posts/new">upload a new post</a>.
+ </p>
+ </div>
+ {% endif %}
+{% endblock %}
diff --git a/templates/posts/new.django b/templates/posts/new.django
new file mode 100644
index 0000000..d3a2e5e
--- /dev/null
+++ b/templates/posts/new.django
@@ -0,0 +1,4 @@
+{% extends 'layouts/main.django' %}
+{% block content %}
+ Upload a new post here
+{% endblock %}
diff --git a/utils/auth/auth.go b/utils/auth/auth.go
index 7b8f260..f92e955 100644
--- a/utils/auth/auth.go
+++ b/utils/auth/auth.go
@@ -1,7 +1,9 @@
package auth
import (
+ "imageboard/config"
"imageboard/models"
+ "net/url"
"github.com/gofiber/fiber/v2"
)
@@ -18,9 +20,44 @@ func IsAuthenticated(ctx *fiber.Ctx) bool {
}
func GetRedirectURL(ctx *fiber.Ctx) string {
- referer := ctx.Get("Referer")
- if referer != "" && referer != ctx.BaseURL()+"/login" && referer != ctx.BaseURL()+"/register" {
- return referer
+ next := ctx.Query("next")
+ if next == "" {
+ next = ctx.FormValue("next")
}
- return "/"
+ if next != "" && isValidRedirectURL(next) {
+ return next
+ }
+ return config.URL_HOME
+}
+
+func isValidRedirectURL(redirectURL string) bool {
+ if redirectURL == "" {
+ return false
+ }
+
+ if redirectURL == config.URL_LOGIN || redirectURL == config.URL_REGISTER || redirectURL == config.URL_LOGOUT {
+ return false
+ }
+
+ if redirectURL[0] == '/' {
+ return true
+ }
+
+ return false
+}
+
+func GetLoginURLWithRedirect(ctx *fiber.Ctx) string {
+ currentPath := ctx.Path()
+ if queryString := string(ctx.Request().URI().QueryString()); queryString != "" {
+ currentPath += "?" + queryString
+ }
+ return config.URL_LOGIN + "?next=" + url.QueryEscape(currentPath)
+}
+
+func GetLogoutURLWithRedirect(ctx *fiber.Ctx) string {
+ currentPath := ctx.Path()
+ if queryString := string(ctx.Request().URI().QueryString()); queryString != "" {
+ currentPath += "?" + queryString
+ }
+ return config.URL_LOGOUT + "?next=" + url.QueryEscape(currentPath)
}
diff --git a/utils/email/email.go b/utils/email/email.go
index fb1d58d..5019627 100644
--- a/utils/email/email.go
+++ b/utils/email/email.go
@@ -45,7 +45,7 @@ func SendVerificationEmail(user *models.User) error {
if err != nil {
return fmt.Errorf("failed to parse email template: %w", err)
}
- verificationLink := fmt.Sprintf("%s/account/verify?token=%s", config.Server.AppBaseURL, token.Token)
+ verificationLink := fmt.Sprintf("%s%s?token=%s", config.Server.AppBaseURL, config.URL_VERIFY_EMAIL, token.Token)
data := struct {
Username string
Appname string