Clean up and refactoring.
This commit is contained in:
		
							parent
							
								
									a107b4f255
								
							
						
					
					
						commit
						5f86ac99ac
					
				
					 27 changed files with 657 additions and 1344 deletions
				
			
		
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -4,8 +4,5 @@
 | 
				
			||||||
# Ignore db/, don't commit the database.
 | 
					# Ignore db/, don't commit the database.
 | 
				
			||||||
*.db
 | 
					*.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Ignore node_modules.
 | 
					# Ignore debug files
 | 
				
			||||||
**/node_modules/*
 | 
					**/__debug*
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Ignore public css, should be generated in build process.
 | 
					 | 
				
			||||||
public/css/style.css
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Use IntelliSense to learn about possible attributes.
 | 
				
			||||||
 | 
					    // Hover to view descriptions of existing attributes.
 | 
				
			||||||
 | 
					    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
 | 
				
			||||||
 | 
					    "version": "0.2.0",
 | 
				
			||||||
 | 
					    "configurations": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "Launch API Server",
 | 
				
			||||||
 | 
					            "type": "go",
 | 
				
			||||||
 | 
					            "request": "launch",
 | 
				
			||||||
 | 
					            "mode": "debug",
 | 
				
			||||||
 | 
					            "program": "${workspaceFolder}/src/gin-cpularp.go",
 | 
				
			||||||
 | 
					            "cwd": "${workspaceFolder}/src"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
								
							| 
						 | 
					@ -1,3 +1,22 @@
 | 
				
			||||||
