separate frontend repository

This commit is contained in:
Alireza Ahmadi
2025-01-28 23:57:53 +01:00
parent f4b1b09362
commit 7faa28a89d
194 changed files with 48 additions and 19256 deletions
+229
View File
@@ -0,0 +1,229 @@
package service
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"net"
"net/http"
"os"
"s-ui/database/model"
"s-ui/logger"
"s-ui/util/common"
"strconv"
"time"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
type WarpService struct{}
func (s *WarpService) getWarpInfo(ep *model.Endpoint) ([]byte, error) {
var warpData map[string]string
err := json.Unmarshal(ep.Ext, &warpData)
if err != nil {
return nil, err
}
url := fmt.Sprintf("https://api.cloudflareclient.com/v0a2158/reg/%s", warpData["device_id"])
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+warpData["access_token"])
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
buffer := bytes.NewBuffer(make([]byte, 8192))
buffer.Reset()
_, err = buffer.ReadFrom(resp.Body)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func (s *WarpService) RegisterWarp(ep *model.Endpoint) error {
tos := time.Now().UTC().Format("2006-01-02T15:04:05.000Z")
privateKey, _ := wgtypes.GenerateKey()
publicKey := privateKey.PublicKey().String()
hostName, _ := os.Hostname()
data := fmt.Sprintf(`{"key":"%s","tos":"%s","type": "PC","model": "s-ui", "name": "%s"}`, publicKey, tos, hostName)
url := "https://api.cloudflareclient.com/v0a2158/reg"
req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(data)))
if err != nil {
return err
}
req.Header.Add("CF-Client-Version", "a-7.21-0721")
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
buffer := bytes.NewBuffer(make([]byte, 8192))
buffer.Reset()
_, err = buffer.ReadFrom(resp.Body)
if err != nil {
return err
}
var rspData map[string]interface{}
err = json.Unmarshal(buffer.Bytes(), &rspData)
if err != nil {
return err
}
deviceId := rspData["id"].(string)
token := rspData["token"].(string)
license, ok := rspData["account"].(map[string]interface{})["license"].(string)
if !ok {
logger.Debug("Error accessing license value.")
return err
}
warpData := map[string]string{
"access_token": token,
"device_id": deviceId,
"license_key": license,
}
ep.Ext, err = json.MarshalIndent(warpData, "", " ")
if err != nil {
return err
}
warpInfo, err := s.getWarpInfo(ep)
if err != nil {
return err
}
var warpDetails map[string]interface{}
err = json.Unmarshal(warpInfo, &warpDetails)
if err != nil {
return err
}
warpConfig, _ := warpDetails["config"].(map[string]interface{})
clientId, _ := warpConfig["client_id"].(string)
reserved := s.getReserved(clientId)
interfaceConfig, _ := warpConfig["interface"].(map[string]interface{})
addresses, _ := interfaceConfig["addresses"].(map[string]interface{})
v4, _ := addresses["v4"].(string)
v6, _ := addresses["v6"].(string)
peer, _ := warpConfig["peers"].([]interface{})[0].(map[string]interface{})
peerEndpoint, _ := peer["endpoint"].(map[string]interface{})["host"].(string)
peerEpAddress, peerEpPort, err := net.SplitHostPort(peerEndpoint)
if err != nil {
return err
}
peerPublicKey, _ := peer["public_key"].(string)
peerPort, _ := strconv.Atoi(peerEpPort)
peers := []map[string]interface{}{
{
"address": peerEpAddress,
"port": peerPort,
"public_key": peerPublicKey,
"allowed_ips": []string{"0.0.0.0/0", "::/0"},
"reserved": reserved,
},
}
var epOptions map[string]interface{}
err = json.Unmarshal(ep.Options, &epOptions)
if err != nil {
return err
}
epOptions["private_key"] = privateKey.String()
epOptions["address"] = []string{fmt.Sprintf("%s/32", v4), fmt.Sprintf("%s/128", v6)}
epOptions["listen_port"] = 0
epOptions["peers"] = peers
ep.Options, err = json.MarshalIndent(epOptions, "", " ")
return err
}
func (s *WarpService) getReserved(clientID string) []int {
var reserved []int
decoded, err := base64.StdEncoding.DecodeString(clientID)
if err != nil {
return nil
}
hexString := ""
for _, char := range decoded {
hex := fmt.Sprintf("%02x", char)
hexString += hex
}
for i := 0; i < len(hexString); i += 2 {
hexByte := hexString[i : i+2]
decValue, err := strconv.ParseInt(hexByte, 16, 32)
if err != nil {
return nil
}
reserved = append(reserved, int(decValue))
}
return reserved
}
func (s *WarpService) SetWarpLicense(old_license string, ep *model.Endpoint) error {
var warpData map[string]string
err := json.Unmarshal(ep.Ext, &warpData)
if err != nil {
return err
}
if warpData["license_key"] == old_license {
return nil
}
url := fmt.Sprintf("https://api.cloudflareclient.com/v0a2158/reg/%s/account", warpData["device_id"])
data := fmt.Sprintf(`{"license": "%s"}`, warpData["license_key"])
req, err := http.NewRequest("PUT", url, bytes.NewBuffer([]byte(data)))
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+warpData["access_token"])
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
buffer := bytes.NewBuffer(make([]byte, 8192))
buffer.Reset()
_, err = buffer.ReadFrom(resp.Body)
if err != nil {
return err
}
var response map[string]interface{}
err = json.Unmarshal(buffer.Bytes(), &response)
if err != nil {
return err
}
if success, ok := response["success"].(bool); ok && success == false {
errorArr, _ := response["errors"].([]interface{})
errorObj := errorArr[0].(map[string]interface{})
return common.NewError(errorObj["code"], errorObj["message"])
}
return nil
}