More stuff for login and editor
This commit is contained in:
@@ -39,4 +39,29 @@ func (e Editor) LoginPage(w http.ResponseWriter, r *http.Request) {
|
|||||||
sendContent(w, r, string(dat), "", "")
|
sendContent(w, r, string(dat), "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Editor) Editor(w http.ResponseWriter, r *http.Request) {}
|
func (e Editor) Editor(w http.ResponseWriter, r *http.Request) {
|
||||||
|
hdr, err := back.ParseHeader(r)
|
||||||
|
if err == backend.ErrApiKeyUnauthorized || err == backend.ErrTokenUnauthorized || hdr == nil || hdr.User == nil {
|
||||||
|
if r.Header.Get("HX-Request") == "true" {
|
||||||
|
w.Header().Set("HX-Location", `{"path":"/login", "target":"#content"}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "text/html")
|
||||||
|
http.Redirect(w, r, "https://darkstorm.tech/login", http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
page, err := editorFS.Open("embed/editor.html")
|
||||||
|
defer page.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error getting editor.html:", err)
|
||||||
|
sendContent(w, r, "error getting page", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dat, err := io.ReadAll(page)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error reading editor.html:", err)
|
||||||
|
sendContent(w, r, "error getting page", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sendContent(w, r, string(dat), "", "")
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<p>THIS IS A POGGIES EDITOR. SAY WOW!</p>
|
||||||
|
|||||||
+3
-8
@@ -1,14 +1,9 @@
|
|||||||
<script src="https://unpkg.com/htmx-ext-json-enc@2.0.1/json-enc.js"></script>
|
<div id="invisiblePusher" hx-push-url="/editor"></div>
|
||||||
<script>
|
<form id="loginForm" onsubmit="login(event)">
|
||||||
document.addEventListener("htmx:beforeOnLoad", function (e) {
|
|
||||||
console.log(e);
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<form id="loginForm" hx-post="https://api.darkstorm.tech/user/login">
|
|
||||||
<label for="username">Username:</label>
|
<label for="username">Username:</label>
|
||||||
<input name="username" id="usernameInput"></input>
|
<input name="username" id="usernameInput"></input>
|
||||||
<label for="password">Password:</label>
|
<label for="password">Password:</label>
|
||||||
<input name="password" type="password" id="passwordInput"></input>
|
<input name="password" type="password" id="passwordInput"></input>
|
||||||
|
<p id="formResult"></p>
|
||||||
<button id="loginButton" type="submit">Login</button>
|
<button id="loginButton" type="submit">Login</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ func (b *Backend) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if r.Method == http.MethodOptions {
|
if r.Method == http.MethodOptions {
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "*")
|
w.Header().Set("Access-Control-Allow-Methods", "*")
|
||||||
w.Header().Set("Access-Control-Allow-Credentials", "true")
|
w.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||||
w.Header().Set("Access-Control-Allow-Headers", "*")
|
w.Header().Set("Access-Control-Allow-Headers", "*, Authorization")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.m.ServeHTTP(w, r)
|
b.m.ServeHTTP(w, r)
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ func (m *MongoTable[T]) Find(ctx context.Context, values map[string]any) ([]T, e
|
|||||||
}
|
}
|
||||||
var out []T
|
var out []T
|
||||||
err = res.All(ctx, &out)
|
err = res.All(ctx, &out)
|
||||||
|
if len(out) == 0 {
|
||||||
|
return nil, backend.ErrNotFound
|
||||||
|
}
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func (b *Backend) ParseHeader(r *http.Request) (*ParsedHeader, error) {
|
|||||||
}
|
}
|
||||||
out.Key = apiKey
|
out.Key = apiKey
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(r.Header.Get("origin"))
|
fmt.Println("origin:", r.Header.Get("origin"))
|
||||||
keys, err := b.keyTable.Find(r.Context(), map[string]any{"allowedOrigins": r.Header.Get("origin")})
|
keys, err := b.keyTable.Find(r.Context(), map[string]any{"allowedOrigins": r.Header.Get("origin")})
|
||||||
if err == ErrNotFound {
|
if err == ErrNotFound {
|
||||||
return nil, ErrApiKeyUnauthorized
|
return nil, ErrApiKeyUnauthorized
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package backend
|
package backend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
@@ -208,9 +210,10 @@ type loginRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type loginReturn struct {
|
type loginReturn struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
Timeout int64 `json:"timeout"`
|
ErrorMsg string `json:"errorMsg"`
|
||||||
|
Timeout int64 `json:"timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) login(w http.ResponseWriter, r *http.Request) {
|
func (b *Backend) login(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -234,6 +237,7 @@ func (b *Backend) login(w http.ResponseWriter, r *http.Request) {
|
|||||||
users, err := b.userTable.Find(r.Context(), map[string]any{"username": req.Username})
|
users, err := b.userTable.Find(r.Context(), map[string]any{"username": req.Username})
|
||||||
if errors.Is(err, ErrNotFound) || len(users) != 1 {
|
if errors.Is(err, ErrNotFound) || len(users) != 1 {
|
||||||
ret.Error = "invalid"
|
ret.Error = "invalid"
|
||||||
|
ret.ErrorMsg = "Incorrect username or password"
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
json.NewEncoder(w).Encode(ret)
|
json.NewEncoder(w).Encode(ret)
|
||||||
return
|
return
|
||||||
@@ -241,7 +245,8 @@ func (b *Backend) login(w http.ResponseWriter, r *http.Request) {
|
|||||||
u := users[0]
|
u := users[0]
|
||||||
if time.Unix(u.Timeout, 0).After(time.Now()) {
|
if time.Unix(u.Timeout, 0).After(time.Now()) {
|
||||||
ret.Error = "timeout"
|
ret.Error = "timeout"
|
||||||
ret.Timeout = time.Now().Unix() - u.Timeout
|
ret.Timeout = u.Timeout - time.Now().Unix()
|
||||||
|
ret.ErrorMsg = "Timed out for " + strconv.Itoa(int(ret.Timeout)) + " seconds"
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
json.NewEncoder(w).Encode(ret)
|
json.NewEncoder(w).Encode(ret)
|
||||||
return
|
return
|
||||||
@@ -260,8 +265,15 @@ func (b *Backend) login(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
json.NewEncoder(w).Encode(ret)
|
json.NewEncoder(w).Encode(ret)
|
||||||
|
if u.Fails != 0 {
|
||||||
|
err = b.userTable.PartUpdate(context.Background(), u.ID, map[string]any{"fails": 0})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error resetting fails after successful login:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret.Error = "invalid"
|
ret.Error = "invalid"
|
||||||
|
ret.ErrorMsg = "Incorrect username or password"
|
||||||
upd := map[string]any{"fails": u.Fails + 1}
|
upd := map[string]any{"fails": u.Fails + 1}
|
||||||
if (u.Fails+1)%3 == 0 {
|
if (u.Fails+1)%3 == 0 {
|
||||||
minutes := 3 ^ ((u.Fails / 3) - 1)
|
minutes := 3 ^ ((u.Fails / 3) - 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user