Files
H2Node/app/routes.go
2026-02-27 13:23:16 +03:00

200 lines
3.8 KiB
Go

package app
import (
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"strconv"
)
type AddUserReq struct {
Token string `json:"token"`
Username string `json:"username"`
Password string `json:"password"`
}
type AddUserRsp struct {
ID int `json:"id"`
Username string `json:"username"`
}
func AddUser(w http.ResponseWriter, r *http.Request) {
log.Println("AddUser called")
req, err := ReadBody[AddUserReq](r)
if err != nil {
WriteError(w, err)
return
}
if req.Token != cfg.JWTSecret {
WriteError(w, errors.New("token required"))
return
}
provider, err := LoadProvider()
if err != nil {
WriteError(w, err)
return
}
err = provider.AddUser(req.Username, req.Password)
if err != nil {
WriteError(w, err)
return
}
err = provider.Save()
if err != nil {
WriteError(w, err)
}
user, err := provider.GetUser(req.Password)
if err != nil {
WriteError(w, err)
return
}
WriteResponseCode(w, user, http.StatusCreated)
}
type DeleteUserReq struct {
Token string `json:"token"`
ID int `json:"id"`
}
func DeleteUser(w http.ResponseWriter, r *http.Request) {
req, err := ReadBody[DeleteUserReq](r)
if err != nil {
WriteError(w, err)
return
}
if req.Token != cfg.JWTSecret {
WriteError(w, errors.New("invalid token"))
return
}
provider, err := LoadProvider()
if err != nil {
WriteError(w, err)
return
}
err = provider.DeleteUser(req.ID)
if err != nil {
WriteError(w, err)
return
}
err = provider.Save()
if err != nil {
WriteError(w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
type AllUserReq struct {
Token string `json:"token"`
}
func AllUsers(w http.ResponseWriter, r *http.Request) {
fmt.Println("AllUsers called")
req, err := ReadBody[AllUserReq](r)
if err != nil {
WriteError(w, err)
return
}
if req.Token != cfg.JWTSecret {
WriteError(w, errors.New("invalid token"))
return
}
provider, err := LoadProvider()
if err != nil {
WriteError(w, err)
return
}
WriteResponse(w, provider)
}
type GetConnectURLReq struct {
ID int `json:"id"`
Pass string `json:"pass"`
}
func GetUserURL(w http.ResponseWriter, r *http.Request) {
vars := r.URL.Query()
idS := vars.Get("id")
id, err := strconv.Atoi(idS)
if err != nil {
WriteError(w, err)
return
}
provider, err := LoadProvider()
if err != nil {
WriteError(w, err)
return
}
user, err := provider.GetById(id)
if err != nil {
WriteError(w, err)
return
}
urlTemplate := "hysteria2://%s@%s:%s?obfs=salamander&obfs-password=%s&type=hysteria&mport&security=tls&sni=%s&alpn=h3&fp=chrome&allowInsecure=0#%s"
authString := encodeURL(user)
u := fmt.Sprintf(urlTemplate, authString, cfg.Host, cfg.Port, cfg.ObfsPassword, cfg.SNI, formatConfigName(cfg.NameFormat, user))
WriteResponse(w, u)
}
type AuthReq struct {
Addr string `json:"addr"`
Auth string `json:"auth"`
Tx int `json:"tx"`
}
type AuthRsp struct {
Ok bool `json:"ok"`
ID string `json:"id"`
}
func DoAuth(w http.ResponseWriter, r *http.Request) {
data, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
log.Println(err)
return
}
req := new(AuthReq)
if err := json.Unmarshal(data, req); err != nil {
w.WriteHeader(http.StatusBadRequest)
log.Println(err)
return
}
log.Printf("New auth request from %s, data %s", req.Addr, string(data))
reqUser, err := decodeURL(req.Auth)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
provider, err := LoadProvider()
if err != nil {
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
user, err := provider.GetUser(reqUser.Password)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
res := &AuthRsp{true, user.Username}
err = json.NewEncoder(w).Encode(res)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
} else {
w.WriteHeader(http.StatusOK)
}
}