Compare commits

...

3 Commits

Author SHA1 Message Date
7f2783b39a add postfix -md5 to checksum field 2025-08-06 15:45:20 +03:00
c08135309f add random salt and result/error checksum 2025-08-06 15:41:25 +03:00
cd9e3ab6c4 remove phone_number from db query 2025-08-06 15:40:42 +03:00
5 changed files with 49 additions and 23 deletions

View File

@@ -60,10 +60,9 @@ end
local hashPass = crypt.generate(params.password, crypt.DefaultCost) local hashPass = crypt.generate(params.password, crypt.DefaultCost)
local existing, err = db:query("SELECT 1 FROM users WHERE deleted = 0 AND (email = ? OR username = ? OR phone_number = ?) LIMIT 1", { local existing, err = db:query("SELECT 1 FROM users WHERE deleted = 0 AND (email = ? OR username = ?) LIMIT 1", {
params.email, params.email,
params.username, params.username
params.phone_number
}) })
if err ~= nil then if err ~= nil then

View File

@@ -26,7 +26,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Session-UUID", sessionUUID) w.Header().Set("X-Session-UUID", sessionUUID)
if !gs.sm.Add(sessionUUID) { if !gs.sm.Add(sessionUUID) {
gs.x.SLog.Debug("session is busy", slog.String("session-uuid", sessionUUID)) gs.x.SLog.Debug("session is busy", slog.String("session-uuid", sessionUUID))
rpc.WriteError(w, &rpc.RPCResponse{ rpc.WriteError(gs.cs.UUID32, w, &rpc.RPCResponse{
Error: map[string]any{ Error: map[string]any{
"code": rpc.ErrSessionIsBusy, "code": rpc.ErrSessionIsBusy,
"message": rpc.ErrSessionIsBusyS, "message": rpc.ErrSessionIsBusyS,
@@ -40,7 +40,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
gs.x.SLog.Debug("failed to read body", slog.String("err", err.Error())) gs.x.SLog.Debug("failed to read body", slog.String("err", err.Error()))
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
rpc.WriteError(w, &rpc.RPCResponse{ rpc.WriteError(gs.cs.UUID32, w, &rpc.RPCResponse{
JSONRPC: rpc.JSONRPCVersion, JSONRPC: rpc.JSONRPCVersion,
ID: nil, ID: nil,
Error: map[string]any{ Error: map[string]any{
@@ -60,7 +60,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
if err := json.Unmarshal(body, &single); err != nil { if err := json.Unmarshal(body, &single); err != nil {
gs.x.SLog.Debug("failed to parse json", slog.String("err", err.Error())) gs.x.SLog.Debug("failed to parse json", slog.String("err", err.Error()))
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
rpc.WriteError(w, &rpc.RPCResponse{ rpc.WriteError(gs.cs.UUID32, w, &rpc.RPCResponse{
JSONRPC: rpc.JSONRPCVersion, JSONRPC: rpc.JSONRPCVersion,
ID: nil, ID: nil,
Error: map[string]any{ Error: map[string]any{
@@ -76,7 +76,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("")) w.Write([]byte(""))
return return
} }
rpc.WriteResponse(w, resp) rpc.WriteResponse(gs.cs.UUID32, w, resp)
return return
} }

View File

@@ -15,6 +15,9 @@ type RPCResponse struct {
ID *json.RawMessage `json:"id"` ID *json.RawMessage `json:"id"`
Result any `json:"result,omitempty"` Result any `json:"result,omitempty"`
Error any `json:"error,omitempty"` Error any `json:"error,omitempty"`
ResponsibleNode string `json:"responsible-node,omitempty"`
Salt string `json:"salt,omitempty"`
Checksum string `json:"checksum-md5,omitempty"`
} }
const ( const (

View File

@@ -1,11 +1,40 @@
package rpc package rpc
import ( import (
"crypto/md5"
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"github.com/google/uuid"
) )
func write(w http.ResponseWriter, msg *RPCResponse) error { func generateChecksum(result any) string {
if result == nil {
return ""
}
data, err := json.Marshal(result)
if err != nil {
return ""
}
return fmt.Sprintf("%x", md5.Sum(data))
}
func generateSalt() string {
return uuid.NewString()
}
func write(nid string, w http.ResponseWriter, msg *RPCResponse) error {
msg.Salt = generateSalt()
if msg.Result != nil {
msg.Checksum = generateChecksum(msg.Result)
} else {
msg.Checksum = generateChecksum(msg.Error)
}
if nid != "" {
msg.ResponsibleNode = nid
}
data, err := json.Marshal(msg) data, err := json.Marshal(msg)
if err != nil { if err != nil {
return err return err
@@ -14,10 +43,10 @@ func write(w http.ResponseWriter, msg *RPCResponse) error {
return err return err
} }
func WriteError(w http.ResponseWriter, errm *RPCResponse) error { func WriteError(nid string, w http.ResponseWriter, errm *RPCResponse) error {
return write(w, errm) return write(nid, w, errm)
} }
func WriteResponse(w http.ResponseWriter, response *RPCResponse) error { func WriteResponse(nid string, w http.ResponseWriter, response *RPCResponse) error {
return write(w, response) return write(nid, w, response)
} }

View File

@@ -447,17 +447,13 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest,
sessionVal := loadedTbl.RawGetString("internal.session") sessionVal := loadedTbl.RawGetString("internal.session")
sessionTbl, ok := sessionVal.(*lua.LTable) sessionTbl, ok := sessionVal.(*lua.LTable)
if !ok { if !ok {
return rpc.NewResponse(map[string]any{ return rpc.NewResponse(nil, req.ID)
"responsible-node": h.cs.UUID32,
}, req.ID)
} }
tag := sessionTbl.RawGetString("__gosally_internal") tag := sessionTbl.RawGetString("__gosally_internal")
if tag.Type() != lua.LTString || tag.String() != fmt.Sprint(seed) { if tag.Type() != lua.LTString || tag.String() != fmt.Sprint(seed) {
llog.Debug("stock session module is not imported: wrong seed", slog.String("script", path)) llog.Debug("stock session module is not imported: wrong seed", slog.String("script", path))
return rpc.NewResponse(map[string]any{ return rpc.NewResponse(nil, req.ID)
"responsible-node": h.cs.UUID32,
}, req.ID)
} }
outVal := sessionTbl.RawGetString("response") outVal := sessionTbl.RawGetString("response")
@@ -500,6 +496,5 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest,
} else { } else {
payload["message"] = ConvertLuaTypesToGolang(resultVal) payload["message"] = ConvertLuaTypesToGolang(resultVal)
} }
payload["responsible-node"] = h.cs.UUID32
return rpc.NewResponse(payload, req.ID) return rpc.NewResponse(payload, req.ID)
} }