mirror of
https://github.com/Macrame-App/Macrame
synced 2025-12-29 15:29:26 +00:00
Redundant commit: only to switch branches. Can be removed.
This commit is contained in:
commit
59dd711ab3
102 changed files with 34954 additions and 0 deletions
102
be/app/helper/api-helper.go
Normal file
102
be/app/helper/api-helper.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"be/app/structs"
|
||||
. "be/app/structs"
|
||||
)
|
||||
|
||||
func EndpointAccess(w http.ResponseWriter, r *http.Request) (bool, string) {
|
||||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if (isLocal(ip) && isEndpointAllowed("Local", r.URL.Path)) ||
|
||||
(isLanRemote(ip) && isEndpointAllowed("Remote", r.URL.Path)) {
|
||||
log.Println(r.URL.Path, "endpoint access: accessible")
|
||||
return true, ""
|
||||
} else if isLanRemote(ip) && isEndpointAllowed("Auth", r.URL.Path) {
|
||||
log.Println(r.URL.Path, "endpoint access: authorized")
|
||||
|
||||
data := decryptAuth(r)
|
||||
|
||||
return data != "", data
|
||||
}
|
||||
|
||||
log.Println(r.URL.Path, "endpoint access: not authorized or accessible")
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func isLocal(ip string) bool {
|
||||
return ip == "127.0.0.1" || ip == "::1"
|
||||
}
|
||||
|
||||
func isLanRemote(ip string) bool {
|
||||
return strings.HasPrefix(ip, "192.168.")
|
||||
}
|
||||
|
||||
func isEndpointAllowed(source string, endpoint string) bool {
|
||||
var endpoints, err = getAllowedEndpoints(source)
|
||||
if err != "" {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
if (endpoints != nil) && (len(endpoints) > 0) {
|
||||
for _, e := range endpoints {
|
||||
if e == endpoint {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func getAllowedEndpoints(source string) (endpoints []string, err string) {
|
||||
if source == "Local" {
|
||||
return Endpoints.Local, ""
|
||||
}
|
||||
if source == "Remote" {
|
||||
return Endpoints.Remote, ""
|
||||
}
|
||||
if source == "Auth" {
|
||||
return Endpoints.Auth, ""
|
||||
}
|
||||
|
||||
return []string{}, "No allowed endpoints"
|
||||
}
|
||||
|
||||
func decryptAuth(r *http.Request) string {
|
||||
var req structs.Authcall
|
||||
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
|
||||
if err != nil || req.Uuid == "" || req.Data == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
deviceKey, errKey := GetKeyByUuid(req.Uuid)
|
||||
decryptData, errDec := DecryptAES(deviceKey, req.Data)
|
||||
|
||||
if errKey != nil && errDec != nil || decryptData == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return decryptData
|
||||
}
|
||||
|
||||
func ParseRequest(req interface{}, data string, r *http.Request) (d interface{}, err error) {
|
||||
if data != "" {
|
||||
dataBytes := []byte(data)
|
||||
return req, json.Unmarshal(dataBytes, &req)
|
||||
} else {
|
||||
return req, json.NewDecoder(r.Body).Decode(&req)
|
||||
}
|
||||
}
|
||||
23
be/app/helper/browser-helper.go
Normal file
23
be/app/helper/browser-helper.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func OpenBrowser(url string) bool {
|
||||
var args []string
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
args = []string{"open"}
|
||||
case "windows":
|
||||
args = []string{"cmd", "/c", "start"}
|
||||
default:
|
||||
args = []string{"xdg-open"}
|
||||
}
|
||||
|
||||
cmd := exec.Command(args[0], append(args[1:], url)...)
|
||||
|
||||
return cmd.Start() == nil
|
||||
}
|
||||
46
be/app/helper/device-helper.go
Normal file
46
be/app/helper/device-helper.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TempPinFile(Uuid string, pin string) bool {
|
||||
log.Println("temp pin file", Uuid, pin)
|
||||
err := os.WriteFile("devices/"+Uuid+".tmp", []byte(pin), 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return false
|
||||
}
|
||||
|
||||
time.AfterFunc(1*time.Minute, func() {
|
||||
log.Println("deleting", Uuid, pin)
|
||||
os.Remove("devices/" + Uuid + ".tmp")
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func CheckPinFile(Uuid string) bool {
|
||||
_, err := os.Stat("devices/" + Uuid + ".tmp")
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func SaveDeviceKey(Uuid string, key string) error {
|
||||
err := os.WriteFile("devices/"+Uuid+".key", []byte(key), 0644)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetKeyByUuid(Uuid string) (string, error) {
|
||||
data, err := os.ReadFile("devices/" + Uuid + ".key")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
105
be/app/helper/encrypt-helper.go
Normal file
105
be/app/helper/encrypt-helper.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func EncryptAES(key string, plaintext string) (string, error) {
|
||||
origData := []byte(plaintext)
|
||||
|
||||
// Create AES cipher
|
||||
block, err := aes.NewCipher(keyToBytes(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
blockSize := block.BlockSize()
|
||||
|
||||
origData = PKCS5Padding(origData, blockSize)
|
||||
|
||||
iv := []byte(EnvGet("MCRM__IV"))
|
||||
blockMode := cipher.NewCBCEncrypter(block, iv)
|
||||
|
||||
crypted := make([]byte, len(origData))
|
||||
blockMode.CryptBlocks(crypted, origData)
|
||||
|
||||
cryptedString := base64.StdEncoding.EncodeToString(crypted)
|
||||
|
||||
return cryptedString, nil
|
||||
}
|
||||
|
||||
func DecryptAES(key string, cryptedText string) (string, error) {
|
||||
crypted, err := base64.StdEncoding.DecodeString(cryptedText)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(keyToBytes(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
iv := []byte(EnvGet("MCRM__IV"))
|
||||
blockMode := cipher.NewCBCDecrypter(block, iv)
|
||||
|
||||
origData := make([]byte, len(crypted))
|
||||
|
||||
blockMode.CryptBlocks(origData, crypted)
|
||||
origData, err = PKCS5UnPadding(origData)
|
||||
|
||||
if err != nil || len(origData) <= 3 {
|
||||
return "", errors.New("invalid key")
|
||||
}
|
||||
|
||||
origDataString := string(origData)
|
||||
|
||||
return origDataString, nil
|
||||
}
|
||||
|
||||
func generateRandomString(length int) string {
|
||||
b := make([]byte, length)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(b)
|
||||
}
|
||||
|
||||
func GenerateKey() string {
|
||||
return strings.Replace(generateRandomString(24), "=", "", -1)
|
||||
}
|
||||
|
||||
func keyToBytes(key string) []byte {
|
||||
// Convert key to bytes
|
||||
keyBytes := []byte(key)
|
||||
|
||||
// If key is 4 characters, append salt
|
||||
if len(key) == 4 {
|
||||
keyBytes = []byte(key + EnvGet("MCRM__SALT"))
|
||||
}
|
||||
|
||||
return keyBytes
|
||||
}
|
||||
|
||||
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(ciphertext)%blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(ciphertext, padtext...)
|
||||
}
|
||||
|
||||
func PKCS5UnPadding(origData []byte) ([]byte, error) {
|
||||
length := len(origData)
|
||||
unpadding := int(origData[length-1])
|
||||
|
||||
if (unpadding >= length) || (unpadding == 0) {
|
||||
return nil, errors.New("unpadding error")
|
||||
}
|
||||
|
||||
return origData[:(length - unpadding)], nil
|
||||
}
|
||||
16
be/app/helper/env-helper.go
Normal file
16
be/app/helper/env-helper.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func EnvGet(key string) string {
|
||||
err := godotenv.Load("../.env")
|
||||
if err != nil {
|
||||
log.Fatal("Error loading .env file")
|
||||
}
|
||||
return os.Getenv("VITE_" + key)
|
||||
}
|
||||
64
be/app/helper/macro-helper.go
Normal file
64
be/app/helper/macro-helper.go
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
package helper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be/app/structs"
|
||||
|
||||
"github.com/go-vgo/robotgo"
|
||||
)
|
||||
|
||||
func FormatMacroFileName(s string) string {
|
||||
// Remove invalid characters
|
||||
re := regexp.MustCompile(`[\/\?\*\>\<\:\\"\|\n]`)
|
||||
s = re.ReplaceAllString(s, "")
|
||||
|
||||
// Replace spaces with underscores
|
||||
s = strings.ReplaceAll(s, " ", "_")
|
||||
|
||||
// Remove special characters
|
||||
re = regexp.MustCompile(`[!@#$%^&\(\)\[\]\{\}\~]`)
|
||||
s = re.ReplaceAllString(s, "")
|
||||
|
||||
// Truncate the string
|
||||
if len(s) > 255 {
|
||||
s = s[:255]
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func ReadMacroFile(filename string) (steps []structs.Step, err error) {
|
||||
log.Println(filename)
|
||||
|
||||
content, err := os.ReadFile(filename)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("Error when opening file: ", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(content, &steps)
|
||||
|
||||
return steps, err
|
||||
}
|
||||
|
||||
func RunMacroSteps(steps []structs.Step) {
|
||||
for _, step := range steps {
|
||||
// log.Println(step)
|
||||
switch step.Type {
|
||||
case "key":
|
||||
robotgo.KeyToggle(step.Key, step.Direction)
|
||||
// log.Println("Toggling", step.Key, "to", step.Direction)
|
||||
case "delay":
|
||||
time.Sleep(time.Duration(step.Location) * time.Millisecond)
|
||||
// log.Println("Sleeping for", step.Value, "milliseconds")
|
||||
default:
|
||||
log.Println("Unknown step type:", step.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue