add more templating and link-add page with js

This commit is contained in:
Adora Laura Kalb 2023-04-27 19:03:28 +02:00
parent 24631a5b6a
commit 1aaa283396
Signed by: adoralaura
GPG key ID: 7A4552166FC8C056
14 changed files with 195 additions and 1704 deletions

View file

@ -1,6 +1,7 @@
package api package api
import ( import (
"codeberg.org/lauralani/go-urlsh/internal/db"
"codeberg.org/lauralani/go-urlsh/internal/misc" "codeberg.org/lauralani/go-urlsh/internal/misc"
"codeberg.org/lauralani/go-urlsh/models" "codeberg.org/lauralani/go-urlsh/models"
"context" "context"
@ -31,7 +32,11 @@ func HandleLinkGet(c *fiber.Ctx) error {
} }
func HandleLinkPost(c *fiber.Ctx) error { func HandleLinkPost(c *fiber.Ctx) error {
// TODO: Add Auth if !db.IsCookieValid(c.Cookies(misc.CookieName, "")) {
return fiber.NewError(fiber.StatusUnauthorized, "401 Unauthorized")
}
// TODO: Add API-Key Auth
var newlink models.Link var newlink models.Link
err := json.Unmarshal(c.Body(), &newlink) err := json.Unmarshal(c.Body(), &newlink)
@ -55,7 +60,7 @@ func HandleLinkPost(c *fiber.Ctx) error {
} }
c.Append("Location", c.BaseURL()+"/api/v1/links/"+newlink.ID) c.Append("Location", c.BaseURL()+"/api/v1/links/"+newlink.ID)
c.Status(200) c.Status(fiber.StatusCreated)
c.JSON(newlink) c.JSON(newlink)
return nil return nil

View file

@ -54,6 +54,8 @@ func SetupFiber() error {
fiberapp.Get("/admin/login", web.HandleAdminLoginGet) fiberapp.Get("/admin/login", web.HandleAdminLoginGet)
fiberapp.Post("/admin/login", web.HandleAdminLoginPost) fiberapp.Post("/admin/login", web.HandleAdminLoginPost)
fiberapp.Get("/admin/link/add", web.HandleAdminLinkAddGet)
fiberapp.Static("/admin/", "./web") fiberapp.Static("/admin/", "./web")
v1 := fiberapp.Group("/api/v1") v1 := fiberapp.Group("/api/v1")

View file

@ -10,6 +10,10 @@ import (
// //
// Returns true if it's valid, false if not. // Returns true if it's valid, false if not.
func IsCookieValid(val string) bool { func IsCookieValid(val string) bool {
if val == "" {
return false
}
count, err := models.DB.NewSelect().Model((*models.Login)(nil)).Where("cookie = ?", val).Count(context.Background()) count, err := models.DB.NewSelect().Model((*models.Login)(nil)).Where("cookie = ?", val).Count(context.Background())
if err != nil { if err != nil {
log.Printf("Error checking cookie validity for cookie %v\n", val) log.Printf("Error checking cookie validity for cookie %v\n", val)

View file

@ -0,0 +1,3 @@
package misc
var CookieName = "gourlsh_auth"

7
internal/web/link.go Normal file
View file

@ -0,0 +1,7 @@
package web
import "github.com/gofiber/fiber/v2"
func HandleAdminLinkAddGet(c *fiber.Ctx) error {
return c.Render("add_link", nil)
}

View file

@ -1,6 +1,7 @@
package web package web
import ( import (
"codeberg.org/lauralani/go-urlsh/internal/misc"
"codeberg.org/lauralani/go-urlsh/models" "codeberg.org/lauralani/go-urlsh/models"
"context" "context"
"crypto/sha256" "crypto/sha256"
@ -33,27 +34,27 @@ func HandleAdminLoginPost(c *fiber.Ctx) error {
expires := time.Now().Add(30 * 24 * time.Hour) expires := time.Now().Add(30 * 24 * time.Hour)
key := uuid.New().String() key := uuid.New().String()
login := new(models.Login) dblogin := new(models.Login)
cookie := new(fiber.Cookie) cookie := new(fiber.Cookie)
cookie.Name = "gourlsh_auth" cookie.Name = misc.CookieName
cookie.Value = key cookie.Value = key
cookie.Expires = expires cookie.Expires = expires
login.Expires = expires dblogin.Expires = expires
login.Cookie = key dblogin.Cookie = key
login.UserName = user.UserName dblogin.UserName = user.UserName
_, err = models.DB.NewInsert().Model(login).Exec(context.Background()) _, err = models.DB.NewInsert().Model(dblogin).Exec(context.Background())
if err != nil { if err != nil {
log.Printf("DB Error inserting login cookie information for user %v: %v\n", login.UserName, err.Error()) log.Printf("DB Error inserting login cookie information for user %v: %v\n", dblogin.UserName, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error") return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error")
} }
user.LastLogin = time.Now() user.LastLogin = time.Now()
_, err = models.DB.NewUpdate().Model(&user).WherePK().Exec(context.Background()) _, err = models.DB.NewUpdate().Model(&user).WherePK().Exec(context.Background())
if err != nil { if err != nil {
log.Printf("DB Error updating last login information for user %v: %v\n", login.UserName, err.Error()) log.Printf("DB Error updating last login information for user %v: %v\n", dblogin.UserName, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error") return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error")
} }
c.Cookie(cookie) c.Cookie(cookie)

View file

@ -2,11 +2,12 @@ package web
import ( import (
"codeberg.org/lauralani/go-urlsh/internal/db" "codeberg.org/lauralani/go-urlsh/internal/db"
"codeberg.org/lauralani/go-urlsh/internal/misc"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
func HandleAdminRootGet(c *fiber.Ctx) error { func HandleAdminRootGet(c *fiber.Ctx) error {
cookie := c.Cookies("gourlsh_auth") cookie := c.Cookies(misc.CookieName)
if cookie == "" { if cookie == "" {
c.Location("/admin/login") c.Location("/admin/login")
c.Status(fiber.StatusSeeOther) c.Status(fiber.StatusSeeOther)
@ -20,7 +21,7 @@ func HandleAdminRootGet(c *fiber.Ctx) error {
"Plat": "almost", "Plat": "almost",
}) })
} else { } else {
c.ClearCookie("gourlsh_auth") c.ClearCookie(misc.CookieName)
c.Location("/admin/login") c.Location("/admin/login")
c.Status(fiber.StatusSeeOther) c.Status(fiber.StatusSeeOther)
return nil return nil

49
views/add_link.tmpl Normal file
View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Add new Shortlink - go-urlsh</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" href="/admin/simple.min.css">
</head>
<body>
<form action="javascript:void(0);" style="margin-top: 2em">
<fieldset id="form_fields">
<legend>Add a new Shortlink</legend>
<p>* shows a required field</p>
<label for="linkname">Shortlink Name (leave empty for random)</label>
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
<label for="link">Link *</label>
<input type="text" name="link" id="link" placeholder="https://" style="width: 100%" onchange="HandleChange()">
<label for="description">Description</label>
<input type="text" name="description" id="description" placeholder="" style="width: 100%">
<input type="submit" id="submit" value="Login" onclick="HandleSubmit()">
</fieldset>
<dialog id="dialog-info">
<h2 id="dialog-heading"></h2>
<p id="dialog-text"></p>
<form method="dialog">
<button>Close</button>
</form>
</dialog>
</form>
<footer>
<p>go-urlsh - <a href="/">Home</a> -
<a href="https://codeberg.org/lauralani/go-urlsh" target="_blank">Source Code</a> -
<a href="https://codeberg.org/lauralani/go-urlsh/src/branch/main/LICENSE" target="_blank">License</a>
</p>
</footer>
<script src="/admin/links.js"></script>
</body>
</html>

View file

@ -1,11 +1,11 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en_US"> <html lang="en">
<head> <head>
<meta charset='utf-8'> <meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'> <meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title> <title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'> <meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css"> <link rel="stylesheet" href="/admin/simple.min/css">
</head> </head>
<body> <body>
<h3 id="form-elements">Form elements</h3> <h3 id="form-elements">Form elements</h3>
@ -14,7 +14,7 @@
<input type="text" name="username" id="username" placeholder="username"> <input type="text" name="username" id="username" placeholder="username">
<label for="password">Password</label> <label for="password">Password</label>
<input type="text" name="password" id="password" placeholder="password"> <input type="hidden" name="password" id="password" placeholder="password">
<input type="submit" value="Login"> <input type="submit" value="Login">
</form> </form>

49
web/add_link.html Normal file
View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Add new Shortlink - go-urlsh</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" href="/admin/simple.min.css">
</head>
<body>
<form action="javascript:void(0);" style="margin-top: 2em">
<fieldset id="form_fields">
<legend>Add a new Shortlink</legend>
<p>* shows a required field</p>
<label for="linkname">Shortlink Name (leave empty for random)</label>
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
<label for="link">Link *</label>
<input type="text" name="link" id="link" placeholder="https://" style="width: 100%" onchange="HandleChange()">
<label for="description">Description</label>
<input type="text" name="description" id="description" placeholder="" style="width: 100%">
<input type="submit" id="submit" value="Login" onclick="HandleSubmit()" disabled>
</fieldset>
<dialog id="dialog-info">
<h2 id="dialog-heading"></h2>
<p id="dialog-text"></p>
<form method="dialog">
<button>Close</button>
</form>
</dialog>
</form>
<footer>
<p>go-urlsh - <a href="/">Home</a> -
<a href="https://codeberg.org/lauralani/go-urlsh" target="_blank">Source Code</a> -
<a href="https://codeberg.org/lauralani/go-urlsh/src/branch/main/LICENSE" target="_blank">License</a>
</p>
</footer>
<script src="/admin/links.js"></script>
</body>
</html>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en_US">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
</head>
<body>
<h3 id="form-elements">Form elements</h3>
<form method="post" action="/admin/login">
<label for="username">Username</label>
<input type="text" name="username" id="username" placeholder="username">
<label for="password">Password</label>
<input type="hidden" name="password" id="password" placeholder="password">
<input type="submit" value="Login">
</form>
</body>
</html>

36
web/links.js Normal file
View file

@ -0,0 +1,36 @@
async function HandleSubmit() {
document.getElementById("submit").active = false
let slug = document.getElementById("linkname").value
let url = document.getElementById("link").value
let description = document.getElementById("description").value
let body = {
"id" : slug,
"url" : url,
"description" : description
}
let response = await fetch("/api/v1/links", {
credentials: "include",
body: JSON.stringify(body),
mode: "same-origin",
method: "POST"
});
if (!response.ok) {
document.getElementById("dialog-heading").textContent = "Error"
document.getElementById("dialog-text").textContent = "The following error occured during the request: " + response.statusText
document.getElementById('dialog-info').showModal()
document.getElementById("submit").active = true
}
}
async function HandleChange() {
console.log("HandleChange")
let buttonactive = true
if (document.getElementById("link").value === "")
{
buttonactive = false
}
document.getElementById("submit").active = buttonactive
}

1
web/simple.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff