Tested and created all endpoints, now entering production beta
This commit is contained in:
parent
c7bd5ad1f6
commit
6c46254988
|
@ -1 +1,3 @@
|
||||||
.idea
|
.idea
|
||||||
|
config.ini
|
||||||
|
tmp/
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
secretkey: supersecretkey
|
secretkey: supersecretkey
|
||||||
port: 8080
|
port: 8080
|
||||||
host: localhost
|
host: localhost
|
||||||
dblocation: /var/lib/maddy/credentials.db
|
dblocation: tmp/credentials.db
|
250
main.go
250
main.go
|
@ -5,9 +5,13 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"centrifuge.hectabit.org/HectaBit/captcha"
|
"centrifuge.hectabit.org/HectaBit/captcha"
|
||||||
|
@ -19,7 +23,7 @@ import (
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const salt_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
const salt_chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ23456789"
|
||||||
|
|
||||||
var DBLOCATION = "/var/lib/maddy/credentials.db"
|
var DBLOCATION = "/var/lib/maddy/credentials.db"
|
||||||
|
|
||||||
|
@ -51,11 +55,11 @@ func computeBcrypt(cost int, pass string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return string(hash), nil
|
return "bcrypt:" + string(hash), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyBcrypt(pass, hashSalt string) error {
|
func verifyBcrypt(hash, pass string) error {
|
||||||
return bcrypt.CompareHashAndPassword([]byte(hashSalt), []byte(pass))
|
return bcrypt.CompareHashAndPassword([]byte(strings.TrimPrefix(hash, "bcrypt:")), []byte(pass))
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -99,7 +103,7 @@ func main() {
|
||||||
c.Next()
|
c.Next()
|
||||||
})
|
})
|
||||||
|
|
||||||
router.GET("/login", func(c *gin.Context) {
|
router.GET("/signup", func(c *gin.Context) {
|
||||||
session := sessions.Default(c)
|
session := sessions.Default(c)
|
||||||
sessionid := genSalt(512)
|
sessionid := genSalt(512)
|
||||||
session.Options(sessions.Options{
|
session.Options(sessions.Options{
|
||||||
|
@ -107,7 +111,7 @@ func main() {
|
||||||
})
|
})
|
||||||
data, err := captcha.New(500, 100)
|
data, err := captcha.New(500, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[ERROR] Failed to generate captcha at", time.Now().Unix(), err)
|
fmt.Println("[ERROR] Failed to generate captcha at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
c.String(500, "Failed to generate captcha")
|
c.String(500, "Failed to generate captcha")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -115,39 +119,54 @@ func main() {
|
||||||
session.Set("id", sessionid)
|
session.Set("id", sessionid)
|
||||||
err = session.Save()
|
err = session.Save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[ERROR] Failed to save session in /login at", time.Now().Unix(), err)
|
fmt.Println("[ERROR] Failed to save session in /login at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
c.String(500, "Failed to save session")
|
c.String(500, "Failed to save session")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var b64bytes bytes.Buffer
|
var b64bytes bytes.Buffer
|
||||||
err = data.WriteImage(&b64bytes)
|
err = data.WriteImage(&b64bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[ERROR] Failed to encode captcha at", time.Now().Unix(), err)
|
fmt.Println("[ERROR] Failed to encode captcha at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
c.String(500, "Failed to encode captcha")
|
c.String(500, "Failed to encode captcha")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.HTML(200, "main.html", gin.H{
|
c.HTML(200, "signup.html", gin.H{
|
||||||
"captcha_image": base64.StdEncoding.EncodeToString(b64bytes.Bytes()),
|
"captcha_image": base64.StdEncoding.EncodeToString(b64bytes.Bytes()),
|
||||||
"unique_token": sessionid,
|
"unique_token": sessionid,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.GET("/account", func(c *gin.Context) {
|
||||||
|
loggedin, err := c.Cookie("loggedin")
|
||||||
|
if errors.Is(err, http.ErrNoCookie) || loggedin != "true" {
|
||||||
|
c.HTML(200, "login.html", gin.H{})
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
c.HTML(200, "dashboard.html", gin.H{})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
router.POST("/api/signup", func(c *gin.Context) {
|
router.POST("/api/signup", func(c *gin.Context) {
|
||||||
err := c.Request.ParseForm()
|
var data map[string]interface{}
|
||||||
|
err := c.ShouldBindJSON(&data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(400, "Failed to parse form")
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data := c.Request.Form
|
|
||||||
session := sessions.Default(c)
|
session := sessions.Default(c)
|
||||||
|
|
||||||
if data.Get("captcha") != session.Get("captcha") {
|
if data["unique_token"].(string) != session.Get("id") {
|
||||||
c.HTML(200, "badcaptcha.html", gin.H{})
|
c.HTML(403, "badtoken.html", gin.H{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.Get("unique_token") != session.Get("id") {
|
if data["captcha"].(string) != session.Get("captcha") {
|
||||||
c.HTML(200, "badtoken.html", gin.H{})
|
c.HTML(400, "badcaptcha.html", gin.H{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !regexp.MustCompile(`^[a-zA-Z0-9.]+$`).MatchString(data["username"].(string)) {
|
||||||
|
c.String(402, "Invalid username")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +175,7 @@ func main() {
|
||||||
|
|
||||||
err = session.Save()
|
err = session.Save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[ERROR] Failed to save session in /api/signup at", time.Now().Unix(), err)
|
fmt.Println("[ERROR] Failed to save session in /api/signup at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
c.String(500, "Failed to save session")
|
c.String(500, "Failed to save session")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -165,26 +184,211 @@ func main() {
|
||||||
defer func(conn *sql.DB) {
|
defer func(conn *sql.DB) {
|
||||||
err := conn.Close()
|
err := conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[ERROR] Failed to defer database connection at", time.Now().Unix(), err)
|
fmt.Println("[ERROR] Failed to defer database connection in /api/signup at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
c.String(500, "Failed to defer database connection")
|
c.String(500, "Failed to defer database connection")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}(conn)
|
}(conn)
|
||||||
|
|
||||||
hashedpass, err := computeBcrypt(10, data.Get("password"))
|
hashedpass, err := computeBcrypt(10, data["password"].(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[ERROR] Failed to hash password connection at", time.Now().Unix(), err)
|
fmt.Println("[ERROR] Failed to hash password in /api/signup at", time.Now().Unix(), err)
|
||||||
c.String(500, "Failed to hash password")
|
c.String(500, "Failed to hash password")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.Exec("INSERT INTO passwords (key, value) VALUES (?, ?)", data.Get("username"), hashedpass)
|
_, err = conn.Exec("INSERT INTO passwords (key, value) VALUES (?, ?)", data["username"].(string), hashedpass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HTML(500, "taken.html", gin.H{})
|
c.String(501, "Username taken")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.HTML(200, "postsignup.html", gin.H{})
|
c.String(200, "Success")
|
||||||
|
})
|
||||||
|
|
||||||
|
router.POST("/api/login", func(c *gin.Context) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
err := c.ShouldBindJSON(&data)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := get_db_connection()
|
||||||
|
defer func(conn *sql.DB) {
|
||||||
|
err := conn.Close()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to defer database connection at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to defer database connection")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(conn)
|
||||||
|
|
||||||
|
var rows string
|
||||||
|
err = conn.QueryRow("SELECT value FROM passwords WHERE key = ?", data["username"].(string)).Scan(&rows)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
c.String(401, "Invalid username")
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
fmt.Println("[ERROR] Failed to query database in /api/login at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to query database")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = verifyBcrypt(rows, data["password"].(string))
|
||||||
|
if err != nil {
|
||||||
|
c.String(403, "Password is incorrect")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, gin.H{"password": rows})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.POST("/api/deleteacct", func(c *gin.Context) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
err := c.ShouldBindJSON(&data)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := get_db_connection()
|
||||||
|
defer func(conn *sql.DB) {
|
||||||
|
err := conn.Close()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to defer database connection in /api/deleteacct at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to defer database connection")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(conn)
|
||||||
|
|
||||||
|
result, err := conn.Exec("DELETE FROM passwords WHERE key = ? AND value = ?", data["username"].(string), data["password"].(string))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to query database in /api/deleteacct at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to query database")
|
||||||
|
} else {
|
||||||
|
rowsaffected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to get rows affected in /api/deleteacct at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to get rows affected")
|
||||||
|
} else {
|
||||||
|
if rowsaffected == int64(0) {
|
||||||
|
c.String(401, "Invalid username or password")
|
||||||
|
} else {
|
||||||
|
c.String(200, "Success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.POST("/api/changepass", func(c *gin.Context) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
err := c.ShouldBindJSON(&data)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := get_db_connection()
|
||||||
|
defer func(conn *sql.DB) {
|
||||||
|
err := conn.Close()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to defer database connection in /api/changepass at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to defer database connection")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(conn)
|
||||||
|
|
||||||
|
newhash, err := computeBcrypt(10, data["newpass"].(string))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to hash password in /api/changepass at", time.Now().Unix(), err)
|
||||||
|
c.String(500, "Failed to hash password")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := conn.Exec("UPDATE passwords SET value = ? WHERE key = ? AND value = ?", newhash, data["username"].(string), data["password"].(string))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to query database in /api/changepass at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to query database")
|
||||||
|
} else {
|
||||||
|
rowsaffected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("[ERROR] Failed to get rows affected in /api/changepass at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
||||||
|
c.String(500, "Failed to get rows affected")
|
||||||
|
} else {
|
||||||
|
if rowsaffected == int64(0) {
|
||||||
|
c.String(401, "Invalid username or password")
|
||||||
|
} else {
|
||||||
|
c.JSON(200, gin.H{"password": newhash})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/account/logout", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "logout.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/account/deleteacct", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "deleteacct.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/account/changepass", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "changepass.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/usererror", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "usererror.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/accounterror", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "accounterror.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/badcaptcha", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "badcaptcha.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/signuperror", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "signuperror.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/loginerror", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "loginerror.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/invalidtoken", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "invalidtoken.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/invaliduser", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "invaliduser.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/badpassword", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "badpassword.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/baduser", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "baduser.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/success", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "success.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/taken", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "taken.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "index.html", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/cta", func(c *gin.Context) {
|
||||||
|
c.HTML(200, "cta.html", gin.H{})
|
||||||
})
|
})
|
||||||
|
|
||||||
fmt.Println("[INFO] Server started at", time.Now().Unix())
|
fmt.Println("[INFO] Server started at", time.Now().Unix())
|
||||||
|
|
|
@ -20,8 +20,6 @@ body.darkmode {
|
||||||
|
|
||||||
input {
|
input {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: var(--button);
|
|
||||||
color: white;
|
|
||||||
border-style: none;
|
border-style: none;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
|
@ -29,6 +27,11 @@ input {
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
text-decoration: none;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: var(--button);
|
background-color: var(--button);
|
||||||
border-style: none;
|
border-style: none;
|
||||||
|
@ -38,6 +41,19 @@ button {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logout {
|
||||||
|
display: block;
|
||||||
|
margin-top: 15px;
|
||||||
|
width: 65px;
|
||||||
|
margin-left: calc(50% - 45px);
|
||||||
|
z-index: 0;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
background-color: var(--header);
|
||||||
|
}
|
||||||
|
|
||||||
.pswdbox {
|
.pswdbox {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,18 @@ addEventListener("DOMContentLoaded", function () {
|
||||||
if (getCookie("darkMode") === "true") {
|
if (getCookie("darkMode") === "true") {
|
||||||
applyDarkMode();
|
applyDarkMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (document.getElementById("username")) {
|
||||||
|
document.getElementById("username").innerText = localStorage.getItem("user")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getElementById("logout")) {
|
||||||
|
document.getElementById("logout").innerText = "Currently logging out " + localStorage.getItem("user") + ", please be patient..."
|
||||||
|
localStorage.removeItem("user")
|
||||||
|
localStorage.removeItem("hash")
|
||||||
|
setCookie("loggedin", "false", 1, "Strict")
|
||||||
|
window.location.href = "/account"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function toggleDarkMode() {
|
function toggleDarkMode() {
|
||||||
|
@ -48,3 +60,117 @@ function getCookie(name) {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function signup() {
|
||||||
|
fetch("/api/signup", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
captcha: document.getElementById("captcha").value,
|
||||||
|
unique_token: document.getElementById("unique_token").value,
|
||||||
|
username: document.getElementById("username").value,
|
||||||
|
password: document.getElementById("password").value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => response)
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff() {
|
||||||
|
console.log(response.status)
|
||||||
|
if (response.status === 200) {
|
||||||
|
window.location.href = "/success"
|
||||||
|
} else if (response.status === 501) {
|
||||||
|
window.location.href = "/taken"
|
||||||
|
} else if (response.status === 400) {
|
||||||
|
window.location.href = "/badcaptcha"
|
||||||
|
} else if (response.status === 402) {
|
||||||
|
window.location.href = "/invaliduser"
|
||||||
|
} else if (response.status === 403) {
|
||||||
|
window.location.href = "/invalidtoken"
|
||||||
|
} else {
|
||||||
|
window.location.href = "/signuperror"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function login() {
|
||||||
|
let username = document.getElementById("username").value
|
||||||
|
fetch("/api/login", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
username: username,
|
||||||
|
password: document.getElementById("password").value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => response)
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff() {
|
||||||
|
console.log(response.status)
|
||||||
|
if (response.status === 200) {
|
||||||
|
setCookie("loggedin", "true", 30, "Strict")
|
||||||
|
const data = await response.json();
|
||||||
|
localStorage.setItem("user", username)
|
||||||
|
localStorage.setItem("hash", data.password)
|
||||||
|
window.location.reload()
|
||||||
|
} else if (response.status === 401) {
|
||||||
|
window.location.href = "/baduser"
|
||||||
|
} else if (response.status === 403) {
|
||||||
|
window.location.href = "/badpassword"
|
||||||
|
} else {
|
||||||
|
window.location.href = "/loginerror"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteacct() {
|
||||||
|
fetch("/api/deleteacct", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
username: localStorage.getItem("user"),
|
||||||
|
password: localStorage.getItem("hash")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => response)
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff() {
|
||||||
|
console.log(response.status)
|
||||||
|
if (response.status === 200) {
|
||||||
|
window.location.href = "/logout"
|
||||||
|
} else if (response.status === 401) {
|
||||||
|
window.location.href = "/usererror"
|
||||||
|
} else {
|
||||||
|
window.location.href = "/accounterror"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function changepass() {
|
||||||
|
fetch("/api/changepass", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
username: localStorage.getItem("user"),
|
||||||
|
password: localStorage.getItem("hash"),
|
||||||
|
newpass: document.getElementById("newpass").value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => response)
|
||||||
|
.then((response) => {
|
||||||
|
async function doStuff() {
|
||||||
|
console.log(response.status)
|
||||||
|
if (response.status === 200) {
|
||||||
|
const data = await response.json();
|
||||||
|
localStorage.setItem("hash", data.password)
|
||||||
|
window.location.href = "/account"
|
||||||
|
} else if (response.status === 401) {
|
||||||
|
window.location.href = "/usererror"
|
||||||
|
} else {
|
||||||
|
window.location.href = "/accounterror"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doStuff()
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,46 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"><head>
|
|
||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
||||||
<title>Sign Up</title>
|
|
||||||
<link rel="stylesheet" href="/static/css/main.css">
|
|
||||||
<script src="/static/js/main.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="headerbar">
|
|
||||||
<a class="a" href="/">CtaMail</a>
|
|
||||||
<a class="main a" href="/register">Sign up</a>
|
|
||||||
<a class="a" href="/account">Account</a>
|
|
||||||
<button class="a right" onclick="toggleDarkMode()">Toggle Theme</button>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<h1>Register an Email Account</h1>
|
|
||||||
<form method="POST" action="/api/signup">
|
|
||||||
<label>Username</label>
|
|
||||||
<div class="spacer">
|
|
||||||
<input type="text" name="username" required="">
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="Password">
|
|
||||||
<label>Password</label>
|
|
||||||
<div class="spacer">
|
|
||||||
<input type="password" name="password" required="">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div class="spacer">
|
|
||||||
<label>CAPTCHA</label>
|
|
||||||
<div class="spacer">
|
|
||||||
<img src="data:image/png;base64,{{ .captcha_image }}" alt="Captcha">
|
|
||||||
</div>
|
|
||||||
<div class="spacer">
|
|
||||||
<input required="" name="captcha" type="text">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<input type="hidden" name="unique_token" value="{{ .unique_token }}">
|
|
||||||
<input type="submit" value="Register">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Reference in New Issue