add more templating and link-add page with js
This commit is contained in:
parent
24631a5b6a
commit
1aaa283396
14 changed files with 195 additions and 1704 deletions
|
@ -1,6 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"codeberg.org/lauralani/go-urlsh/internal/db"
|
||||
"codeberg.org/lauralani/go-urlsh/internal/misc"
|
||||
"codeberg.org/lauralani/go-urlsh/models"
|
||||
"context"
|
||||
|
@ -31,7 +32,11 @@ func HandleLinkGet(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
|
||||
|
||||
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.Status(200)
|
||||
c.Status(fiber.StatusCreated)
|
||||
c.JSON(newlink)
|
||||
|
||||
return nil
|
|
@ -54,6 +54,8 @@ func SetupFiber() error {
|
|||
fiberapp.Get("/admin/login", web.HandleAdminLoginGet)
|
||||
fiberapp.Post("/admin/login", web.HandleAdminLoginPost)
|
||||
|
||||
fiberapp.Get("/admin/link/add", web.HandleAdminLinkAddGet)
|
||||
|
||||
fiberapp.Static("/admin/", "./web")
|
||||
|
||||
v1 := fiberapp.Group("/api/v1")
|
||||
|
|
|
@ -10,6 +10,10 @@ import (
|
|||
//
|
||||
// Returns true if it's valid, false if not.
|
||||
func IsCookieValid(val string) bool {
|
||||
if val == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
count, err := models.DB.NewSelect().Model((*models.Login)(nil)).Where("cookie = ?", val).Count(context.Background())
|
||||
if err != nil {
|
||||
log.Printf("Error checking cookie validity for cookie %v\n", val)
|
||||
|
|
3
internal/misc/constants.go
Normal file
3
internal/misc/constants.go
Normal file
|
@ -0,0 +1,3 @@
|
|||
package misc
|
||||
|
||||
var CookieName = "gourlsh_auth"
|
7
internal/web/link.go
Normal file
7
internal/web/link.go
Normal 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)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"codeberg.org/lauralani/go-urlsh/internal/misc"
|
||||
"codeberg.org/lauralani/go-urlsh/models"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
|
@ -33,27 +34,27 @@ func HandleAdminLoginPost(c *fiber.Ctx) error {
|
|||
|
||||
expires := time.Now().Add(30 * 24 * time.Hour)
|
||||
key := uuid.New().String()
|
||||
login := new(models.Login)
|
||||
dblogin := new(models.Login)
|
||||
|
||||
cookie := new(fiber.Cookie)
|
||||
cookie.Name = "gourlsh_auth"
|
||||
cookie.Name = misc.CookieName
|
||||
cookie.Value = key
|
||||
cookie.Expires = expires
|
||||
|
||||
login.Expires = expires
|
||||
login.Cookie = key
|
||||
login.UserName = user.UserName
|
||||
dblogin.Expires = expires
|
||||
dblogin.Cookie = key
|
||||
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 {
|
||||
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")
|
||||
}
|
||||
|
||||
user.LastLogin = time.Now()
|
||||
_, err = models.DB.NewUpdate().Model(&user).WherePK().Exec(context.Background())
|
||||
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")
|
||||
}
|
||||
c.Cookie(cookie)
|
||||
|
|
|
@ -2,11 +2,12 @@ package web
|
|||
|
||||
import (
|
||||
"codeberg.org/lauralani/go-urlsh/internal/db"
|
||||
"codeberg.org/lauralani/go-urlsh/internal/misc"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func HandleAdminRootGet(c *fiber.Ctx) error {
|
||||
cookie := c.Cookies("gourlsh_auth")
|
||||
cookie := c.Cookies(misc.CookieName)
|
||||
if cookie == "" {
|
||||
c.Location("/admin/login")
|
||||
c.Status(fiber.StatusSeeOther)
|
||||
|
@ -20,7 +21,7 @@ func HandleAdminRootGet(c *fiber.Ctx) error {
|
|||
"Plat": "almost",
|
||||
})
|
||||
} else {
|
||||
c.ClearCookie("gourlsh_auth")
|
||||
c.ClearCookie(misc.CookieName)
|
||||
c.Location("/admin/login")
|
||||
c.Status(fiber.StatusSeeOther)
|
||||
return nil
|
||||
|
|
49
views/add_link.tmpl
Normal file
49
views/add_link.tmpl
Normal 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>
|
|
@ -1,11 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en_US">
|
||||
<html lang="en">
|
||||
<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">
|
||||
<link rel="stylesheet" href="/admin/simple.min/css">
|
||||
</head>
|
||||
<body>
|
||||
<h3 id="form-elements">Form elements</h3>
|
||||
|
@ -14,7 +14,7 @@
|
|||
<input type="text" name="username" id="username" placeholder="username">
|
||||
|
||||
<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">
|
||||
</form>
|
||||
|
|
49
web/add_link.html
Normal file
49
web/add_link.html
Normal 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>
|
|
@ -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
36
web/links.js
Normal 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
1
web/simple.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1689
web/water.css
1689
web/water.css
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue