package localserver import ( "bytes" "context" "crypto/x509" "encoding/json" "encoding/pem" "fmt" "io" "log" "net/http" "os" "path/filepath" "github.com/google/uuid" ) var NodeToken string type LocalServerConfig struct { configFilePath string NodeId string `json:"nodeId"` PrivateKeyPath string `json:"privateKeyPath"` Token string `json:"token"` } func NewLocalServerConfig() (localServerConfig *LocalServerConfig, err error) { logFile, err := os.OpenFile(filepath.Join("local_server.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755) if err != nil { return } logger.SetOutput(logFile) logger.SetFlags(log.Ldate | log.LUTC | log.Lshortfile | log.Ltime | log.LstdFlags | log.Lmsgprefix) localServerConfig = &LocalServerConfig{ configFilePath: filepath.Join("config", "node_config.json"), } err = localServerConfig.startup() if err != nil { return } err = localServerConfig.authenticate() return } func (l *LocalServerConfig) startup() (err error) { if _, err = os.Stat(l.configFilePath); os.IsNotExist(err) { file, fileErr := os.Create(l.configFilePath) if fileErr != nil { return fileErr } id := uuid.NewString() e := NewEncryptionManager() keypair, keyErr := e.GenerateKeyPair(context.Background(), id, "") if keyErr != nil { return keyErr } baseConfig := map[string]interface{}{ "nodeId": id, "privKeyPath": filepath.Join("config", id), "token": "", } bs, marshallErr := json.Marshal(&baseConfig) if marshallErr != nil { return marshallErr } _, writeErr := file.Write(bs) if writeErr != nil { return writeErr } key_bytes := x509.MarshalPKCS1PublicKey(&keypair.PublicKey) key := pem.EncodeToMemory(&pem.Block{ Type: "RSA PUBLIC KEY", Bytes: key_bytes, }) logger.Println(string(key)) l.NodeId = id l.PrivateKeyPath = "" l.Token = "" bss, marshallErr := json.Marshal(map[string]interface{}{ "type": "create_node", "from": id, "to": "serv", "token": "", "peerType":"node", "payload": map[string]string{ "nodeId": id, "nodeKey": string(key), "nodeUsername": "anonymous", }, }) if marshallErr != nil { return marshallErr } res, postErr := http.Post("https://dev.zippytal.com/req", "application/json", bytes.NewBuffer(bss)) if postErr != nil { logger.Println("e") return postErr } logger.Println(res) if err = file.Close(); err != nil { return } } else if err != nil { return } file, err := os.Open(l.configFilePath) if err != nil { return } var config map[string]string err = json.NewDecoder(file).Decode(&config) if err != nil { return } logger.Println(config) l.NodeId = config["nodeId"] l.PrivateKeyPath = config["privKeyPath"] l.Token = config["token"] return } func (l *LocalServerConfig) authenticate() (err error) { f, err := os.Open(l.PrivateKeyPath) if err != nil { return } var buff []byte buff, err = io.ReadAll(f) if err != nil { return } em := NewEncryptionManager() sig, err := em.SignRequest(string(buff), l.NodeId) if err != nil { return } body, err := json.Marshal(map[string]interface{}{ "type": "login_key_node", "from": l.NodeId, "peerType":"node", "payload": map[string]string{ "id": l.NodeId, "signature": sig, }, }) if err != nil { return } res, err := http.Post("https://app.zippytal.com/req", "application/json", bytes.NewBuffer(body)) if err != nil { return } bs, err := io.ReadAll(res.Body) if err != nil { return } var payload map[string]any if err = json.Unmarshal(bs, &payload); err != nil { return } err = l.handleLoginResponse(payload) return } func (l *LocalServerConfig) handleLoginResponse(res map[string]any) (err error) { if _, ok := res["token"]; !ok { err = fmt.Errorf("no field token in res") return } if _, ok := res["token"].(string); !ok { err = fmt.Errorf("field token not string in res") return } NodeToken = res["token"].(string) return }