Compare commits

..

No commits in common. "3752648c782d1a46a117193f19e15187b136cf5e" and "7dfa018fe60d322212fe00ad8975ac4db8c8df5b" have entirely different histories.

1 changed files with 92 additions and 39 deletions

131
main.go
View File

@ -12,11 +12,13 @@ import (
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"log"
"math/big"
"net/http"
"os"
"regexp"
"strconv"
@ -146,13 +148,13 @@ func checkUsernameTaken(username string) (int, bool, error) {
err := conn.QueryRow("SELECT id FROM users WHERE lower(username) = ? LIMIT 1", username).Scan(&id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return 0, true, nil
return 0, false, nil
} else {
return 0, true, err
}
}
return id, false, nil
return id, true, nil
}
func init_db() {
@ -305,6 +307,12 @@ func main() {
gin.SetMode(gin.ReleaseMode)
router := gin.New()
store := cookie.NewStore([]byte(SECRET_KEY))
store.Options(sessions.Options{
MaxAge: 300,
HttpOnly: true,
Secure: true,
SameSite: 3,
})
router.Use(sessions.Sessions("currentSession", store))
// Enable CORS
@ -813,6 +821,8 @@ func main() {
nonce := c.Request.URL.Query().Get("nonce")
deny := c.Request.URL.Query().Get("deny")
session := sessions.Default(c)
var appIdCheck, redirectUriCheck string
err := conn.QueryRow("SELECT appId, rdiruri FROM oauth WHERE appId = ? LIMIT 1", appId).Scan(&appIdCheck, &redirectUriCheck)
@ -852,13 +862,13 @@ func main() {
}
}
_, userid, err := getSession(secretKey)
_, userId, err := getSession(secretKey)
if err != nil {
c.String(401, "Invalid session")
return
}
_, username, _, sub, err := getUser(userid)
_, username, _, sub, err := getUser(userId)
if errors.Is(err, sql.ErrNoRows) {
c.String(400, "User does not exist")
return
@ -890,38 +900,58 @@ func main() {
tokenTemp := jwt.NewWithClaims(jwt.SigningMethodRS256, dataTemplate)
tokenTemp.Header["kid"] = "burgerauth"
jwt_token, err := tokenTemp.SignedString(privateKey)
openIdToken, err := tokenTemp.SignedString(privateKey)
if err != nil {
log.Println("[ERROR] Unknown in /api/auth jwt_token at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
log.Println("[ERROR] Unknown in /api/auth openIdToken at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.String(500, "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-AUTH-JWTCANNOTSIGN")
return
}
secretTemp := jwt.NewWithClaims(jwt.SigningMethodRS256, dataTemplateTwo)
secretTemp.Header["kid"] = "burgerauth"
secret_token, err := secretTemp.SignedString(privateKey)
oauthToken, err := secretTemp.SignedString(privateKey)
if err != nil {
log.Println("[ERROR] Unknown in /api/auth secret_token at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
log.Println("[ERROR] Unknown in /api/auth oauthToken at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.String(500, "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-AUTH-JWTCANNOTSIGN.")
return
}
randomBytes, err := genSalt(512)
exchangeKey, err := genSalt(512)
if err != nil {
log.Println("[ERROR] Unknown in /api/auth randomBytes at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
log.Println("[ERROR] Unknown in /api/auth exchangeKey at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.String(500, "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-AUTH-RANDOMBYTES.")
return
}
_, err = conn.Exec("INSERT INTO logins (appId, secret, nextsecret, code, nextcode, creator, openid, nextopenid, pkce, pkcemethod) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", appId, randomBytes, "none", secret_token, "none", userid, jwt_token, "none", code, codeMethod)
sessionInfo := map[string]any{
"iat": time.Now().Unix(),
"session": secretKey,
"appId": appId,
"exchangeKey": exchangeKey,
"creator": userId,
"PKCECode": code,
"PKCEMethod": codeMethod,
}
c.SetSameSite(3)
c.SetCookie("oauthToken", oauthToken, 300, "/", "", true, true)
c.SetCookie("openIdToken", openIdToken, 300, "/", "", true, true)
sessionInfoStr, err := json.Marshal(sessionInfo)
if err != nil {
log.Println("[ERROR] Unknown in /api/auth insert at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.String(500, "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-AUTH-INSERT.")
log.Println("[ERROR] Unknown in /api/auth sessionInfoStr at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.String(500, "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-AUTH-SESSIONINFO.")
return
}
session.Set("activeLogin", sessionInfoStr)
err = session.Save()
if err != nil {
log.Println("[ERROR] Client-Server unknown in /api/auth session save at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.String(400, "Something went wrong, but we don't know who's fault it is (because we are mean coders, the error code says it's yours). If you deliberately caused this error (well done), please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and give us more info on how it happened. Your error code is: UNKNOWN-API-AUTH-SESSIONSAVE.")
return
}
if randomBytes != "" {
c.Redirect(302, redirect_uri+"?code="+randomBytes+"&state="+state)
if exchangeKey != "" {
c.Redirect(302, redirect_uri+"?code="+exchangeKey+"&state="+state)
} else {
c.String(500, "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-AUTH-REDIRECT.")
log.Println("[ERROR] Secret key not found at", strconv.FormatInt(time.Now().Unix(), 10))
@ -941,6 +971,8 @@ func main() {
code_verify := data.Get("code_verifier")
secret := data.Get("client_secret")
session := sessions.Default(c)
var verifyCode bool
if code_verify == "" {
verifyCode = false
@ -948,9 +980,8 @@ func main() {
verifyCode = true
}
var appIdCheck, secretCheck, openid, loginCode, PKCECode, PKCEMethod string
err = conn.QueryRow("SELECT o.appId, o.secret, l.openid, l.code, l.pkce, l.pkcemethod FROM oauth AS o JOIN logins AS l ON o.appId = l.appId WHERE o.appId = ? AND l.secret = ? LIMIT 1;", appId, code).Scan(&appIdCheck, &secretCheck, &openid, &loginCode, &PKCECode, &PKCEMethod)
var appIdCheck, secretCheck string
err = conn.QueryRow("SELECT appId, secret FROM oauth WHERE appId = ? LIMIT 1;", appId).Scan(&appIdCheck, &secretCheck)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
c.JSON(401, gin.H{"error": "OAuth screening failed"})
@ -965,6 +996,44 @@ func main() {
return
}
activeLogin := session.Get("activeLogin")
if activeLogin == nil {
c.JSON(401, gin.H{"error": "The token has expired or was never created"})
return
}
var activeLoginMap map[string]any
err = json.Unmarshal([]byte(activeLogin.(string)), &activeLoginMap)
PKCECode, PKCEMethod, loginCode := activeLoginMap["PKCECode"].(string), activeLoginMap["PKCEMethod"].(string), activeLoginMap["exchangeKey"].(string)
if loginCode != code {
c.JSON(401, gin.H{"error": "Another login attempt is in progress or the login was never started"})
return
}
oauthCode, err := c.Cookie("oauthToken")
if err != nil {
if errors.Is(err, http.ErrNoCookie) {
c.JSON(401, gin.H{"error": "The token has expired or was never created"})
return
} else {
log.Println("[ERROR] Unknown in /api/tokenauth oauth cookie at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-TOKENAUTH-OAUTHTOKEN"})
return
}
}
openid, err := c.Cookie("openIdToken")
if err != nil {
if errors.Is(err, http.ErrNoCookie) {
c.JSON(401, gin.H{"error": "The token has expired or was never created"})
return
} else {
log.Println("[ERROR] Unknown in /api/tokenauth openid cookie at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-TOKENAUTH-OAUTHTOKEN"})
return
}
}
if verifyCode {
if PKCECode == "none" {
c.JSON(400, gin.H{"error": "Attempted PKCECode exchange with non-PKCECode authentication"})
@ -972,16 +1041,16 @@ func main() {
} else {
if PKCEMethod == "S256" {
if sha256Base64(code_verify) != PKCECode {
c.JSON(403, gin.H{"error": "Invalid PKCECode code"})
c.JSON(403, gin.H{"error": "Invalid PKCECode"})
return
}
} else if PKCEMethod == "plain" {
if code_verify != PKCECode {
c.JSON(403, gin.H{"error": "Invalid PKCECode code"})
c.JSON(403, gin.H{"error": "Invalid PKCECode"})
return
}
} else {
c.JSON(403, gin.H{"error": "Attempted PKCECode exchange without supported PKCECode token method"})
c.JSON(403, gin.H{"error": "Attempted PKCECode exchange without supported PKCECode verification method"})
return
}
}
@ -992,14 +1061,7 @@ func main() {
}
}
_, err = conn.Exec("DELETE FROM logins WHERE code = ?", loginCode)
if err != nil {
log.Println("[ERROR] Unknown in /api/tokenauth delete at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-TOKENAUTH-DELETE"})
return
}
c.JSON(200, gin.H{"access_token": loginCode, "token_type": "bearer", "expires_in": 2592000, "id_token": openid})
c.JSON(200, gin.H{"access_token": oauthCode, "token_type": "bearer", "expires_in": 2592000, "id_token": openid})
})
router.POST("/api/deleteauth", func(c *gin.Context) {
@ -1188,15 +1250,6 @@ func main() {
}
}
_, err = conn.Exec("DELETE FROM logins WHERE creator = ?", id)
if err != nil {
if !errors.Is(err, sql.ErrNoRows) {
log.Println("[ERROR] Unknown in /api/deleteaccount logins at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-DELETEACCT-LOGINS"})
return
}
}
_, err = conn.Exec("DELETE FROM oauth WHERE creator = ?", id)
if err != nil {
if !errors.Is(err, sql.ErrNoRows) {
@ -1209,7 +1262,7 @@ func main() {
_, err = conn.Exec("DELETE FROM users WHERE id = ?", id)
if err != nil {
if !errors.Is(err, sql.ErrNoRows) {
log.Println("[ERROR] Unknown in /api/deleteuser logins at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
log.Println("[ERROR] Unknown in /api/deleteuser users at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgerauth and refer to the docs for more info. Your error code is: UNKNOWN-API-DELETEUSER-USERS"})
return
}