Redundant commit: only to switch branches. Can be removed.

This commit is contained in:
Jesse Malotaux 2025-04-04 11:52:48 +02:00
commit 59dd711ab3
102 changed files with 34954 additions and 0 deletions

102
be/app/helper/api-helper.go Normal file
View 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)
}
}

View 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
}

View 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
}

View 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
}

View 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)
}

View 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)
}
}
}