This commit is contained in:
Steven Tracey 2025-07-17 12:17:47 -04:00
parent 152adc8e3c
commit 7ddc339eba
5 changed files with 91 additions and 81 deletions

View File

@ -38,7 +38,7 @@
const path = window.location.pathname; const path = window.location.pathname;
const parts = path.split("/"); const parts = path.split("/");
const user = parts.pop(); const user = parts.pop();
let url = location.protocol + "//" + location.host + "/u/" + user; let url = location.protocol + "//" + location.host + "/u/" + user.toLowerCase();
const qrcode = new QRCode(document.getElementById('qr'), { const qrcode = new QRCode(document.getElementById('qr'), {
text: url, text: url,
@ -52,7 +52,7 @@
let qrLink = document.getElementById("qr-link"); let qrLink = document.getElementById("qr-link");
let qrImg = document.querySelector("#qr img"); let qrImg = document.querySelector("#qr img");
console.log(qrImg.src); console.log(qrImg.src);
qrLink.setAttribute("download", "qrcode-" + user + ".png"); qrLink.setAttribute("download", "qrcode-" + user.toLowerCase() + ".png");
const delay = ms => new Promise(res => setTimeout(res, ms)); const delay = ms => new Promise(res => setTimeout(res, ms));
const setHref = async () => { const setHref = async () => {

19
main.go
View File

@ -3,7 +3,6 @@ package main
import ( import (
"context" "context"
"github.com/gin-contrib/cors" "github.com/gin-contrib/cors"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"log" "log"
"os" "os"
@ -23,8 +22,8 @@ func main() {
r := gin.Default() r := gin.Default()
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
createSessionStore() //createSessionStore()
r.Use(sessions.Sessions("luggageinfo_session", sessionStore)) //r.Use(sessions.Sessions("luggageinfo_session", sessionStore))
createRateLimiters() createRateLimiters()
allowedOrigins := strings.Split(os.Getenv("CORS_ALLOWED_ORIGINS"), ",") allowedOrigins := strings.Split(os.Getenv("CORS_ALLOWED_ORIGINS"), ",")
@ -41,8 +40,8 @@ func main() {
r.LoadHTMLGlob("./templates/*") r.LoadHTMLGlob("./templates/*")
r.GET("/", htmlRL, webRoot) r.GET("/", htmlRL, webRoot)
r.GET("/register", htmlRL, webRegister) //r.GET("/register", htmlRL, webRegister)
r.GET("/register/success", htmlRL, webRegisterSuccess) //r.GET("/register/success", htmlRL, webRegisterSuccess)
r.GET("/qr/:user", htmlRL, webQr) r.GET("/qr/:user", htmlRL, webQr)
r.GET("/ping", webPing) r.GET("/ping", webPing)
@ -50,16 +49,16 @@ func main() {
api.GET("/u/:user", jsonRL, webUserApi) api.GET("/u/:user", jsonRL, webUserApi)
api.GET("/verify/:user", jsonRL, webVerifyUserApi) api.GET("/verify/:user", jsonRL, webVerifyUserApi)
api.GET("/checkname/:user", jsonRL, webCheckNameApi) api.GET("/checkname/:user", jsonRL, webCheckNameApi)
api.POST("/register", jsonRL, webRegisterApi) //api.POST("/register", jsonRL, webRegisterApi)
user := r.Group("/u") user := r.Group("/u")
user.GET("/:user", htmlRL, webUser) user.GET("/:user", htmlRL, webUser)
user.GET("/:user/info", htmlRL, webUserInfo) user.GET("/:user/info", htmlRL, webUserInfo)
auth := r.Group("/auth") //auth := r.Group("/auth")
auth.GET("/login", htmlRL, webLoginAuth) //auth.GET("/login", htmlRL, webLoginAuth)
auth.POST("/login", htmlRL, webLoginAuthPost) //auth.POST("/login", htmlRL, webLoginAuthPost)
auth.GET("/logout", htmlRL, webLogoutAuth) //auth.GET("/logout", htmlRL, webLogoutAuth)
err := r.Run() err := r.Run()
if err != nil { if err != nil {

View File

@ -1,4 +1,4 @@
const form = document.getElementById("reg-form"); // Replace #my-form with your form's ID const form = document.getElementById("reg-form");
form.addEventListener("submit", async (event) => { form.addEventListener("submit", async (event) => {
event.preventDefault(); event.preventDefault();

View File

@ -1,10 +1,10 @@
document.getElementById("submitBtn").addEventListener('click', function(e) { let submitBtn = document.getElementById("submitBtn");
let code = document.getElementById("code").value; submitBtn.addEventListener('click', function(e) {
console.log("Clicked: " + code); let code = document.getElementById("code").value.replaceAll(" ", "");
const path = window.location.pathname; const path = window.location.pathname;
const parts = path.split("/"); const parts = path.split("/");
const user = parts.pop(); const user = parts.pop().toLowerCase();
fetch("/api/verify/" + user, { fetch("/api/verify/" + user, {
method: 'GET', method: 'GET',
@ -15,8 +15,9 @@ document.getElementById("submitBtn").addEventListener('click', function(e) {
}).then(response => response.json()) }).then(response => response.json())
.then(data => { .then(data => {
let statusText = document.getElementById("status"); let statusText = document.getElementById("status");
console.log(data);
statusText.classList.remove("hidden"); statusText.classList.remove("hidden");
console.log("Status Code: " + data.status);
console.log("Code Type: " + typeof data.status)
if (data.status === 404) { if (data.status === 404) {
// Not found // Not found
statusText.innerText = "User with that code not found"; statusText.innerText = "User with that code not found";
@ -29,4 +30,10 @@ document.getElementById("submitBtn").addEventListener('click', function(e) {
statusText.innerText = "Error, please send this to Steven to be fixed. Error: " + data.error; statusText.innerText = "Error, please send this to Steven to be fixed. Error: " + data.error;
} }
}) })
}) });
document.getElementById("code").addEventListener('keyup', function(e) {
if (e.key === "Enter") {
submitBtn.click();
}
});

76
web.go
View File

@ -7,6 +7,7 @@ import (
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie" "github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"html/template"
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
@ -87,39 +88,41 @@ func webPing(c *gin.Context) {
} }
func webUserApi(c *gin.Context) { func webUserApi(c *gin.Context) {
user, err := db.queryUser(c.Param("user")) user, err := db.queryUser(strings.ToLower(c.Param("user")))
if user.CurrentToken == nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"status": 401,
"error": "Unauthorized",
})
} else if strings.Compare(c.Query("token"), *user.CurrentToken) == 0 {
if err != nil { if err != nil {
if errors.Is(err, NoEntriesFoundError) { if errors.Is(err, NoEntriesFoundError) {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{ c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"status": 401, "status": 401,
"error": "Unauthorized", "error": "Unauthorized",
}) })
} else { return
fmt.Printf("Error: %s\n", err) }
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"status": 500, "status": 500,
"error": err.Error(), "error": fmt.Sprintf("Internal Server Error: %s", err.Error()),
}) })
return
} }
} else { if user.CurrentToken == nil {
c.JSON(http.StatusOK, user)
}
} else {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{ c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"status": 401, "status": 401,
"error": "Unauthorized", "error": "Unauthorized",
}) })
return
} }
if strings.Compare(c.Query("token"), *user.CurrentToken) == 0 {
user.Status = 200
c.JSON(http.StatusOK, user)
return
}
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"status": 401,
"error": "Unauthorized",
})
} }
func webVerifyUserApi(c *gin.Context) { func webVerifyUserApi(c *gin.Context) {
user, err := db.queryUser(c.Param("user")) user, err := db.queryUser(strings.ToLower(c.Param("user")))
if err != nil { if err != nil {
if errors.Is(err, NoEntriesFoundError) { if errors.Is(err, NoEntriesFoundError) {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{ c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
@ -137,12 +140,11 @@ func webVerifyUserApi(c *gin.Context) {
}) })
return return
} }
codes := strings.Split(user.SecretCodes, "'") codes := strings.Split(user.SecretCodes, ",")
responded := false
for _, code := range codes {
codeHeader := c.GetHeader("Authorization") codeHeader := c.GetHeader("Authorization")
reqCodeRaw := strings.Split(codeHeader, " ") reqCodeRaw := strings.Split(codeHeader, " ")
reqCode := strings.ReplaceAll(reqCodeRaw[len(reqCodeRaw)-1], " ", "") reqCode := strings.ReplaceAll(reqCodeRaw[len(reqCodeRaw)-1], " ", "")
for _, code := range codes {
if strings.Compare(code, reqCode) == 0 { if strings.Compare(code, reqCode) == 0 {
token, err := GenerateToken(16) token, err := GenerateToken(16)
if err != nil { if err != nil {
@ -151,39 +153,31 @@ func webVerifyUserApi(c *gin.Context) {
"user": "", "user": "",
"error": err.Error(), "error": err.Error(),
}) })
responded = true
return return
} else { }
err = db.updateToken(user.UserName, token) err = db.updateToken(user.UserName, token) // TODO make a more robust system for authorizing info page
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{ c.JSON(http.StatusInternalServerError, gin.H{
"status": 500, "status": 500,
"user": "", "user": "",
"error": err.Error(), "error": err.Error(),
}) })
responded = true
return return
} else { }
user.Status = 200 user.Status = 200
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"status": 200,
"user": user.UserName, "user": user.UserName,
"error": "", "error": "",
"token": token, "token": token,
}) })
responded = true return
break
} }
} }
}
}
if !responded {
c.JSON(http.StatusNotFound, gin.H{ c.JSON(http.StatusNotFound, gin.H{
"status": "404", "status": 404,
"user": "", "user": "",
"error": "User not found", "error": "User not found",
}) })
}
} }
func webCheckNameApi(c *gin.Context) { func webCheckNameApi(c *gin.Context) {
@ -197,7 +191,7 @@ func webCheckNameApi(c *gin.Context) {
} }
anyMatch := false anyMatch := false
for _, user := range users { for _, user := range users {
if strings.Compare(user, c.Param("user")) == 0 { if strings.Compare(user, strings.ToLower(c.Param("user"))) == 0 {
anyMatch = true anyMatch = true
break break
} }
@ -242,11 +236,21 @@ func webUser(c *gin.Context) {
} }
func webUserInfo(c *gin.Context) { func webUserInfo(c *gin.Context) {
user, err := db.queryUser(c.Param("user")) user, err := db.queryUser(strings.ToLower(c.Param("user")))
if err != nil {
if errors.Is(err, NoEntriesFoundError) {
body := template.HTML("The user searched is not found, please try again.")
c.HTML(http.StatusNotFound, "base.html.tmpl", gin.H{
"header": "User Not Found",
"body": body,
})
return
}
}
if user.CurrentToken == nil { if user.CurrentToken == nil {
c.HTML(http.StatusUnauthorized, "base.html.tmpl", gin.H{ c.HTML(http.StatusUnauthorized, "base.html.tmpl", gin.H{
"header": "Unauthorized", "header": "Unauthorized",
"body": "You don't have the right token :/", "body": "You don't have the right token, please try again.",
}) })
return return
} }
@ -255,7 +259,7 @@ func webUserInfo(c *gin.Context) {
if errors.Is(err, NoEntriesFoundError) { if errors.Is(err, NoEntriesFoundError) {
c.HTML(http.StatusUnauthorized, "base.html.tmpl", gin.H{ c.HTML(http.StatusUnauthorized, "base.html.tmpl", gin.H{
"header": "Unauthorized", "header": "Unauthorized",
"body": "You don't have the right token :/", "body": "You don't have the right token, please try again.",
}) })
return return
} }