# CPULarp MyLarp Clone
 | 
					# CPULarp Manager API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We making our own MyLarp.
 | 
					The back end for what will soon be a manager webapp for CPULarp.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You need to rename the sample config.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					mv config.sample.toml config.toml
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then, add your OAuth credentials for your Discord App.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Usage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I'm pretty sure you can just run the package and it'll figure itself out.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```golang
 | 
				
			||||||
 | 
					cd src/
 | 
				
			||||||
 | 
					go run gin-cpularp.go
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										254
									
								
								gin-cpularp.go
									
									
									
									
									
								
							
							
						
						
									
										254
									
								
								gin-cpularp.go
									
									
									
									
									
								
							| 
						 | 
					@ -1,254 +0,0 @@
 | 
				
			||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"example.com/lib/dbcommands"
 | 
					 | 
				
			||||||
	"github.com/gin-gonic/gin"
 | 
					 | 
				
			||||||
	"github.com/pelletier/go-toml/v2"
 | 
					 | 
				
			||||||
	"github.com/ravener/discord-oauth2"
 | 
					 | 
				
			||||||
	"github.com/xyproto/randomstring"
 | 
					 | 
				
			||||||
	"golang.org/x/oauth2"
 | 
					 | 
				
			||||||
	"gorm.io/gorm"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type appConfig struct {
 | 
					 | 
				
			||||||
	API struct {
 | 
					 | 
				
			||||||
		Domain string
 | 
					 | 
				
			||||||
		Port   string
 | 
					 | 
				
			||||||
		Https  bool
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	OAuth struct {
 | 
					 | 
				
			||||||
		ClientID     string
 | 
					 | 
				
			||||||
		ClientSecret string
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type discordUser struct {
 | 
					 | 
				
			||||||
	Id                     string
 | 
					 | 
				
			||||||
	Username               string
 | 
					 | 
				
			||||||
	Avatar                 string
 | 
					 | 
				
			||||||
	Discriminator          string
 | 
					 | 
				
			||||||
	Public_Flags           float64
 | 
					 | 
				
			||||||
	Flags                  float64
 | 
					 | 
				
			||||||
	Banner                 string
 | 
					 | 
				
			||||||
	Accent_Color           float64
 | 
					 | 
				
			||||||
	Global_Name            string
 | 
					 | 
				
			||||||
	Avatar_Decoration_Data struct {
 | 
					 | 
				
			||||||
		Asset      string
 | 
					 | 
				
			||||||
		Sku_Id     string
 | 
					 | 
				
			||||||
		Expires_At string
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	Collectibles  string
 | 
					 | 
				
			||||||
	Banner_Color  string
 | 
					 | 
				
			||||||
	Clan          string
 | 
					 | 
				
			||||||
	Primary_Guild string
 | 
					 | 
				
			||||||
	Mfa_Eneabled  bool
 | 
					 | 
				
			||||||
	Locale        string
 | 
					 | 
				
			||||||
	Premium_Type  float64
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var db *gorm.DB
 | 
					 | 
				
			||||||
var config appConfig
 | 
					 | 
				
			||||||
var oauthConfig *oauth2.Config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func parseConfig(configPath string) appConfig {
 | 
					 | 
				
			||||||
	configFile, err := os.Open(configPath)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	configFileContent, err := io.ReadAll(configFile)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var configObject appConfig
 | 
					 | 
				
			||||||
	err = toml.Unmarshal(configFileContent, &configObject)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return configObject
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func createDiscordOAuthConfig() *oauth2.Config {
 | 
					 | 
				
			||||||
	protocolString := ""
 | 
					 | 
				
			||||||
	if config.API.Https {
 | 
					 | 
				
			||||||
		protocolString = "https://"
 | 
					 | 
				
			||||||
		config.API.Port = ""
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		protocolString = "http://"
 | 
					 | 
				
			||||||
		config.API.Port = fmt.Sprintf(":%s", config.API.Port)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	redirectUrlString := fmt.Sprintf("%s%s%s/auth/callback", protocolString, config.API.Domain, config.API.Port)
 | 
					 | 
				
			||||||
	config := &oauth2.Config{
 | 
					 | 
				
			||||||
		ClientID:     config.OAuth.ClientID,
 | 
					 | 
				
			||||||
		ClientSecret: config.OAuth.ClientSecret,
 | 
					 | 
				
			||||||
		RedirectURL:  redirectUrlString,
 | 
					 | 
				
			||||||
		Scopes:       []string{discord.ScopeIdentify},
 | 
					 | 
				
			||||||
		Endpoint:     discord.Endpoint,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return config
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func loginRedirect(context *gin.Context) {
 | 
					 | 
				
			||||||
	context.Redirect(302, oauthConfig.AuthCodeURL(context.GetString("state")))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func logoutRedirect(context *gin.Context) {
 | 
					 | 
				
			||||||
	oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		dbcommands.LogoutDatabaseUser(db, oauthTokenJSON)
 | 
					 | 
				
			||||||
		context.SetCookie("discord-oauthtoken", "", -1, "", config.API.Domain, false, true)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func authCallback(context *gin.Context) {
 | 
					 | 
				
			||||||
	oauthState := randomstring.CookieFriendlyString(32)
 | 
					 | 
				
			||||||
	context.Set("state", oauthState)
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	oauthToken, err := oauthConfig.Exchange(context.Request.Context(), context.Query("code"))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		context.Redirect(http.StatusInternalServerError, "http://localhost:15995/")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	oauthTokenJSON, _ := json.Marshal(oauthToken)
 | 
					 | 
				
			||||||
	context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", config.API.Domain, false, false)
 | 
					 | 
				
			||||||
	user := getDiscordUser(context, oauthToken)
 | 
					 | 
				
			||||||
	createOrUpdateUser(context, oauthToken, user)
 | 
					 | 
				
			||||||
	context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/dashboard")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getDiscordUser(context *gin.Context, oauthToken *oauth2.Token) discordUser {
 | 
					 | 
				
			||||||
	response, err := oauthConfig.Client(context.Request.Context(), oauthToken).Get("https://discord.com/api/users/@me")
 | 
					 | 
				
			||||||
	if err != nil || response.StatusCode != 200 {
 | 
					 | 
				
			||||||
		responseMessage := ""
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			responseMessage = err.Error()
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			responseMessage = response.Status
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		context.JSON(http.StatusInternalServerError, gin.H{
 | 
					 | 
				
			||||||
			"message": responseMessage,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer response.Body.Close()
 | 
					 | 
				
			||||||
	body, err := io.ReadAll(response.Body)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		context.JSON(http.StatusInternalServerError, gin.H{
 | 
					 | 
				
			||||||
			"message": err.Error(),
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var user discordUser
 | 
					 | 
				
			||||||
	json.Unmarshal(body, &user)
 | 
					 | 
				
			||||||
	return user
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func createOrUpdateUser(context *gin.Context, oauthToken *oauth2.Token, user discordUser) {
 | 
					 | 
				
			||||||
	oauthTokenJSON, err := json.Marshal(oauthToken)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dbUser := dbcommands.User{
 | 
					 | 
				
			||||||
		DisplayName:      user.Global_Name,
 | 
					 | 
				
			||||||
		Username:         user.Username,
 | 
					 | 
				
			||||||
		Id:               user.Id,
 | 
					 | 
				
			||||||
		Avatar:           user.Avatar,
 | 
					 | 
				
			||||||
		AvatarDecoration: user.Avatar_Decoration_Data.Asset,
 | 
					 | 
				
			||||||
		LoginToken:       string(oauthTokenJSON),
 | 
					 | 
				
			||||||
		LoggedIn:         true,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if dbcommands.DatabaseUserExists(db, user.Id) {
 | 
					 | 
				
			||||||
		dbOAuthToken := dbcommands.GetDatabaseUserToken(db, user.Id)
 | 
					 | 
				
			||||||
		if dbOAuthToken == "" {
 | 
					 | 
				
			||||||
			context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", config.API.Domain, false, false)
 | 
					 | 
				
			||||||
			err := dbcommands.UpdateDatabaseUser(db, dbUser)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				log.Println(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			context.SetCookie("discord-oauthtoken", dbOAuthToken, 0, "", config.API.Domain, false, false)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		err := dbcommands.CreateDatabaseUser(db, dbUser)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			log.Println(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getDashboardInfo(context *gin.Context) {
 | 
					 | 
				
			||||||
	oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		var oauthToken *oauth2.Token
 | 
					 | 
				
			||||||
		err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
					 | 
				
			||||||
		if err == nil {
 | 
					 | 
				
			||||||
			if oauthToken.Valid() {
 | 
					 | 
				
			||||||
				user := getDiscordUser(context, oauthToken)
 | 
					 | 
				
			||||||
				if dbcommands.DatabaseUserLoggedIn(db, user.Id) {
 | 
					 | 
				
			||||||
					context.JSON(http.StatusOK, user)
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					context.Redirect(http.StatusTemporaryRedirect, "http://localhost:31337/logout")
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			log.Println(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isUserAuthorized(context *gin.Context) {
 | 
					 | 
				
			||||||
	oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		var oauthToken *oauth2.Token
 | 
					 | 
				
			||||||
		err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
					 | 
				
			||||||
		if err == nil {
 | 
					 | 
				
			||||||
			if oauthToken.Valid() {
 | 
					 | 
				
			||||||
				user := getDiscordUser(context, oauthToken)
 | 
					 | 
				
			||||||
				if dbcommands.DatabaseUserLoggedIn(db, user.Id) {
 | 
					 | 
				
			||||||
					context.JSON(http.StatusOK, gin.H{
 | 
					 | 
				
			||||||
						"message": true,
 | 
					 | 
				
			||||||
					})
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					context.JSON(http.StatusUnauthorized, gin.H{
 | 
					 | 
				
			||||||
						"message": true,
 | 
					 | 
				
			||||||
					})
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				log.Println(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			log.Println(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		log.Println(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	context.JSON(http.StatusUnauthorized, gin.H{
 | 
					 | 
				
			||||||
		"message": false,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					 | 
				
			||||||
	db = dbcommands.InitializeDatabase()
 | 
					 | 
				
			||||||
	config = parseConfig("config.toml")
 | 
					 | 
				
			||||||
	oauthConfig = createDiscordOAuthConfig()
 | 
					 | 
				
			||||||
	app := gin.Default()
 | 
					 | 
				
			||||||
	app.Static("/public", "./public")
 | 
					 | 
				
			||||||
	app.GET("/login", loginRedirect)
 | 
					 | 
				
			||||||
	app.GET("/auth/callback", authCallback)
 | 
					 | 
				
			||||||
	app.GET("/logout", logoutRedirect)
 | 
					 | 
				
			||||||
	app.GET("/dashboard", getDashboardInfo)
 | 
					 | 
				
			||||||
	app.GET("/authorized", isUserAuthorized)
 | 
					 | 
				
			||||||
	app.Run(":31337")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										45
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								go.mod
									
									
									
									
									
								
							| 
						 | 
					@ -1,45 +0,0 @@
 | 
				
			||||||
module gin-cpularp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go 1.24.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
replace example.com/lib/dbcommands => ./lib/dbcommands
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
require (
 | 
					 | 
				
			||||||
	example.com/lib/dbcommands v0.0.0
 | 
					 | 
				
			||||||
	github.com/bytedance/sonic v1.13.2 // indirect
 | 
					 | 
				
			||||||
	github.com/bytedance/sonic/loader v0.2.4 // indirect
 | 
					 | 
				
			||||||
	github.com/cloudwego/base64x v0.1.5 // indirect
 | 
					 | 
				
			||||||
	github.com/cloudwego/iasm v0.2.0 // indirect
 | 
					 | 
				
			||||||
	github.com/gabriel-vasile/mimetype v1.4.9 // indirect
 | 
					 | 
				
			||||||
	github.com/gin-contrib/sse v1.1.0 // indirect
 | 
					 | 
				
			||||||
	github.com/gin-gonic/gin v1.10.0 // indirect
 | 
					 | 
				
			||||||
	github.com/go-playground/locales v0.14.1 // indirect
 | 
					 | 
				
			||||||
	github.com/go-playground/universal-translator v0.18.1 // indirect
 | 
					 | 
				
			||||||
	github.com/go-playground/validator/v10 v10.26.0 // indirect
 | 
					 | 
				
			||||||
	github.com/goccy/go-json v0.10.5 // indirect
 | 
					 | 
				
			||||||
	github.com/jinzhu/inflection v1.0.0 // indirect
 | 
					 | 
				
			||||||
	github.com/jinzhu/now v1.1.5 // indirect
 | 
					 | 
				
			||||||
	github.com/json-iterator/go v1.1.12 // indirect
 | 
					 | 
				
			||||||
	github.com/klauspost/cpuid/v2 v2.2.10 // indirect
 | 
					 | 
				
			||||||
	github.com/leodido/go-urn v1.4.0 // indirect
 | 
					 | 
				
			||||||
	github.com/mattn/go-isatty v0.0.20 // indirect
 | 
					 | 
				
			||||||
	github.com/mattn/go-sqlite3 v1.14.22 // indirect
 | 
					 | 
				
			||||||
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
					 | 
				
			||||||
	github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
					 | 
				
			||||||
	github.com/pelletier/go-toml/v2 v2.2.4 // indirect
 | 
					 | 
				
			||||||
	github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3 // indirect
 | 
					 | 
				
			||||||
	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 | 
					 | 
				
			||||||
	github.com/ugorji/go/codec v1.2.12 // indirect
 | 
					 | 
				
			||||||
	github.com/xyproto/randomstring v1.2.0 // indirect
 | 
					 | 
				
			||||||
	golang.org/x/arch v0.16.0 // indirect
 | 
					 | 
				
			||||||
	golang.org/x/crypto v0.37.0 // indirect
 | 
					 | 
				
			||||||
	golang.org/x/net v0.39.0 // indirect
 | 
					 | 
				
			||||||
	golang.org/x/oauth2 v0.29.0 // indirect
 | 
					 | 
				
			||||||
	golang.org/x/sys v0.32.0 // indirect
 | 
					 | 
				
			||||||
	golang.org/x/text v0.24.0 // indirect
 | 
					 | 
				
			||||||
	google.golang.org/protobuf v1.36.6 // indirect
 | 
					 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
					 | 
				
			||||||
	gorm.io/driver/sqlite v1.5.7 // indirect
 | 
					 | 
				
			||||||
	gorm.io/gorm v1.25.12 // indirect
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										970
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										970
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| 
						 | 
					@ -1,970 +0,0 @@
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  "name": "gin-cpularp",
 | 
					 | 
				
			||||||
  "lockfileVersion": 3,
 | 
					 | 
				
			||||||
  "requires": true,
 | 
					 | 
				
			||||||
  "packages": {
 | 
					 | 
				
			||||||
    "": {
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "@tailwindcss/cli": "^4.1.4",
 | 
					 | 
				
			||||||
        "tailwindcss": "^4.1.4"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
 | 
					 | 
				
			||||||
      "hasInstallScript": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "detect-libc": "^1.0.3",
 | 
					 | 
				
			||||||
        "is-glob": "^4.0.3",
 | 
					 | 
				
			||||||
        "micromatch": "^4.0.5",
 | 
					 | 
				
			||||||
        "node-addon-api": "^7.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "optionalDependencies": {
 | 
					 | 
				
			||||||
        "@parcel/watcher-android-arm64": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-darwin-arm64": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-darwin-x64": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-freebsd-x64": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-linux-arm-glibc": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-linux-arm-musl": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-linux-arm64-glibc": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-linux-arm64-musl": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-linux-x64-glibc": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-linux-x64-musl": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-win32-arm64": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-win32-ia32": "2.5.1",
 | 
					 | 
				
			||||||
        "@parcel/watcher-win32-x64": "2.5.1"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-android-arm64": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "android"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-darwin-arm64": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "darwin"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-darwin-x64": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "darwin"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-freebsd-x64": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "freebsd"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-linux-arm-glibc": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-linux-arm-musl": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-linux-arm64-glibc": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-linux-arm64-musl": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-linux-x64-glibc": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-linux-x64-musl": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-win32-arm64": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "win32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-win32-ia32": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "ia32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "win32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@parcel/watcher-win32-x64": {
 | 
					 | 
				
			||||||
      "version": "2.5.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "win32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/cli": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-gP05Qihh+cZ2FqD5fa0WJXx3KEk2YWUYv/RBKAyiOg0V4vYVDr/xlLc0sacpnVEXM45BVUR9U2hsESufYs6YTA==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "@parcel/watcher": "^2.5.1",
 | 
					 | 
				
			||||||
        "@tailwindcss/node": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide": "4.1.4",
 | 
					 | 
				
			||||||
        "enhanced-resolve": "^5.18.1",
 | 
					 | 
				
			||||||
        "mri": "^1.2.0",
 | 
					 | 
				
			||||||
        "picocolors": "^1.1.1",
 | 
					 | 
				
			||||||
        "tailwindcss": "4.1.4"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "bin": {
 | 
					 | 
				
			||||||
        "tailwindcss": "dist/index.mjs"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/node": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "enhanced-resolve": "^5.18.1",
 | 
					 | 
				
			||||||
        "jiti": "^2.4.2",
 | 
					 | 
				
			||||||
        "lightningcss": "1.29.2",
 | 
					 | 
				
			||||||
        "tailwindcss": "4.1.4"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "optionalDependencies": {
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-android-arm64": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-darwin-arm64": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-darwin-x64": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-freebsd-x64": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-linux-arm64-gnu": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-linux-arm64-musl": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-linux-x64-gnu": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-linux-x64-musl": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-wasm32-wasi": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-win32-arm64-msvc": "4.1.4",
 | 
					 | 
				
			||||||
        "@tailwindcss/oxide-win32-x64-msvc": "4.1.4"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-android-arm64": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "android"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-darwin-arm64": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "darwin"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-darwin-x64": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "darwin"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-freebsd-x64": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "freebsd"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-linux-x64-musl": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-wasm32-wasi": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==",
 | 
					 | 
				
			||||||
      "bundleDependencies": [
 | 
					 | 
				
			||||||
        "@napi-rs/wasm-runtime",
 | 
					 | 
				
			||||||
        "@emnapi/core",
 | 
					 | 
				
			||||||
        "@emnapi/runtime",
 | 
					 | 
				
			||||||
        "@tybys/wasm-util",
 | 
					 | 
				
			||||||
        "@emnapi/wasi-threads",
 | 
					 | 
				
			||||||
        "tslib"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "wasm32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "@emnapi/core": "^1.4.0",
 | 
					 | 
				
			||||||
        "@emnapi/runtime": "^1.4.0",
 | 
					 | 
				
			||||||
        "@emnapi/wasi-threads": "^1.0.1",
 | 
					 | 
				
			||||||
        "@napi-rs/wasm-runtime": "^0.2.8",
 | 
					 | 
				
			||||||
        "@tybys/wasm-util": "^0.9.0",
 | 
					 | 
				
			||||||
        "tslib": "^2.8.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=14.0.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "win32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "win32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/braces": {
 | 
					 | 
				
			||||||
      "version": "3.0.3",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "fill-range": "^7.1.1"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=8"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/detect-libc": {
 | 
					 | 
				
			||||||
      "version": "1.0.3",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
 | 
					 | 
				
			||||||
      "license": "Apache-2.0",
 | 
					 | 
				
			||||||
      "bin": {
 | 
					 | 
				
			||||||
        "detect-libc": "bin/detect-libc.js"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=0.10"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/enhanced-resolve": {
 | 
					 | 
				
			||||||
      "version": "5.18.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "graceful-fs": "^4.2.4",
 | 
					 | 
				
			||||||
        "tapable": "^2.2.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=10.13.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/fill-range": {
 | 
					 | 
				
			||||||
      "version": "7.1.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "to-regex-range": "^5.0.1"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=8"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/graceful-fs": {
 | 
					 | 
				
			||||||
      "version": "4.2.11",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
 | 
					 | 
				
			||||||
      "license": "ISC"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/is-extglob": {
 | 
					 | 
				
			||||||
      "version": "2.1.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=0.10.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/is-glob": {
 | 
					 | 
				
			||||||
      "version": "4.0.3",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "is-extglob": "^2.1.1"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=0.10.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/is-number": {
 | 
					 | 
				
			||||||
      "version": "7.0.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=0.12.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/jiti": {
 | 
					 | 
				
			||||||
      "version": "2.4.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "bin": {
 | 
					 | 
				
			||||||
        "jiti": "lib/jiti-cli.mjs"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==",
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "detect-libc": "^2.0.3"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "optionalDependencies": {
 | 
					 | 
				
			||||||
        "lightningcss-darwin-arm64": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-darwin-x64": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-freebsd-x64": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-linux-arm-gnueabihf": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-linux-arm64-gnu": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-linux-arm64-musl": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-linux-x64-gnu": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-linux-x64-musl": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-win32-arm64-msvc": "1.29.2",
 | 
					 | 
				
			||||||
        "lightningcss-win32-x64-msvc": "1.29.2"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-darwin-arm64": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "darwin"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-darwin-x64": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "darwin"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-freebsd-x64": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "freebsd"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-linux-arm-gnueabihf": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-linux-arm64-gnu": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-linux-arm64-musl": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-linux-x64-gnu": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-linux-x64-musl": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "linux"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-win32-arm64-msvc": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "arm64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "win32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss-win32-x64-msvc": {
 | 
					 | 
				
			||||||
      "version": "1.29.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==",
 | 
					 | 
				
			||||||
      "cpu": [
 | 
					 | 
				
			||||||
        "x64"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MPL-2.0",
 | 
					 | 
				
			||||||
      "optional": true,
 | 
					 | 
				
			||||||
      "os": [
 | 
					 | 
				
			||||||
        "win32"
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 12.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/parcel"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/lightningcss/node_modules/detect-libc": {
 | 
					 | 
				
			||||||
      "version": "2.0.3",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
 | 
					 | 
				
			||||||
      "license": "Apache-2.0",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=8"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/micromatch": {
 | 
					 | 
				
			||||||
      "version": "4.0.8",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "braces": "^3.0.3",
 | 
					 | 
				
			||||||
        "picomatch": "^2.3.1"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=8.6"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/mri": {
 | 
					 | 
				
			||||||
      "version": "1.2.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=4"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/node-addon-api": {
 | 
					 | 
				
			||||||
      "version": "7.1.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
 | 
					 | 
				
			||||||
      "license": "MIT"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/picocolors": {
 | 
					 | 
				
			||||||
      "version": "1.1.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
 | 
					 | 
				
			||||||
      "license": "ISC"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/picomatch": {
 | 
					 | 
				
			||||||
      "version": "2.3.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=8.6"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "url": "https://github.com/sponsors/jonschlinkert"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/tailwindcss": {
 | 
					 | 
				
			||||||
      "version": "4.1.4",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.4.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==",
 | 
					 | 
				
			||||||
      "license": "MIT"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/tapable": {
 | 
					 | 
				
			||||||
      "version": "2.2.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=6"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/to-regex-range": {
 | 
					 | 
				
			||||||
      "version": "5.0.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "is-number": "^7.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=8.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "@tailwindcss/cli": "^4.1.4",
 | 
					 | 
				
			||||||
    "tailwindcss": "^4.1.4"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
@import "tailwindcss" source("../templates");
 | 
					 | 
				
			||||||
@theme {
 | 
					 | 
				
			||||||
    --color-primary: oklch(0.1 0 0);
 | 
					 | 
				
			||||||
    --color-secondary: oklch(0.85 0.1733 93.56);
 | 
					 | 
				
			||||||
    --color-accent: oklch(0.6 0.1556 246.71);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								src/gin-cpularp.go
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								src/gin-cpularp.go
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						api "example.com/api"
 | 
				
			||||||
 | 
						authdiscord "example.com/auth/discord"
 | 
				
			||||||
 | 
						configserver "example.com/config/server"
 | 
				
			||||||
 | 
						databasecommands "example.com/database/commands"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						api.GlobalDatabase = databasecommands.InitializeDatabase()
 | 
				
			||||||
 | 
						api.GlobalConfig = configserver.ParseConfig("../config.toml")
 | 
				
			||||||
 | 
						api.GlobalOAuth = authdiscord.CreateDiscordOAuthConfig(api.GlobalConfig)
 | 
				
			||||||
 | 
						app := gin.Default()
 | 
				
			||||||
 | 
						app.GET("/login", api.LoginRedirect)
 | 
				
			||||||
 | 
						app.GET("/auth/callback", api.AuthCallback)
 | 
				
			||||||
 | 
						app.GET("/logout", api.LogoutRedirect)
 | 
				
			||||||
 | 
						app.GET("/dashboard", api.GetDashboardInfo)
 | 
				
			||||||
 | 
						app.GET("/authorized", api.IsUserAuthorized)
 | 
				
			||||||
 | 
						app.Run(":31337")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										59
									
								
								src/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/go.mod
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,59 @@
 | 
				
			||||||
 | 
					module gin-cpularp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.24.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/database/commands => ./lib/database/commands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/database/models => ./lib/database/models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/config/server => ./lib/config/server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/auth/discord => ./lib/auth/discord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/api => ./lib/api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						example.com/api v0.0.0
 | 
				
			||||||
 | 
						example.com/auth/discord v0.0.0
 | 
				
			||||||
 | 
						example.com/config/server v0.0.0
 | 
				
			||||||
 | 
						example.com/database/commands v0.0.0
 | 
				
			||||||
 | 
						github.com/gin-gonic/gin v1.10.0
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						example.com/database/models v0.0.0 // indirect
 | 
				
			||||||
 | 
						github.com/bytedance/sonic v1.11.6 // indirect
 | 
				
			||||||
 | 
						github.com/bytedance/sonic/loader v0.1.1 // indirect
 | 
				
			||||||
 | 
						github.com/cloudwego/base64x v0.1.4 // indirect
 | 
				
			||||||
 | 
						github.com/cloudwego/iasm v0.2.0 // indirect
 | 
				
			||||||
 | 
						github.com/gabriel-vasile/mimetype v1.4.3 // indirect
 | 
				
			||||||
 | 
						github.com/gin-contrib/sse v0.1.0 // indirect
 | 
				
			||||||
 | 
						github.com/go-playground/locales v0.14.1 // indirect
 | 
				
			||||||
 | 
						github.com/go-playground/universal-translator v0.18.1 // indirect
 | 
				
			||||||
 | 
						github.com/go-playground/validator/v10 v10.20.0 // indirect
 | 
				
			||||||
 | 
						github.com/goccy/go-json v0.10.2 // indirect
 | 
				
			||||||
 | 
						github.com/jinzhu/inflection v1.0.0 // indirect
 | 
				
			||||||
 | 
						github.com/jinzhu/now v1.1.5 // indirect
 | 
				
			||||||
 | 
						github.com/json-iterator/go v1.1.12 // indirect
 | 
				
			||||||
 | 
						github.com/klauspost/cpuid/v2 v2.2.7 // indirect
 | 
				
			||||||
 | 
						github.com/leodido/go-urn v1.4.0 // indirect
 | 
				
			||||||
 | 
						github.com/mattn/go-isatty v0.0.20 // indirect
 | 
				
			||||||
 | 
						github.com/mattn/go-sqlite3 v1.14.22 // indirect
 | 
				
			||||||
 | 
						github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
				
			||||||
 | 
						github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
				
			||||||
 | 
						github.com/pelletier/go-toml/v2 v2.2.4 // indirect
 | 
				
			||||||
 | 
						github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3 // indirect
 | 
				
			||||||
 | 
						github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 | 
				
			||||||
 | 
						github.com/ugorji/go/codec v1.2.12 // indirect
 | 
				
			||||||
 | 
						github.com/xyproto/randomstring v1.2.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/arch v0.8.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/crypto v0.23.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/net v0.25.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/oauth2 v0.29.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/sys v0.20.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/text v0.15.0 // indirect
 | 
				
			||||||
 | 
						google.golang.org/protobuf v1.34.1 // indirect
 | 
				
			||||||
 | 
						gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
				
			||||||
 | 
						gorm.io/driver/sqlite v1.5.7 // indirect
 | 
				
			||||||
 | 
						gorm.io/gorm v1.25.12 // indirect
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -1,28 +1,32 @@
 | 
				
			||||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
 | 
					github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
 | 
				
			||||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
 | 
					github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
 | 
				
			||||||
 | 
					github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
 | 
				
			||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
 | 
					github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
 | 
				
			||||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
 | 
					github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
 | 
				
			||||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
 | 
					github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
 | 
				
			||||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
 | 
					 | 
				
			||||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
 | 
					 | 
				
			||||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
 | 
					github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
 | 
				
			||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
 | 
					github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
 | 
					github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
 | 
				
			||||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
 | 
					github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
 | 
				
			||||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
 | 
					github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 | 
				
			||||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
 | 
					github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 | 
				
			||||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
 | 
					github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
 | 
				
			||||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
 | 
					github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
 | 
				
			||||||
 | 
					github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
 | 
				
			||||||
 | 
					github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
 | 
				
			||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
 | 
					github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
 | 
				
			||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
 | 
					github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
 | 
				
			||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 | 
					github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 | 
				
			||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
 | 
					github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
 | 
				
			||||||
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
 | 
					github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
 | 
				
			||||||
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
 | 
					github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
 | 
				
			||||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
 | 
					github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 | 
				
			||||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
 | 
					github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 | 
				
			||||||
 | 
					github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 | 
				
			||||||
 | 
					github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 | 
				
			||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 | 
					github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 | 
				
			||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 | 
					github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 | 
				
			||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 | 
					github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 | 
				
			||||||
| 
						 | 
					@ -31,8 +35,8 @@ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
 | 
				
			||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 | 
					github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 | 
				
			||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 | 
					github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 | 
				
			||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 | 
					github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 | 
				
			||||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
 | 
					github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
 | 
				
			||||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
 | 
					github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 | 
				
			||||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
 | 
					github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
 | 
				
			||||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 | 
					github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 | 
				
			||||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
 | 
					github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
 | 
				
			||||||
| 
						 | 
					@ -47,6 +51,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
 | 
				
			||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 | 
					github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 | 
				
			||||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
 | 
					github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
 | 
				
			||||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
 | 
					github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
 | 
				
			||||||
 | 
					github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
				
			||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
					github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
				
			||||||
github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3 h1:x3LgcvujjG+mx8PUMfPmwn3tcu2aA95uCB6ilGGObWk=
 | 
					github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3 h1:x3LgcvujjG+mx8PUMfPmwn3tcu2aA95uCB6ilGGObWk=
 | 
				
			||||||
github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3/go.mod h1:P/mZMYLZ87lqRSECEWsOqywGrO1hlZkk9RTwEw35IP4=
 | 
					github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3/go.mod h1:P/mZMYLZ87lqRSECEWsOqywGrO1hlZkk9RTwEw35IP4=
 | 
				
			||||||
| 
						 | 
					@ -58,27 +63,32 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 | 
				
			||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
					github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
				
			||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 | 
					github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 | 
				
			||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 | 
					github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 | 
				
			||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
 | 
					github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
 | 
				
			||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 | 
					github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 | 
				
			||||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
 | 
					github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
 | 
				
			||||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 | 
					github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 | 
				
			||||||
github.com/xyproto/randomstring v1.2.0 h1:y7PXAEBM3XlwJjPG2JQg4voxBYZ4+hPgRdGKCfU8wik=
 | 
					github.com/xyproto/randomstring v1.2.0 h1:y7PXAEBM3XlwJjPG2JQg4voxBYZ4+hPgRdGKCfU8wik=
 | 
				
			||||||
github.com/xyproto/randomstring v1.2.0/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
 | 
					github.com/xyproto/randomstring v1.2.0/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
 | 
				
			||||||
golang.org/x/arch v0.16.0 h1:foMtLTdyOmIniqWCHjY6+JxuC54XP1fDwx4N0ASyW+U=
 | 
					golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 | 
				
			||||||
golang.org/x/arch v0.16.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
 | 
					golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
 | 
				
			||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
 | 
					golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 | 
				
			||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
 | 
					golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
 | 
				
			||||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
 | 
					golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 | 
				
			||||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
 | 
					golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
 | 
				
			||||||
 | 
					golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 | 
				
			||||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
 | 
					golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
 | 
				
			||||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 | 
					golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
 | 
					golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
 | 
				
			||||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 | 
					golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
				
			||||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
 | 
					golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
 | 
				
			||||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
 | 
					golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
				
			||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
 | 
					google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
 | 
				
			||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
 | 
					google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 | 
				
			||||||
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
				
			||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
					gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
					gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
				
			||||||
							
								
								
									
										167
									
								
								src/lib/api/api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/lib/api/api.go
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,167 @@
 | 
				
			||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						authdiscord "example.com/auth/discord"
 | 
				
			||||||
 | 
						configserver "example.com/config/server"
 | 
				
			||||||
 | 
						databasecommands "example.com/database/commands"
 | 
				
			||||||
 | 
						databasemodels "example.com/database/models"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
 | 
						"github.com/xyproto/randomstring"
 | 
				
			||||||
 | 
						"golang.org/x/oauth2"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var GlobalDatabase *gorm.DB
 | 
				
			||||||
 | 
					var GlobalConfig configserver.AppConfig
 | 
				
			||||||
 | 
					var GlobalOAuth *oauth2.Config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LoginRedirect(context *gin.Context) {
 | 
				
			||||||
 | 
						context.Redirect(302, GlobalOAuth.AuthCodeURL(context.GetString("state")))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LogoutRedirect(context *gin.Context) {
 | 
				
			||||||
 | 
						oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							databasecommands.LogoutDatabaseUser(GlobalDatabase, oauthTokenJSON)
 | 
				
			||||||
 | 
							context.SetCookie("discord-oauthtoken", "", -1, "", GlobalConfig.API.Domain, false, true)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func AuthCallback(context *gin.Context) {
 | 
				
			||||||
 | 
						oauthState := randomstring.CookieFriendlyString(32)
 | 
				
			||||||
 | 
						context.Set("state", oauthState)
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						oauthToken, err := GlobalOAuth.Exchange(context.Request.Context(), context.Query("code"))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							context.Redirect(http.StatusInternalServerError, "http://localhost:15995/")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						oauthTokenJSON, _ := json.Marshal(oauthToken)
 | 
				
			||||||
 | 
						context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
 | 
				
			||||||
 | 
						user := GetDiscordUser(context, oauthToken)
 | 
				
			||||||
 | 
						CreateOrUpdateUser(context, oauthToken, user)
 | 
				
			||||||
 | 
						context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/dashboard")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetDiscordUser(context *gin.Context, oauthToken *oauth2.Token) authdiscord.DiscordUser {
 | 
				
			||||||
 | 
						response, err := GlobalOAuth.Client(context.Request.Context(), oauthToken).Get("https://discord.com/api/users/@me")
 | 
				
			||||||
 | 
						if err != nil || response.StatusCode != 200 {
 | 
				
			||||||
 | 
							responseMessage := ""
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								responseMessage = err.Error()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								responseMessage = response.Status
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							context.JSON(http.StatusInternalServerError, gin.H{
 | 
				
			||||||
 | 
								"message": responseMessage,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer response.Body.Close()
 | 
				
			||||||
 | 
						body, err := io.ReadAll(response.Body)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							context.JSON(http.StatusInternalServerError, gin.H{
 | 
				
			||||||
 | 
								"message": err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var user authdiscord.DiscordUser
 | 
				
			||||||
 | 
						json.Unmarshal(body, &user)
 | 
				
			||||||
 | 
						return user
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateOrUpdateUser(context *gin.Context, oauthToken *oauth2.Token, user authdiscord.DiscordUser) {
 | 
				
			||||||
 | 
						oauthTokenJSON, err := json.Marshal(oauthToken)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dbUser := databasemodels.User{
 | 
				
			||||||
 | 
							DisplayName:      user.Global_Name,
 | 
				
			||||||
 | 
							Username:         user.Username,
 | 
				
			||||||
 | 
							Id:               user.Id,
 | 
				
			||||||
 | 
							Avatar:           user.Avatar,
 | 
				
			||||||
 | 
							AvatarDecoration: user.Avatar_Decoration_Data.Asset,
 | 
				
			||||||
 | 
							LoginToken:       string(oauthTokenJSON),
 | 
				
			||||||
 | 
							LoggedIn:         true,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if databasecommands.DatabaseUserExists(GlobalDatabase, user.Id) {
 | 
				
			||||||
 | 
							dbOAuthToken := databasecommands.GetDatabaseUserToken(GlobalDatabase, user.Id)
 | 
				
			||||||
 | 
							if dbOAuthToken == "" {
 | 
				
			||||||
 | 
								context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
 | 
				
			||||||
 | 
								err := databasecommands.UpdateDatabaseUser(GlobalDatabase, dbUser)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Println(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								context.SetCookie("discord-oauthtoken", dbOAuthToken, 0, "", GlobalConfig.API.Domain, false, false)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							err := databasecommands.CreateDatabaseUser(GlobalDatabase, dbUser)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetDashboardInfo(context *gin.Context) {
 | 
				
			||||||
 | 
						oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							var oauthToken *oauth2.Token
 | 
				
			||||||
 | 
							err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								if oauthToken.Valid() {
 | 
				
			||||||
 | 
									user := GetDiscordUser(context, oauthToken)
 | 
				
			||||||
 | 
									if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
 | 
				
			||||||
 | 
										context.JSON(http.StatusOK, user)
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										context.Redirect(http.StatusTemporaryRedirect, "http://localhost:31337/logout")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func IsUserAuthorized(context *gin.Context) {
 | 
				
			||||||
 | 
						oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							var oauthToken *oauth2.Token
 | 
				
			||||||
 | 
							err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								if oauthToken.Valid() {
 | 
				
			||||||
 | 
									user := GetDiscordUser(context, oauthToken)
 | 
				
			||||||
 | 
									if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
 | 
				
			||||||
 | 
										context.JSON(http.StatusOK, gin.H{
 | 
				
			||||||
 | 
											"message": true,
 | 
				
			||||||
 | 
										})
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										context.JSON(http.StatusUnauthorized, gin.H{
 | 
				
			||||||
 | 
											"message": true,
 | 
				
			||||||
 | 
										})
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									log.Println(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								log.Println(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						context.JSON(http.StatusUnauthorized, gin.H{
 | 
				
			||||||
 | 
							"message": false,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								src/lib/api/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/lib/api/go.mod
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					module example.com/api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/database/commands => ../database/commands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/auth/discord => ../auth/discord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/database/models => ../database/models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/config/server => ../config/server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.24.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						example.com/auth/discord v0.0.0
 | 
				
			||||||
 | 
						example.com/config/server v0.0.0
 | 
				
			||||||
 | 
						example.com/database/commands v0.0.0
 | 
				
			||||||
 | 
						example.com/database/models v0.0.0
 | 
				
			||||||
 | 
						github.com/gin-gonic/gin v1.10.0
 | 
				
			||||||
 | 
						github.com/xyproto/randomstring v1.2.0
 | 
				
			||||||
 | 
						golang.org/x/oauth2 v0.29.0
 | 
				
			||||||
 | 
						gorm.io/gorm v1.25.12
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						github.com/bytedance/sonic v1.11.6 // indirect
 | 
				
			||||||
 | 
						github.com/bytedance/sonic/loader v0.1.1 // indirect
 | 
				
			||||||
 | 
						github.com/cloudwego/base64x v0.1.4 // indirect
 | 
				
			||||||
 | 
						github.com/cloudwego/iasm v0.2.0 // indirect
 | 
				
			||||||
 | 
						github.com/gabriel-vasile/mimetype v1.4.3 // indirect
 | 
				
			||||||
 | 
						github.com/gin-contrib/sse v0.1.0 // indirect
 | 
				
			||||||
 | 
						github.com/go-playground/locales v0.14.1 // indirect
 | 
				
			||||||
 | 
						github.com/go-playground/universal-translator v0.18.1 // indirect
 | 
				
			||||||
 | 
						github.com/go-playground/validator/v10 v10.20.0 // indirect
 | 
				
			||||||
 | 
						github.com/goccy/go-json v0.10.2 // indirect
 | 
				
			||||||
 | 
						github.com/jinzhu/inflection v1.0.0 // indirect
 | 
				
			||||||
 | 
						github.com/jinzhu/now v1.1.5 // indirect
 | 
				
			||||||
 | 
						github.com/json-iterator/go v1.1.12 // indirect
 | 
				
			||||||
 | 
						github.com/klauspost/cpuid/v2 v2.2.7 // indirect
 | 
				
			||||||
 | 
						github.com/leodido/go-urn v1.4.0 // indirect
 | 
				
			||||||
 | 
						github.com/mattn/go-isatty v0.0.20 // indirect
 | 
				
			||||||
 | 
						github.com/mattn/go-sqlite3 v1.14.22 // indirect
 | 
				
			||||||
 | 
						github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
				
			||||||
 | 
						github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
				
			||||||
 | 
						github.com/pelletier/go-toml/v2 v2.2.4 // indirect
 | 
				
			||||||
 | 
						github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3 // indirect
 | 
				
			||||||
 | 
						github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 | 
				
			||||||
 | 
						github.com/ugorji/go/codec v1.2.12 // indirect
 | 
				
			||||||
 | 
						golang.org/x/arch v0.8.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/crypto v0.23.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/net v0.25.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/sys v0.20.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/text v0.15.0 // indirect
 | 
				
			||||||
 | 
						google.golang.org/protobuf v1.34.1 // indirect
 | 
				
			||||||
 | 
						gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
				
			||||||
 | 
						gorm.io/driver/sqlite v1.5.7 // indirect
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										101
									
								
								src/lib/api/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/lib/api/go.sum
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,101 @@
 | 
				
			||||||
 | 
					github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
 | 
				
			||||||
 | 
					github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
 | 
				
			||||||
 | 
					github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
 | 
				
			||||||
 | 
					github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
 | 
				
			||||||
 | 
					github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
 | 
				
			||||||
 | 
					github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
 | 
				
			||||||
 | 
					github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
 | 
				
			||||||
 | 
					github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
					github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
 | 
				
			||||||
 | 
					github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
 | 
				
			||||||
 | 
					github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 | 
				
			||||||
 | 
					github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 | 
				
			||||||
 | 
					github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
 | 
				
			||||||
 | 
					github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
 | 
				
			||||||
 | 
					github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
 | 
				
			||||||
 | 
					github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
 | 
				
			||||||
 | 
					github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
 | 
				
			||||||
 | 
					github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
 | 
				
			||||||
 | 
					github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 | 
				
			||||||
 | 
					github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
 | 
				
			||||||
 | 
					github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
 | 
				
			||||||
 | 
					github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
 | 
				
			||||||
 | 
					github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 | 
				
			||||||
 | 
					github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 | 
				
			||||||
 | 
					github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 | 
				
			||||||
 | 
					github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 | 
				
			||||||
 | 
					github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 | 
				
			||||||
 | 
					github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 | 
				
			||||||
 | 
					github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 | 
				
			||||||
 | 
					github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 | 
				
			||||||
 | 
					github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 | 
				
			||||||
 | 
					github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 | 
				
			||||||
 | 
					github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 | 
				
			||||||
 | 
					github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 | 
				
			||||||
 | 
					github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
 | 
				
			||||||
 | 
					github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 | 
				
			||||||
 | 
					github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
 | 
				
			||||||
 | 
					github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 | 
				
			||||||
 | 
					github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 | 
				
			||||||
 | 
					github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 | 
				
			||||||
 | 
					github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 | 
				
			||||||
 | 
					github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
				
			||||||
 | 
					github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 | 
				
			||||||
 | 
					github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
				
			||||||
 | 
					github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 | 
				
			||||||
 | 
					github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 | 
				
			||||||
 | 
					github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
 | 
				
			||||||
 | 
					github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
 | 
				
			||||||
 | 
					github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
				
			||||||
 | 
					github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
				
			||||||
 | 
					github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3 h1:x3LgcvujjG+mx8PUMfPmwn3tcu2aA95uCB6ilGGObWk=
 | 
				
			||||||
 | 
					github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3/go.mod h1:P/mZMYLZ87lqRSECEWsOqywGrO1hlZkk9RTwEw35IP4=
 | 
				
			||||||
 | 
					github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
				
			||||||
 | 
					github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 | 
				
			||||||
 | 
					github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 | 
				
			||||||
 | 
					github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
 | 
				
			||||||
 | 
					github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 | 
				
			||||||
 | 
					github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
 | 
				
			||||||
 | 
					github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 | 
				
			||||||
 | 
					github.com/xyproto/randomstring v1.2.0 h1:y7PXAEBM3XlwJjPG2JQg4voxBYZ4+hPgRdGKCfU8wik=
 | 
				
			||||||
 | 
					github.com/xyproto/randomstring v1.2.0/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
 | 
				
			||||||
 | 
					golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 | 
				
			||||||
 | 
					golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
 | 
				
			||||||
 | 
					golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 | 
				
			||||||
 | 
					golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
 | 
				
			||||||
 | 
					golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 | 
				
			||||||
 | 
					golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
 | 
				
			||||||
 | 
					golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 | 
				
			||||||
 | 
					golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
 | 
				
			||||||
 | 
					golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
				
			||||||
 | 
					golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
 | 
				
			||||||
 | 
					golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
				
			||||||
 | 
					google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
 | 
				
			||||||
 | 
					google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 | 
				
			||||||
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
				
			||||||
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
 | 
					gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
				
			||||||
 | 
					gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
				
			||||||
 | 
					gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
				
			||||||
 | 
					gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
 | 
				
			||||||
 | 
					gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
 | 
				
			||||||
 | 
					nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
 | 
				
			||||||
 | 
					rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 | 
				
			||||||
							
								
								
									
										54
									
								
								src/lib/auth/discord/discord.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/lib/auth/discord/discord.go
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					package authdiscord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						configserver "example.com/config/server"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ravener/discord-oauth2"
 | 
				
			||||||
 | 
						"golang.org/x/oauth2"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DiscordUser struct {
 | 
				
			||||||
 | 
						Id                     string
 | 
				
			||||||
 | 
						Username               string
 | 
				
			||||||
 | 
						Avatar                 string
 | 
				
			||||||
 | 
						Discriminator          string
 | 
				
			||||||
 | 
						Public_Flags           float64
 | 
				
			||||||
 | 
						Flags                  float64
 | 
				
			||||||
 | 
						Banner                 string
 | 
				
			||||||
 | 
						Accent_Color           float64
 | 
				
			||||||
 | 
						Global_Name            string
 | 
				
			||||||
 | 
						Avatar_Decoration_Data struct {
 | 
				
			||||||
 | 
							Asset      string
 | 
				
			||||||
 | 
							Sku_Id     string
 | 
				
			||||||
 | 
							Expires_At string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						Collectibles  string
 | 
				
			||||||
 | 
						Banner_Color  string
 | 
				
			||||||
 | 
						Clan          string
 | 
				
			||||||
 | 
						Primary_Guild string
 | 
				
			||||||
 | 
						Mfa_Eneabled  bool
 | 
				
			||||||
 | 
						Locale        string
 | 
				
			||||||
 | 
						Premium_Type  float64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateDiscordOAuthConfig(config configserver.AppConfig) *oauth2.Config {
 | 
				
			||||||
 | 
						protocolString := ""
 | 
				
			||||||
 | 
						if config.API.Https {
 | 
				
			||||||
 | 
							protocolString = "https://"
 | 
				
			||||||
 | 
							config.API.Port = ""
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							protocolString = "http://"
 | 
				
			||||||
 | 
							config.API.Port = fmt.Sprintf(":%s", config.API.Port)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						redirectUrlString := fmt.Sprintf("%s%s%s/auth/callback", protocolString, config.API.Domain, config.API.Port)
 | 
				
			||||||
 | 
						oauthconfig := &oauth2.Config{
 | 
				
			||||||
 | 
							ClientID:     config.OAuth.ClientID,
 | 
				
			||||||
 | 
							ClientSecret: config.OAuth.ClientSecret,
 | 
				
			||||||
 | 
							RedirectURL:  redirectUrlString,
 | 
				
			||||||
 | 
							Scopes:       []string{discord.ScopeIdentify},
 | 
				
			||||||
 | 
							Endpoint:     discord.Endpoint,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return oauthconfig
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/lib/auth/discord/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/lib/auth/discord/go.mod
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					module example.com/auth/discord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/config/server => ../../config/server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.24.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						example.com/config/server v0.0.0
 | 
				
			||||||
 | 
						github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3
 | 
				
			||||||
 | 
						golang.org/x/oauth2 v0.29.0
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require github.com/pelletier/go-toml/v2 v2.2.4 // indirect
 | 
				
			||||||
							
								
								
									
										8
									
								
								src/lib/auth/discord/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/lib/auth/discord/go.sum
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 | 
				
			||||||
 | 
					github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 | 
				
			||||||
 | 
					github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
 | 
				
			||||||
 | 
					github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
 | 
				
			||||||
 | 
					github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3 h1:x3LgcvujjG+mx8PUMfPmwn3tcu2aA95uCB6ilGGObWk=
 | 
				
			||||||
 | 
					github.com/ravener/discord-oauth2 v0.0.0-20230514095040-ae65713199b3/go.mod h1:P/mZMYLZ87lqRSECEWsOqywGrO1hlZkk9RTwEw35IP4=
 | 
				
			||||||
 | 
					golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
 | 
				
			||||||
 | 
					golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 | 
				
			||||||
							
								
								
									
										5
									
								
								src/lib/config/server/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/lib/config/server/go.mod
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					module example.com/config/server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.24.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require github.com/pelletier/go-toml/v2 v2.2.4
 | 
				
			||||||
							
								
								
									
										2
									
								
								src/lib/config/server/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/lib/config/server/go.sum
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
 | 
				
			||||||
 | 
					github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/lib/config/server/server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/lib/config/server/server.go
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					package configserver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/pelletier/go-toml/v2"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AppConfig struct {
 | 
				
			||||||
 | 
						API struct {
 | 
				
			||||||
 | 
							Domain string
 | 
				
			||||||
 | 
							Port   string
 | 
				
			||||||
 | 
							Https  bool
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						OAuth struct {
 | 
				
			||||||
 | 
							ClientID     string
 | 
				
			||||||
 | 
							ClientSecret string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ParseConfig(configPath string) AppConfig {
 | 
				
			||||||
 | 
						configFile, err := os.Open(configPath)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						configFileContent, err := io.ReadAll(configFile)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var configObject AppConfig
 | 
				
			||||||
 | 
						err = toml.Unmarshal(configFileContent, &configObject)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return configObject
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,35 +1,26 @@
 | 
				
			||||||
package dbcommands
 | 
					package databasecommands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						databasemodels "example.com/database/models"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gorm.io/driver/sqlite"
 | 
						"gorm.io/driver/sqlite"
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type User struct {
 | 
					 | 
				
			||||||
	gorm.Model
 | 
					 | 
				
			||||||
	Id               string
 | 
					 | 
				
			||||||
	DisplayName      string
 | 
					 | 
				
			||||||
	Username         string
 | 
					 | 
				
			||||||
	Avatar           string
 | 
					 | 
				
			||||||
	AvatarDecoration string
 | 
					 | 
				
			||||||
	LoginToken       string
 | 
					 | 
				
			||||||
	LoggedIn         bool
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func InitializeDatabase() *gorm.DB {
 | 
					func InitializeDatabase() *gorm.DB {
 | 
				
			||||||
	db, err := gorm.Open(sqlite.Open("db/main.db"), &gorm.Config{})
 | 
						db, err := gorm.Open(sqlite.Open("../db/main.db"), &gorm.Config{})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal("Failed to connect to database.")
 | 
							log.Fatal("Failed to connect to database.")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	db.AutoMigrate(&User{})
 | 
						db.AutoMigrate(&databasemodels.User{})
 | 
				
			||||||
	return db
 | 
						return db
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetDatabaseUserToken(db *gorm.DB, id string) string {
 | 
					func GetDatabaseUserToken(db *gorm.DB, id string) string {
 | 
				
			||||||
	var dbUser User
 | 
						var dbUser databasemodels.User
 | 
				
			||||||
	result := db.Where("id = ?", id).Select("login_token").Take(&dbUser)
 | 
						result := db.Where("id = ?", id).Select("login_token").Take(&dbUser)
 | 
				
			||||||
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
 | 
						if errors.Is(result.Error, gorm.ErrRecordNotFound) {
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
| 
						 | 
					@ -39,7 +30,7 @@ func GetDatabaseUserToken(db *gorm.DB, id string) string {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DatabaseUserExists(db *gorm.DB, id string) bool {
 | 
					func DatabaseUserExists(db *gorm.DB, id string) bool {
 | 
				
			||||||
	var queryUser User
 | 
						var queryUser databasemodels.User
 | 
				
			||||||
	result := db.Where("id = ?", id).Take(&queryUser)
 | 
						result := db.Where("id = ?", id).Take(&queryUser)
 | 
				
			||||||
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
 | 
						if errors.Is(result.Error, gorm.ErrRecordNotFound) {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
| 
						 | 
					@ -49,7 +40,7 @@ func DatabaseUserExists(db *gorm.DB, id string) bool {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DatabaseUserLoggedIn(db *gorm.DB, id string) bool {
 | 
					func DatabaseUserLoggedIn(db *gorm.DB, id string) bool {
 | 
				
			||||||
	var queryUser User
 | 
						var queryUser databasemodels.User
 | 
				
			||||||
	result := db.Where("id = ?", id).Take(&queryUser)
 | 
						result := db.Where("id = ?", id).Take(&queryUser)
 | 
				
			||||||
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
 | 
						if errors.Is(result.Error, gorm.ErrRecordNotFound) {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
| 
						 | 
					@ -58,7 +49,7 @@ func DatabaseUserLoggedIn(db *gorm.DB, id string) bool {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UpdateDatabaseUser(db *gorm.DB, user User) error {
 | 
					func UpdateDatabaseUser(db *gorm.DB, user databasemodels.User) error {
 | 
				
			||||||
	result := db.Save(&user)
 | 
						result := db.Save(&user)
 | 
				
			||||||
	if result.Error != nil {
 | 
						if result.Error != nil {
 | 
				
			||||||
		return result.Error
 | 
							return result.Error
 | 
				
			||||||
| 
						 | 
					@ -66,7 +57,7 @@ func UpdateDatabaseUser(db *gorm.DB, user User) error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func CreateDatabaseUser(db *gorm.DB, user User) error {
 | 
					func CreateDatabaseUser(db *gorm.DB, user databasemodels.User) error {
 | 
				
			||||||
	result := db.Create(&user)
 | 
						result := db.Create(&user)
 | 
				
			||||||
	if result.Error != nil {
 | 
						if result.Error != nil {
 | 
				
			||||||
		return result.Error
 | 
							return result.Error
 | 
				
			||||||
| 
						 | 
					@ -75,6 +66,6 @@ func CreateDatabaseUser(db *gorm.DB, user User) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LogoutDatabaseUser(db *gorm.DB, oauthToken string) {
 | 
					func LogoutDatabaseUser(db *gorm.DB, oauthToken string) {
 | 
				
			||||||
	db.Model(&User{}).Where("login_token = ?", oauthToken).Update("logged_in", false)
 | 
						db.Model(&databasemodels.User{}).Where("login_token = ?", oauthToken).Update("logged_in", false)
 | 
				
			||||||
	db.Model(&User{}).Where("login_token = ?", oauthToken).Update("login_token", "")
 | 
						db.Model(&databasemodels.User{}).Where("login_token = ?", oauthToken).Update("login_token", "")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,18 @@
 | 
				
			||||||
module example.com/lib/dbc
 | 
					module example.com/database/commands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
go 1.24.2
 | 
					go 1.24.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace example.com/database/models => ../models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						example.com/database/models v0.0.0
 | 
				
			||||||
 | 
						gorm.io/driver/sqlite v1.5.7 // direct
 | 
				
			||||||
 | 
						gorm.io/gorm v1.25.12 // direct
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/jinzhu/inflection v1.0.0 // indirect
 | 
						github.com/jinzhu/inflection v1.0.0 // indirect
 | 
				
			||||||
	github.com/jinzhu/now v1.1.5 // indirect
 | 
						github.com/jinzhu/now v1.1.5 // indirect
 | 
				
			||||||
	github.com/mattn/go-sqlite3 v1.14.22 // indirect
 | 
						github.com/mattn/go-sqlite3 v1.14.22 // indirect
 | 
				
			||||||
	golang.org/x/text v0.14.0 // indirect
 | 
						golang.org/x/text v0.14.0 // indirect
 | 
				
			||||||
	gorm.io/driver/sqlite v1.5.7 // direct
 | 
					 | 
				
			||||||
	gorm.io/gorm v1.25.12 // direct
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -4,13 +4,9 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 | 
				
			||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 | 
					github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 | 
				
			||||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 | 
					github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 | 
				
			||||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 | 
					github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 | 
				
			||||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
 | 
					 | 
				
			||||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 | 
					 | 
				
			||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 | 
					golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 | 
				
			||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
					golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
				
			||||||
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
 | 
					gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
 | 
				
			||||||
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
 | 
					gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
 | 
				
			||||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde h1:9DShaph9qhkIYw7QF91I/ynrr4cOO2PZra2PFD7Mfeg=
 | 
					 | 
				
			||||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
 | 
					 | 
				
			||||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
 | 
					gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
 | 
				
			||||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
 | 
					gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
 | 
				
			||||||
							
								
								
									
										11
									
								
								src/lib/database/models/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/lib/database/models/go.mod
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					module example.com/database/models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.24.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require gorm.io/gorm v1.25.12 // direct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						github.com/jinzhu/inflection v1.0.0 // indirect
 | 
				
			||||||
 | 
						github.com/jinzhu/now v1.1.5 // indirect
 | 
				
			||||||
 | 
						golang.org/x/text v0.14.0 // indirect
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										8
									
								
								src/lib/database/models/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/lib/database/models/go.sum
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 | 
				
			||||||
 | 
					github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 | 
				
			||||||
 | 
					github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 | 
				
			||||||
 | 
					github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 | 
				
			||||||
 | 
					golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 | 
				
			||||||
 | 
					golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
 | 
				
			||||||
 | 
					gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/lib/database/models/models.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/lib/database/models/models.go
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					package databasemodels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "gorm.io/gorm"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type User struct {
 | 
				
			||||||
 | 
						gorm.Model
 | 
				
			||||||
 | 
						Id               string
 | 
				
			||||||
 | 
						DisplayName      string
 | 
				
			||||||
 | 
						Username         string
 | 
				
			||||||
 | 
						Avatar           string
 | 
				
			||||||
 | 
						AvatarDecoration string
 | 
				
			||||||
 | 
						LoginToken       string
 | 
				
			||||||
 | 
						LoggedIn         bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue