updates
All checks were successful
build / build (push) Successful in 33s

This commit is contained in:
Tijl 2024-08-22 12:57:38 +02:00
parent c6e80552cd
commit 5693a59784
Signed by: tijl
GPG Key ID: DAE24BFCD722F053
41 changed files with 188 additions and 74 deletions

View File

@ -5,7 +5,7 @@ tmp_dir = ".air-tmp"
bin = "./tijl.dev" bin = "./tijl.dev"
cmd = "just build" cmd = "just build"
delay = 1000 delay = 1000
exclude_dir = ["node_modules","modules/database","web/assets/static"] exclude_dir = ["node_modules","modules/database","web/static"]
exclude_unchanged = false exclude_unchanged = false
follow_symlink = false follow_symlink = false
include_ext = ["go", "html", "js", "ts"] include_ext = ["go", "html", "js", "ts"]

4
.gitignore vendored
View File

@ -1,6 +1,6 @@
node_modules/ node_modules/
tijl.dev tijl.dev
web/assets/static/js/interactive.js web/static/js/interactive.js
web/assets/static/css/styles.css web/static/css/styles.css
config.yaml config.yaml

View File

@ -1,4 +1,4 @@
package views package assets
import "embed" import "embed"

View File

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

View File

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 382 B

View File

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 328 B

View File

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 301 B

View File

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

View File

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 271 B

View File

@ -2,10 +2,10 @@ package assets
import ( import (
"html/template" "html/template"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
"git.tijl.dev/tijl/tijl.dev/assets"
"git.tijl.dev/tijl/tijl.dev/modules/logger" "git.tijl.dev/tijl/tijl.dev/modules/logger"
) )
@ -14,24 +14,29 @@ var SVGData map[string]string
func loadSVGs() { func loadSVGs() {
SVGData = make(map[string]string) SVGData = make(map[string]string)
dir := "web/assets/icons" files, err := assets.Embed.ReadDir("icons")
// assets.Embed
files, err := filepath.Glob(filepath.Join(dir, "*.svg"))
if err != nil { if err != nil {
log.Fatal().Err(err) log.Fatal().Err(err)
} }
for _, file := range files { for _, file := range files {
data, err := os.ReadFile(file) if file.IsDir() {
continue
}
if filepath.Ext(file.Name()) != ".svg" {
continue
}
data, err := assets.Embed.ReadFile(filepath.Join("icons", file.Name()))
if err != nil { if err != nil {
log.Fatal().Err(err) log.Fatal().Err(err)
continue continue
} }
filename := filepath.Base(file) filename := file.Name()
key := strings.TrimSuffix(filename, filepath.Ext(filename)) key := strings.TrimSuffix(filename, filepath.Ext(filename))
SVGData[key] = string(data) SVGData[key] = string(data)
log.Debug().Str("filename", filename).Msg("assets.loadSVGs: loaded")
} }
log.Debug().Msg("loaded svg files") log.Debug().Msg("loaded svg files")

View File

@ -0,0 +1,25 @@
package handlers
import (
"database/sql"
"git.tijl.dev/tijl/tijl.dev/internal/i18n"
"git.tijl.dev/tijl/tijl.dev/internal/user"
"git.tijl.dev/tijl/tijl.dev/modules/web"
"github.com/gofiber/fiber/v2"
)
func accountHandler(c *fiber.Ctx) error {
data := *web.Common(c)
data["Title"] = i18n.Translate(c, "account")
err, u := user.GetUser(data["Uid"].(string))
data["User"] = u
if err != nil {
if err == sql.ErrNoRows {
c.Redirect("/login")
} else {
return err
}
}
return c.Render("account", data, "layouts/base")
}

39
internal/handlers/auth.go Normal file
View File

@ -0,0 +1,39 @@
package handlers
import (
"git.tijl.dev/tijl/tijl.dev/internal/i18n"
"git.tijl.dev/tijl/tijl.dev/internal/oidc"
"git.tijl.dev/tijl/tijl.dev/internal/user"
"git.tijl.dev/tijl/tijl.dev/modules/web"
"github.com/gofiber/fiber/v2"
)
func loginHandler(c *fiber.Ctx) error {
_, err := user.GetSession(c)
if err == nil {
return c.Redirect("/account")
} else {
data := *web.Common(c)
data["Title"] = i18n.Translate(c, "login")
return c.Render("login", data, "layouts/base")
}
}
func authHandler(c *fiber.Ctx) error {
_, err := user.GetSession(c)
if err == nil {
return c.Redirect("/account")
} else {
return oidc.HandleRedirect(c)
}
}
func logoutHandler(c *fiber.Ctx) error {
_, err := user.GetSession(c)
if err == nil {
c.ClearCookie("session")
return c.Redirect("/login")
} else {
return c.Redirect("/login")
}
}

View File

@ -1,16 +0,0 @@
package handlers
import (
"git.tijl.dev/tijl/tijl.dev/internal/oidc"
"git.tijl.dev/tijl/tijl.dev/internal/sessions"
"github.com/gofiber/fiber/v2"
)
func loginHandler(c *fiber.Ctx) error {
_, err := sessions.GetSession(c)
if err == nil {
return c.Redirect("/account")
} else {
return oidc.HandleRedirect(c)
}
}

View File

@ -8,7 +8,7 @@ import (
"git.tijl.dev/tijl/tijl.dev/internal/i18n" "git.tijl.dev/tijl/tijl.dev/internal/i18n"
"git.tijl.dev/tijl/tijl.dev/internal/oidc" "git.tijl.dev/tijl/tijl.dev/internal/oidc"
"git.tijl.dev/tijl/tijl.dev/modules/web" "git.tijl.dev/tijl/tijl.dev/modules/web"
"git.tijl.dev/tijl/tijl.dev/web/assets" webf "git.tijl.dev/tijl/tijl.dev/web"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/fiber/v2/middleware/filesystem"
) )
@ -39,15 +39,18 @@ func routes(app *fiber.App) {
data["Title"] = i18n.Translate(c, "about") data["Title"] = i18n.Translate(c, "about")
return c.Render("about", data, "layouts/base") return c.Render("about", data, "layouts/base")
}) })
app.Get("/login", loginHandler)
app.Get("/account", accountHandler)
app.Get("/logout", logoutHandler)
app.Get("/settings", settingsHandler) app.Get("/settings", settingsHandler)
app.Get("/login", loginHandler) app.Get("/auth", authHandler)
app.Get(config.Config.Oidc.CallbackUrl, oidc.HandleCallback) app.Get(config.Config.Oidc.CallbackUrl, oidc.HandleCallback)
/* /*
Static Static
*/ */
static, _ := fs.Sub(assets.StaticEmbed, "static") static, _ := fs.Sub(webf.StaticEmbed, "static")
app.Use("/static/", filesystem.New(filesystem.Config{ app.Use("/static/", filesystem.New(filesystem.Config{
Root: http.FS(static), Root: http.FS(static),
})) }))

