add session, login And register '-'

This commit is contained in:
2025-06-15 02:27:45 -03:00
parent 86327ddad6
commit 4528c8a06f
6 changed files with 262 additions and 30 deletions

View File

@@ -9,12 +9,14 @@ import (
"github.com/go-sql-driver/mysql"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
)
func sessionCookie(id int) (*http.Cookie, error) {
func sessionCookie(id int, player string) (*http.Cookie, error) {
sessionID := uuid.New().String()
sessionInfo := map[string]interface{}{
"user_id": id,
"user_id": id,
"playerName": player,
}
err := redisCL.HSet(ctx, sessionID, sessionInfo).Err()
@@ -28,7 +30,7 @@ func sessionCookie(id int) (*http.Cookie, error) {
}
cookie := &http.Cookie{
Name: "PlayerSession",
Name: cookieName,
Value: sessionID,
Path: "/*",
HttpOnly: true,
@@ -94,9 +96,24 @@ func CheckTables(query string) error {
if err != nil {
return fmt.Errorf("a tabela: %s não foi criada", a)
}
defer rows.Close()
log.Printf("tabela %s foi criada.\n", a)
}
}
log.Println("verificação comcluida.")
return nil
}
func ValidSession(c echo.Context) (map[string]string, error) {
cookie, err := c.Cookie(cookieName)
if err != nil {
return nil, fmt.Errorf("sessão não existe, faça login.")
}
sessionID := cookie.Value
dataSession, err := redisCL.HGetAll(ctx, sessionID).Result()
if err != nil {
return nil, fmt.Errorf("sessão invalida ou expirada.")
}
return dataSession, nil
}

View File

@@ -11,10 +11,15 @@ type Table struct {
Name string
}
type logEntry struct {
ID int `json:"id"`
Log string `json:"log"`
}
type resp_json struct {
Status string `json:"Status"`
Message string `json:"Message,omitempty"`
Logs map[string]string `json:"Logs,omitempty"`
Status string `json:"Status"`
Message string `json:"Message,omitempty"`
Logs []logEntry `json:"Logs,omitempty"`
}
var (
@@ -22,7 +27,14 @@ var (
redisCL *redis.Client
ctx = context.Background()
table_list = map[string]string{
"players": "CREATE TABLE players (`id` INT NOT NULL AUTO_INCREMENT,`foto` MEDIUMTEXT NOT NULL,`player` VARCHAR(15) NOT NULL,`password` TEXT NOT NULL,`nome` VARCHAR(30) NOT NULL,`level` INT NOT NULL DEFAULT '0',`idade` INT NOT NULL DEFAULT '18',`altura` FLOAT NOT NULL DEFAULT '1.40',`vida` INT NOT NULL DEFAULT '10',`vida_maxima` INT NOT NULL DEFAULT '10',`destresa` INT NOT NULL DEFAULT '0',`inteligencia` INT NOT NULL DEFAULT '0',`força` INT NOT NULL DEFAULT '0',`constituição` INT NOT NULL DEFAULT '0',`cárisma` INT NOT NULL DEFAULT '0',`inventario` INT NOT NULL DEFAULT '10',`descrição` TEXT NOT NULL,PRIMARY KEY (`id`)) ENGINE = InnoDB;",
"players": "CREATE TABLE players (`id` INT NOT NULL AUTO_INCREMENT,`foto` MEDIUMTEXT NOT NULL,`player` VARCHAR(15) NOT NULL,`password` TEXT NOT NULL,`nome` VARCHAR(30) NOT NULL, `conhecimento` INT NOT NULL DEFAULT '0',`level` INT NOT NULL DEFAULT '0',`idade` INT NOT NULL DEFAULT '18',`altura` FLOAT NOT NULL DEFAULT '1.40',`vida` INT NOT NULL DEFAULT '10',`vida_maxima` INT NOT NULL DEFAULT '10',`destresa` INT NOT NULL DEFAULT '0',`inteligencia` INT NOT NULL DEFAULT '0',`força` INT NOT NULL DEFAULT '0',`constituição` INT NOT NULL DEFAULT '0',`cárisma` INT NOT NULL DEFAULT '0',`inventario` INT NOT NULL DEFAULT '10',`descrição` TEXT NOT NULL,PRIMARY KEY (`id`)) ENGINE = InnoDB;",
"roll_logs": "CREATE TABLE roll_logs (`id` INT NOT NULL AUTO_INCREMENT , `log` TEXT NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;",
}
formatFILES = map[string]bool{
".png": true,
".jpg": true,
".jpeg": true,
".gif": true,
}
cookieName string = "PlayerSession"
)

View File

@@ -76,18 +76,16 @@ func main() {
return next(c)
}
}
log.Println("concluido, back_end rodando")
/* rotas */
e.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, resp_json{
Status: "Success",
Message: "Api esta online",
})
})
e.GET("/", online)
e.GET("roll", roll_get)
e.POST("register", registrar)
e.POST("login", login, timeoutMiddleware, rateLimit)
e.GET("player", player_data)
/* log */
e.Logger.Fatal(e.Start(fmt.Sprintf(":%s", load_data["port"])))

View File

@@ -1,33 +1,170 @@
package main
import (
"encoding/base64"
"fmt"
"io"
"log"
"net/http"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/labstack/echo/v4"
"golang.org/x/crypto/bcrypt"
)
func login(c echo.Context) error {
func online(c echo.Context) error {
return c.JSON(http.StatusOK, resp_json{
Status: "Success",
Message: "Api esta online",
})
}
func registrar(c echo.Context) error {
player := c.FormValue("player")
password := c.FormValue("password")
confpass := c.FormValue("confirmpassowrd")
playerlore := c.FormValue("playerlore")
if strings.TrimSpace(player) == "" || strings.TrimSpace(password) == "" {
return c.JSON(http.StatusForbidden, resp_json{
if !regexp.MustCompile(`^[a-zA-Z0-9_]+$`).MatchString(player) {
return c.JSON(http.StatusBadRequest, resp_json{
Status: "Error",
Message: "algum parametro esta faltando tente novamente",
Message: "você usou caracteres proibidos no seu nome",
})
}
/*passhash, err := bcrypt.GenerateFromPassword([]byte(password), 15)
if strings.TrimSpace(player) == "" || strings.TrimSpace(password) == "" || strings.TrimSpace(confpass) == "" || strings.TrimSpace(playerlore) == "" {
return c.JSON(http.StatusBadRequest, resp_json{
Status: "Error",
Message: "algum parametro esta faltando ou esta vazio, tente novamente",
})
}
if password != confpass {
return c.JSON(http.StatusBadRequest, resp_json{
Status: "Error",
Message: "Suas senhas não são iguais, verifique e tente novamente.",
})
}
passhash, err := bcrypt.GenerateFromPassword([]byte(password), 15)
if err != nil {
log.Println("Algo deu errado com a hash de senha.")
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "Erro ao criar hash de senha do usuario: " + player,
})
}*/
}
format := formatFILES
ImageFile, err := c.FormFile("PlayerImage")
if err != nil {
return c.JSON(http.StatusBadRequest, resp_json{
Status: "Error",
Message: "Arquivo de Imagem não foi enviado, adcione uma imagem.",
})
}
if !format[strings.ToLower(filepath.Ext(ImageFile.Filename))] {
return c.JSON(http.StatusBadRequest, resp_json{
Status: "Error",
Message: "sua imagem deve ser png, jpg, jpeg ou gif.",
})
}
openfile, err := ImageFile.Open()
if err != nil {
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "não foi possivel ler sua imagem",
})
}
defer openfile.Close()
if ImageFile.Size > 3*1024*1024 {
return c.JSON(http.StatusBadRequest, resp_json{
Status: "Error",
Message: "Sua imagem deve ter no maximo 3MB",
})
}
readFile, err := io.ReadAll(openfile)
if err != nil {
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "não foi possivel ler sua Imagem, tente novamente.",
})
}
encode := base64.StdEncoding.EncodeToString(readFile)
var id int
err = db.QueryRow("SELECT id FROM players WHERE player=? LIMIT 1", player).Scan(&id)
if err == nil {
log.Println(id)
return c.JSON(http.StatusConflict, resp_json{
Status: "Error",
Message: "Esse usuario ja esta em uso, escolha outro e tente novamente.",
})
}
row, err := db.Exec("INSERT INTO players (foto, player, password, nome, descrição) VALUES (?, ?, ?, ?, ?);", encode, player, string(passhash), "John Doe", playerlore)
if err == nil {
newID, _ := row.LastInsertId()
query := fmt.Sprintf("CREATE TABLE invPower_%s (id INT NOT NULL AUTO_INCREMENT, name_power VARCHAR(30) NOT NULL, desc_power LONGTEXT NOT NULL, PRIMARY KEY (`id`)) ENGINE = InnoDB;", player)
_, err := db.Exec(query)
if err != nil {
db.Exec("DELETE FROM players WHERE id=?", int(newID))
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "algo deu errado ao criar o inventario de poderes do player: " + player,
})
}
log.Printf("tabela invPower_%s foi criada.\n", player)
query = fmt.Sprintf(`CREATE TABLE inv_%s (id INT NOT NULL , item_nome VARCHAR(30) NOT NULL , quantidade INT NOT NULL DEFAULT '1' , item_peso INT NOT NULL DEFAULT '1' , item_durabilit BOOLEAN NOT NULL DEFAULT FALSE ) ENGINE = InnoDB;`, player)
newInv, err := db.Query(query)
if err != nil {
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "algo deu errado ao criar o inventario do player: " + player,
})
}
newInv.Next()
defer newInv.Close()
log.Printf("tabela inv_%s foi criada.\n", player)
newCookie, err := sessionCookie(int(newID), player)
if err != nil {
log.Println(err)
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: err.Error(),
})
}
c.SetCookie(newCookie)
return c.JSON(http.StatusOK, resp_json{
Status: "Success",
Message: "sua conta foi criada com sucesso",
})
}
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "Erro ao criar sua conta, tente novamente",
})
}
func login(c echo.Context) error {
player := c.FormValue("player")
password := c.FormValue("password")
if strings.TrimSpace(player) == "" || strings.TrimSpace(password) == "" {
return c.JSON(http.StatusBadRequest, resp_json{
Status: "Error",
Message: "algum parametro esta faltando ou esta vaziu, tente novamente",
})
}
var id int
var DBpass string
@@ -35,7 +172,7 @@ func login(c echo.Context) error {
if err == nil {
if bcrypt.CompareHashAndPassword([]byte(DBpass), []byte(password)) == nil {
newCookie, err := sessionCookie(id)
newCookie, err := sessionCookie(id, player)
if err != nil {
log.Println(err)
@@ -48,9 +185,61 @@ func login(c echo.Context) error {
}
}
return c.JSON(http.StatusForbidden, resp_json{
return c.JSON(http.StatusUnauthorized, resp_json{
Status: "Error",
Message: "Usuario ou senha incorreto",
})
}
func roll_get(c echo.Context) error {
row, err := db.Query("SELECT * FROM roll_logs ORDER BY id DESC LIMIT 5;")
if err != nil {
log.Println("Erro ao consultar tabela de rolagem.")
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "algo deu errado ao consultar tabela de rolagem",
})
}
var lista []logEntry
for row.Next() {
var id int
var log string
if err := row.Scan(&id, &log); err != nil {
return c.JSON(http.StatusInternalServerError, resp_json{
Status: "Error",
Message: "algo deu errado ao montar lista de rolagem",
})
}
lista = append(lista, logEntry{ID: id, Log: log})
}
sort.Slice(lista, func(i, j int) bool {
return lista[i].ID < lista[j].ID
})
if len(lista) <= 0 {
return c.JSON(http.StatusNotFound, resp_json{
Status: "NoDB",
Message: "Ainda não exite historico de rolagem",
})
}
return c.JSON(http.StatusOK, resp_json{
Status: "Success",
Logs: lista,
})
}
func player_data(c echo.Context) error {
test, err := ValidSession(c)
if err != nil {
return c.JSON(http.StatusUnauthorized, resp_json{
Status: "Error",
Message: err.Error(),
})
}
return c.JSON(http.StatusOK, resp_json{
Status: "Success",
Message: test["user_id"],
})
}

Binary file not shown.

View File

@@ -12,6 +12,24 @@
<div id="playerDATA">
<img id="hero" src="images/none.png" />
<ul>
<li>
<label>vida:</label>
<p>0/0</p>
<a id="btn">
<span class="material-symbols-outlined">
arrow_upward
</span>
</a>
<a id="btn">
<span class="material-symbols-outlined">
arrow_downward
</span>
</a>
<a id="btn" class="editbtn player_life">
<span class="material-symbols-outlined"> edit </span>
edit
</a>
</li>
<li>
<label>nome:</label>
<p>you user name</p>
@@ -91,7 +109,7 @@
<span class="material-symbols-outlined">
casino
</span>
1d30
1d40
</a>
</li>
<li>
@@ -99,7 +117,7 @@
<span class="material-symbols-outlined">
casino
</span>
1d40
1d50
</a>
</li>
<li>
@@ -124,10 +142,8 @@
<ul>
<li>
<label>
vida:
conh:
<p id="life" class="status_player">0</p>
/
<p id="max_life" class="status_player">0</p>
<a id="btn">
<span
class="material-symbols-outlined btn-left"
@@ -140,7 +156,7 @@
arrow_downward
</span>
</a>
<a id="btn" class="editbtn vida">
<a id="btn" class="editbtn">
<span
class="material-symbols-outlined btn-right"
>
@@ -201,7 +217,7 @@
</li>
<li>
<label>
con:
const:
<p id="constitution" class="status_player">0</p>
<a id="btn">
<span