refactor javascript and fix minor bugs
This commit is contained in:
parent
545ade9c28
commit
2489406c08
17 changed files with 235 additions and 135 deletions
|
@ -7,3 +7,16 @@ services:
|
||||||
POSTGRES_PASSWORD: example
|
POSTGRES_PASSWORD: example
|
||||||
POSTGRES_USER: go-urlsh
|
POSTGRES_USER: go-urlsh
|
||||||
POSTGRES_DB: go-urlsh
|
POSTGRES_DB: go-urlsh
|
||||||
|
volumes:
|
||||||
|
- ./postgres-data:/var/lib/postgresql/data
|
||||||
|
go-urlsh:
|
||||||
|
image: codeberg.org/lauralani/go-urlsh:0.1
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 127.0.0.1:3000:3000
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
environment:
|
||||||
|
# format: postgresql://<username>:<password>@<database_ip>/<database>
|
||||||
|
DATABASE_URL: postgres://
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
BINDADDR=127.0.0.1
|
BINDADDR=127.0.0.1
|
||||||
|
|
||||||
# Port to bind to
|
# Port to bind to
|
||||||
# default: 2345
|
# default: 3000
|
||||||
PORT=2345
|
PORT=3000
|
||||||
|
|
||||||
# List of trusted proxy IPs separated by colons
|
# List of trusted proxy IPs separated by colons
|
||||||
# default: 127.0.0.1,::1
|
# default: 127.0.0.1,::1
|
||||||
TRUSTEDPROXIES=127.0.0.1,::1
|
# TRUSTEDPROXIES=127.0.0.1,::1
|
||||||
|
|
||||||
# Postgresql connection string
|
# Postgresql connection string
|
||||||
# format: postgresql://<username>:<password>@<database_ip>/todos?sslmode=verify-ca
|
# format: postgresql://<username>:<password>@<database_ip>/todos?sslmode=verify-ca
|
||||||
|
|
|
@ -13,6 +13,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleLinkGetAll(c *fiber.Ctx) error {
|
func HandleLinkGetAll(c *fiber.Ctx) error {
|
||||||
|
if !db.IsCookieValid(c.Cookies(misc.CookieName, "")) && !db.IsApiKeyValid(c.GetRespHeader("x-api-key", "")) {
|
||||||
|
return fiber.NewError(fiber.StatusUnauthorized, "401 Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
var links []models.Link
|
var links []models.Link
|
||||||
|
|
||||||
err := models.DB.NewSelect().Model(&links).Scan(context.Background())
|
err := models.DB.NewSelect().Model(&links).Scan(context.Background())
|
||||||
|
@ -23,7 +27,10 @@ func HandleLinkGetAll(c *fiber.Ctx) error {
|
||||||
for _, link := range links {
|
for _, link := range links {
|
||||||
log.Printf("id: %v, url: %v", link.ID, link.URL)
|
log.Printf("id: %v, url: %v", link.ID, link.URL)
|
||||||
}
|
}
|
||||||
c.JSON(links)
|
err = c.JSON(links)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +39,10 @@ func HandleLinkGet(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleLinkPost(c *fiber.Ctx) error {
|
func HandleLinkPost(c *fiber.Ctx) error {
|
||||||
if !db.IsCookieValid(c.Cookies(misc.CookieName, "")) {
|
if !db.IsCookieValid(c.Cookies(misc.CookieName, "")) && !db.IsApiKeyValid(c.GetRespHeader("x-api-key", "")) {
|
||||||
return fiber.NewError(fiber.StatusUnauthorized, "401 Unauthorized")
|
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)
|
||||||
|
@ -61,7 +67,11 @@ 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(fiber.StatusCreated)
|
c.Status(fiber.StatusCreated)
|
||||||
c.JSON(newlink)
|
|
||||||
|
err = c.JSON(newlink)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -92,5 +102,12 @@ func HandleLinkDelete(c *fiber.Ctx) error {
|
||||||
log.Println(err.Error())
|
log.Println(err.Error())
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error")
|
return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Status(fiber.StatusNoContent)
|
||||||
|
err = c.SendString("204 No Content")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
@ -34,7 +33,6 @@ func HandleUserPost(c *fiber.Ctx) error {
|
||||||
salt := misc.RandomString(15)
|
salt := misc.RandomString(15)
|
||||||
created := time.Now()
|
created := time.Now()
|
||||||
hashbytes := sha256.Sum256([]byte(salt + newuser.Password))
|
hashbytes := sha256.Sum256([]byte(salt + newuser.Password))
|
||||||
fmt.Printf("%x\n", hashbytes)
|
|
||||||
|
|
||||||
hash := hex.EncodeToString(hashbytes[:])
|
hash := hex.EncodeToString(hashbytes[:])
|
||||||
|
|
||||||
|
|
27
internal/db/apikey.go
Normal file
27
internal/db/apikey.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"codeberg.org/lauralani/go-urlsh/models"
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsApiKeyValid checks the database if ApiKey val is valid.
|
||||||
|
//
|
||||||
|
// Returns true if it's valid, false if not.
|
||||||
|
func IsApiKeyValid(val string) bool {
|
||||||
|
if val == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err := models.DB.NewSelect().Model((*models.ApiKey)(nil)).Where("key = ?", val).Count(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error checking apikey validity for key %v\n", val)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if count < 1 {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleAdminLinkNewGet(c *fiber.Ctx) error {
|
func HandleAdminLinkNewGet(c *fiber.Ctx) error {
|
||||||
|
if !db.IsCookieValid(c.Cookies(misc.CookieName, "")) {
|
||||||
|
c.Location("/admin/")
|
||||||
|
c.Status(fiber.StatusSeeOther)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return c.Render("add_link", nil)
|
return c.Render("add_link", nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
type ApiKey struct {
|
type ApiKey struct {
|
||||||
bun.BaseModel `bun:"table:apikeys"`
|
bun.BaseModel `bun:"table:apikeys"`
|
||||||
Key string `bun:"key,pk,type:uuid,default:gen_random_uuid()" json:"key,omitempty"`
|
Key string `bun:"key,pk,type:uuid,default:gen_random_uuid()" json:"key,omitempty"`
|
||||||
UserName string `bun:"username,notnull" json:"username"`
|
UserName string `bun:"username,notnull" json:"username,omitempty"`
|
||||||
Created time.Time `bun:"created,default:now()" json:"created"`
|
Created time.Time `bun:"created,default:now()" json:"created,omitempty"`
|
||||||
|
Description string `bun:"description,notnull" json:"description"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<main class="container" style="padding: 0">
|
<main class="container" style="padding: 0">
|
||||||
<form action="javascript:HandleSubmit();" style="margin: 0">
|
<form action="javascript:HandleLinkAddSubmit();" style="margin: 0">
|
||||||
<fieldset id="form_fields">
|
<fieldset id="form_fields">
|
||||||
<hgroup>
|
<hgroup>
|
||||||
<h1>Add new shortlink</h1>
|
<h1>Add new shortlink</h1>
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
||||||
|
|
||||||
<label for="link">Link <i style="color: red;">*</i></label>
|
<label for="link">Link <i style="color: red;">*</i></label>
|
||||||
<input type="text" name="link" id="link" placeholder="https://" onchange="HandleChange()">
|
<input type="text" name="link" id="link" placeholder="https://" onchange="HandleLinkFieldChange()">
|
||||||
|
|
||||||
<label for="description">Description</label>
|
<label for="description">Description</label>
|
||||||
<input type="text" name="description" id="description" placeholder="">
|
<input type="text" name="description" id="description" placeholder="">
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/pico.min.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
<link rel="stylesheet" href="/admin/custom.css">
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
<script src="/admin/link_add.js" defer></script>
|
<script src="/admin/main.js" defer></script>
|
||||||
<script src="/admin/misc.js" defer></script>
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/pico.min.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
<link rel="stylesheet" href="/admin/custom.css">
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
<script src="/admin/links.js" defer></script>
|
<script src="/admin/main.js" defer></script>
|
||||||
<script src="/admin/misc.js" defer></script>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
td {
|
td {
|
||||||
|
@ -54,7 +53,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
{{range .}}
|
{{range .}}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="javascript: HandleCopy('{{.ID}}');" data-tooltip="click to copy">{{.ID}}</a></td>
|
<td><a href="javascript: HandleLinkIndexCopy('{{.ID}}');" data-tooltip="click to copy">{{.ID}}</a></td>
|
||||||
<td><a href="{{.URL}}" target="_blank" {{if .Description}}data-tooltip="{{.Description}}"{{end}}>{{.URL}}</a></td>
|
<td><a href="{{.URL}}" target="_blank" {{if .Description}}data-tooltip="{{.Description}}"{{end}}>{{.URL}}</a></td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<a href="/admin/links/edit/{{.ID}}">
|
<a href="/admin/links/edit/{{.ID}}">
|
||||||
|
@ -62,7 +61,7 @@
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<a href="javascript: HandleDelete('{{.ID}}');">
|
<a href="javascript: HandleLinkIndexDelete('{{.ID}}');">
|
||||||
Delete
|
Delete
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<main class="container" style="padding: 0">
|
<main class="container" style="padding: 0">
|
||||||
<form action="javascript:HandleSubmit();" style="margin: 0">
|
<form action="javascript:HandleLinkAddSubmit();" style="margin: 0">
|
||||||
<fieldset id="form_fields">
|
<fieldset id="form_fields">
|
||||||
<hgroup>
|
<hgroup>
|
||||||
<h1>Add new shortlink</h1>
|
<h1>Add new shortlink</h1>
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
||||||
|
|
||||||
<label for="link">Link <i style="color: red;">*</i></label>
|
<label for="link">Link <i style="color: red;">*</i></label>
|
||||||
<input type="text" name="link" id="link" placeholder="https://" onchange="HandleChange()">
|
<input type="text" name="link" id="link" placeholder="https://" onchange="HandleLinkFieldChange()">
|
||||||
|
|
||||||
<label for="description">Description</label>
|
<label for="description">Description</label>
|
||||||
<input type="text" name="description" id="description" placeholder="">
|
<input type="text" name="description" id="description" placeholder="">
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
document.location = "/admin/"
|
|
||||||
}
|
|
||||||
|
|
||||||
async function HandleChange() {
|
|
||||||
console.log("HandleChange")
|
|
||||||
let buttonactive = true
|
|
||||||
if (document.getElementById("link").value === "")
|
|
||||||
{
|
|
||||||
buttonactive = false
|
|
||||||
}
|
|
||||||
document.getElementById("submit").active = buttonactive
|
|
||||||
}
|
|
|
@ -8,8 +8,7 @@
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/pico.min.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
<link rel="stylesheet" href="/admin/custom.css">
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
<script src="/admin/link_add.js" defer></script>
|
<script src="/admin/main.js" defer></script>
|
||||||
<script src="/admin/misc.js" defer></script>
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/pico.min.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
<link rel="stylesheet" href="/admin/custom.css">
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
<script src="/admin/links.js" defer></script>
|
<script src="/admin/main.js" defer></script>
|
||||||
<script src="/admin/misc.js" defer></script>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
td {
|
td {
|
||||||
|
@ -54,7 +53,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
{{range .}}
|
{{range .}}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="javascript: HandleCopy('{{.ID}}');" data-tooltip="click to copy">{{.ID}}</a></td>
|
<td><a href="javascript: HandleLinkIndexCopy('{{.ID}}');" data-tooltip="click to copy">{{.ID}}</a></td>
|
||||||
<td><a href="{{.URL}}" target="_blank" {{if .Description}}data-tooltip="{{.Description}}"{{end}}>{{.URL}}</a></td>
|
<td><a href="{{.URL}}" target="_blank" {{if .Description}}data-tooltip="{{.Description}}"{{end}}>{{.URL}}</a></td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<a href="/admin/links/edit/{{.ID}}">
|
<a href="/admin/links/edit/{{.ID}}">
|
||||||
|
@ -62,7 +61,7 @@
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
<a href="javascript: HandleDelete('{{.ID}}');">
|
<a href="javascript: HandleLinkIndexDelete('{{.ID}}');">
|
||||||
Delete
|
Delete
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
16
web/links.js
16
web/links.js
|
@ -1,16 +0,0 @@
|
||||||
async function HandleDelete(id){
|
|
||||||
let response = await fetch("/api/v1/links/" + id, {
|
|
||||||
credentials: "include",
|
|
||||||
mode: "same-origin",
|
|
||||||
method: "DELETE"
|
|
||||||
});
|
|
||||||
if (!response.ok) {
|
|
||||||
console.log("error deleting " + id + ": " + response.statusText)
|
|
||||||
}
|
|
||||||
document.location = "/admin/"
|
|
||||||
}
|
|
||||||
|
|
||||||
async function HandleCopy(id) {
|
|
||||||
let host = window.location.protocol + "//" + window.location.host;
|
|
||||||
await navigator.clipboard.writeText(host + "/" + id);
|
|
||||||
}
|
|
99
web/main.js
Normal file
99
web/main.js
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
// Link overview
|
||||||
|
|
||||||
|
async function HandleLinkIndexDelete(id){
|
||||||
|
let response = await fetch("/api/v1/links/" + id, {
|
||||||
|
credentials: "include",
|
||||||
|
mode: "same-origin",
|
||||||
|
method: "DELETE"
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
console.log("error deleting " + id + ": " + response.statusText)
|
||||||
|
}
|
||||||
|
document.location = "/admin/"
|
||||||
|
}
|
||||||
|
|
||||||
|
async function HandleLinkIndexCopy(id) {
|
||||||
|
let host = window.location.protocol + "//" + window.location.host;
|
||||||
|
await navigator.clipboard.writeText(host + "/" + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Link Add
|
||||||
|
|
||||||
|
async function HandleLinkAddSubmit() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
document.location = "/admin/"
|
||||||
|
}
|
||||||
|
|
||||||
|
async function HandleLinkFieldChange() {
|
||||||
|
console.log("HandleChange")
|
||||||
|
let buttonactive = true
|
||||||
|
if (document.getElementById("link").value === "")
|
||||||
|
{
|
||||||
|
buttonactive = false
|
||||||
|
}
|
||||||
|
document.getElementById("submit").active = buttonactive
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApiKey Add
|
||||||
|
|
||||||
|
async function HandleApiKeyNewSubmit() {
|
||||||
|
let button = document.getElementById("submit")
|
||||||
|
let description = document.getElementById("description")
|
||||||
|
button.active = false
|
||||||
|
button.setAttribute("aria-busy", "true")
|
||||||
|
|
||||||
|
let body = {
|
||||||
|
"description" : description
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = await fetch("/api/v1/apikeys", {
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
mode: "same-origin",
|
||||||
|
method: "POST"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let data = await response.json()
|
||||||
|
document.getElementById("dialog-heading").textContent = "New API-Key"
|
||||||
|
document.getElementById("dialog-text").textContent = "Here is your new API Key. Copy it NOW, it won't be shown again."
|
||||||
|
document.getElementById("dialog-apikey").textContent = data.key
|
||||||
|
document.getElementById('dialog-info').showModal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function HandleApiKeyModalClose() {
|
||||||
|
let modal = document.getElementById('dialog-info');
|
||||||
|
modal.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// General
|
||||||
|
|
||||||
|
function Logout() {
|
||||||
|
document.cookie = 'gourlsh_auth=; Max-Age=-1; path=/; domain=' + location.hostname;
|
||||||
|
document.location = "/admin/login"
|
||||||
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
function Logout() {
|
|
||||||
document.cookie = 'gourlsh_auth=; Max-Age=-1; path=/; domain=' + location.hostname;
|
|
||||||
document.location = "/admin/login"
|
|
||||||
}
|
|
Loading…
Reference in a new issue