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
|
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
|
|
@ -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")
|
||||||
|
|
|
@ -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)
|
||||||
|
|
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
|
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)
|
||||||
|
|
|
@ -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
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>
|
<!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
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