View File

@ -1,19 +1,33 @@
package handlers package handlers
import "github.com/gofiber/fiber/v2" import (
"git.tijl.dev/tijl/tijl.dev/internal/i18n"
"git.tijl.dev/tijl/tijl.dev/modules/web"
"github.com/gofiber/fiber/v2"
)
func settingsHandler(c *fiber.Ctx) error { func settingsHandler(c *fiber.Ctx) error {
lang := c.Query("lang")
redirectURL := c.Query("redirect") redirectURL := c.Query("redirect")
if lang != "" {
c.Cookie(&fiber.Cookie{
Name: "language",
Value: lang,
Secure: false,
})
}
if redirectURL != "" { if redirectURL != "" {
lang := c.Query("lang")
logout := c.Query("logout")
if lang != "" {
c.Cookie(&fiber.Cookie{
Name: "language",
Value: lang,
Secure: false,
})
}
if logout == "true" {
c.ClearCookie("session", "state")
}
return c.Redirect(redirectURL) return c.Redirect(redirectURL)
} }
return nil
data := *web.Common(c)
data["Title"] = i18n.Translate(c, "settings")
return c.Render("settings", data, "layouts/base")
} }

View File

@ -2,9 +2,10 @@ package i18n
import ( import (
"encoding/json" "encoding/json"
"os"
"path/filepath" "path/filepath"
"strings"
"git.tijl.dev/tijl/tijl.dev/locales"
log "git.tijl.dev/tijl/tijl.dev/modules/logger" log "git.tijl.dev/tijl/tijl.dev/modules/logger"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
@ -16,28 +17,35 @@ const DefaultLang = "en"
func Load() { func Load() {
translations = make(map[string]map[string]string) translations = make(map[string]map[string]string)
dir := "locales" files, err := locales.Embed.ReadDir(".")
files, err := filepath.Glob(filepath.Join(dir, "*.json"))
if err != nil { if err != nil {
log.Fatal().Err(err) log.Fatal().Err(err)
} }
for _, file := range files { for _, file := range files {
lang := filepath.Base(file) if file.IsDir() {
lang = lang[:len(lang)-len(filepath.Ext(lang))] continue
}
file, err := os.Open(file)
if err != nil { if filepath.Ext(file.Name()) != ".json" {
log.Error().Err(err) continue
}
lang := strings.TrimSuffix(file.Name(), filepath.Ext(file.Name()))
data, err := locales.Embed.ReadFile(filepath.Join(".", file.Name()))
if err != nil {
log.Error().Err(err).Msg("Failed to read file")
continue continue
} }
defer file.Close()
var messages map[string]string var messages map[string]string
if err := json.NewDecoder(file).Decode(&messages); err != nil { if err := json.Unmarshal(data, &messages); err != nil {
log.Error().Err(err) log.Error().Err(err).Msg("Failed to decode JSON")
continue continue
} }
log.Debug().Str("lang", lang).Msg("i18n.Load: loaded")
translations[lang] = messages translations[lang] = messages
} }

View File

@ -7,7 +7,7 @@ import (
"net/http" "net/http"
"git.tijl.dev/tijl/tijl.dev/internal/db" "git.tijl.dev/tijl/tijl.dev/internal/db"
"git.tijl.dev/tijl/tijl.dev/internal/sessions" "git.tijl.dev/tijl/tijl.dev/internal/user"
"git.tijl.dev/tijl/tijl.dev/internal/utils" "git.tijl.dev/tijl/tijl.dev/internal/utils"
"git.tijl.dev/tijl/tijl.dev/modules/database" "git.tijl.dev/tijl/tijl.dev/modules/database"
log "git.tijl.dev/tijl/tijl.dev/modules/logger" log "git.tijl.dev/tijl/tijl.dev/modules/logger"
@ -73,7 +73,7 @@ func HandleCallback(c *fiber.Ctx) error {
return err return err
} }
_, err = sessions.NewSession(idToken.Subject, c) _, err = user.NewSession(idToken.Subject, c)
if err != nil { if err != nil {
return err return err
} }

View File

@ -13,7 +13,7 @@ import (
webinternal "git.tijl.dev/tijl/tijl.dev/internal/web" webinternal "git.tijl.dev/tijl/tijl.dev/internal/web"
"git.tijl.dev/tijl/tijl.dev/modules/logger" "git.tijl.dev/tijl/tijl.dev/modules/logger"
"git.tijl.dev/tijl/tijl.dev/modules/web" "git.tijl.dev/tijl/tijl.dev/modules/web"
"git.tijl.dev/tijl/tijl.dev/views" webf "git.tijl.dev/tijl/tijl.dev/web"
"github.com/gofiber/contrib/fiberzerolog" "github.com/gofiber/contrib/fiberzerolog"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/gofiber/template/html/v2" "github.com/gofiber/template/html/v2"
@ -41,7 +41,8 @@ func Listen() {
webinternal.Load() webinternal.Load()
// Init templating engine // Init templating engine
engine := html.NewFileSystem(http.FS(views.Embed), ".html") engine := html.NewFileSystem(http.FS(webf.ViewsEmbed), ".html")
engine.Directory = "views"
engine.AddFunc("icon", assets.Svg) engine.AddFunc("icon", assets.Svg)
// Init fiber // Init fiber

View File

@ -1,4 +1,4 @@
package sessions package user
import ( import (
"context" "context"

17
internal/user/users.go Normal file
View File

@ -0,0 +1,17 @@
package user
import (
"context"
"git.tijl.dev/tijl/tijl.dev/internal/db"
"git.tijl.dev/tijl/tijl.dev/modules/database"
)
func GetUser(uid string) (error, database.User) {
user, err := db.Queries.GetUser(context.TODO(), uid)
if err != nil {
return err, database.User{}
}
return nil, user
}

View File

@ -2,19 +2,20 @@ package web
import ( import (
"git.tijl.dev/tijl/tijl.dev/internal/i18n" "git.tijl.dev/tijl/tijl.dev/internal/i18n"
"git.tijl.dev/tijl/tijl.dev/internal/sessions" "git.tijl.dev/tijl/tijl.dev/internal/user"
"git.tijl.dev/tijl/tijl.dev/modules/web" "git.tijl.dev/tijl/tijl.dev/modules/web"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
func Load() { func Load() {
web.RegisterCommon(func(c *fiber.Ctx, m *fiber.Map) { web.RegisterCommon(func(c *fiber.Ctx, m *fiber.Map) {
_, err := sessions.GetSession(c) uid, err := user.GetSession(c)
signedIn := false signedIn := false
if err == nil { if err == nil {
signedIn = true signedIn = true
} }
(*m)["Uid"] = uid
(*m)["SignedIn"] = signedIn (*m)["SignedIn"] = signedIn
(*m)["Path"] = c.Path() (*m)["Path"] = c.Path()
(*m)["Language"] = i18n.GetLanguage(c) (*m)["Language"] = i18n.GetLanguage(c)

View File

@ -7,5 +7,7 @@
"dutch": "Dutch", "dutch": "Dutch",
"about": "About", "about": "About",
"projects": "Projects", "projects": "Projects",
"account": "Account" "account": "Account",
"login": "Login",
"settings": "Settings"
} }

View File

@ -7,5 +7,7 @@
"dutch": "Nederlands", "dutch": "Nederlands",
"about": "Over", "about": "Over",
"projects": "Projecten", "projects": "Projecten",
"account": "Account" "account": "Account",
"login": "Login",
"settings": "Instellingen"
} }

View File

@ -3,7 +3,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"build:css": "tailwindcss -i ./web/styles.css -o ./web/assets/static/css/styles.css --minify" "build:css": "tailwindcss -i ./web/lib/main.css -o ./web/static/css/styles.css --minify"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.14", "@tailwindcss/typography": "^0.5.14",

View File

@ -3,7 +3,7 @@ import { defineConfig } from "vite";
export default defineConfig({ export default defineConfig({
plugins: [], plugins: [],
build: { build: {
outDir: "web/assets/static/js", // Output directory for compiled JS outDir: "web/static/js", // Output directory for compiled JS
rollupOptions: { rollupOptions: {
output: { output: {
entryFileNames: "[name].js", entryFileNames: "[name].js",

View File

@ -1,9 +0,0 @@
package assets
import "embed"
//go:embed *
var Embed embed.FS
//go:embed static/*
var StaticEmbed embed.FS

11
web/embed.go Normal file
View File

@ -0,0 +1,11 @@
package web
import (
"embed"
)
//go:embed static/*
var StaticEmbed embed.FS
//go:embed views/*
var ViewsEmbed embed.FS

7
web/views/account.html Normal file
View File

@ -0,0 +1,7 @@
<div>
<div>id: {{.User.Uid}}</div>
<div>username: {{.User.Username}}</div>
<div>email: {{.User.Email}}</div>
<div>full name: {{.User.FullName}}</div>
<a class="btn btn-error" hx-boost="true" href="/settings?redirect=/&logout=true">Logout</a>
</div>

1
web/views/login.html Normal file
View File

@ -0,0 +1 @@
<a class="btn" href="/auth">Login with TT Authentication Services</a>

View File

@ -45,6 +45,7 @@
<span class="text-base">{{.T.about}}</span> <span class="text-base">{{.T.about}}</span>
</a> </a>
</li> </li>
<!--
<li class="flex-none"> <li class="flex-none">
<details class="dropdown"> <details class="dropdown">
<summary><a class="flex gap-4"> <summary><a class="flex gap-4">
@ -81,9 +82,10 @@
</ul> </ul>
</details> </details>
</li> </li>
-->
<li> <li>
{{if .SignedIn}} {{if .SignedIn}}
<a class="flex gap-4" href="/account"> <a class='flex gap-4 {{if eq .Path "/account"}}active{{end}}' href="/account">
<span class="w-5 text-center"> <span class="w-5 text-center">
{{icon "login"}} {{icon "login"}}
</span> </span>

1
web/views/settings.html Normal file
View File

@ -0,0 +1 @@
<div>hello</div>