e06153b6f4
fix bug for Array
1414 lines
42 KiB
Go
1414 lines
42 KiB
Go
package util
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto"
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/hmac"
|
|
"crypto/md5"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/sha1"
|
|
"crypto/sha256"
|
|
"crypto/sha512"
|
|
"crypto/x509"
|
|
_ "embed"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"encoding/pem"
|
|
"errors"
|
|
"math/big"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"runtime"
|
|
"strings"
|
|
"text/template"
|
|
"time"
|
|
|
|
"apigo.cc/gojs"
|
|
"apigo.cc/gojs/goja"
|
|
"github.com/ZZMarquis/gm/sm3"
|
|
"github.com/ZZMarquis/gm/sm4"
|
|
"github.com/ZZMarquis/gm/util"
|
|
"github.com/emmansun/gmsm/sm2"
|
|
"github.com/emmansun/gmsm/smx509"
|
|
"github.com/obscuren/ecies"
|
|
"github.com/ssgo/u"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
//go:embed util.ts
|
|
var utilTS string
|
|
|
|
//go:embed README.md
|
|
var utilMD string
|
|
|
|
var envConfigs map[string]map[string]any
|
|
var confAes = u.NewAes([]byte("?GQ$0K0GgLdO=f+~L68PLm$uhKr4'=tV"), []byte("VFs7@sK61cj^f?HZ"))
|
|
var keysIsSet = false
|
|
|
|
func SetSSKey(key, iv []byte) {
|
|
if !keysIsSet {
|
|
confAes = u.NewAes(key, iv)
|
|
keysIsSet = true
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
obj := map[string]any{
|
|
"json": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
if r, err := json.Marshal(args.Arguments[0].Export()); err == nil {
|
|
return vm.ToValue(string(r))
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"jsonP": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
if r, err := json.Marshal(args.Arguments[0].Export()); err == nil {
|
|
r1 := bytes.Buffer{}
|
|
if err2 := json.Indent(&r1, r, "", " "); err2 == nil {
|
|
return vm.ToValue(string(r))
|
|
} else {
|
|
return vm.ToValue(string(r))
|
|
}
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"unJson": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
var r any
|
|
if err := json.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"yaml": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
if r, err := yaml.Marshal(args.Arguments[0].Export()); err == nil {
|
|
return vm.ToValue(string(r))
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"unYaml": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
var r any
|
|
if err := yaml.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"save": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
filename := args.Str(0)
|
|
var data []byte
|
|
var err error
|
|
if strings.HasSuffix(filename, ".yml") || strings.HasSuffix(filename, ".yaml") {
|
|
data, err = yaml.Marshal(args.Any(1))
|
|
} else {
|
|
data, err = json.Marshal(args.Any(1))
|
|
}
|
|
if err == nil {
|
|
if err = u.WriteFileBytes(gojs.FindPath(vm, filename), data); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
return nil
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"load": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
filename := args.Str(0)
|
|
if data, err := u.ReadFileBytes(gojs.FindPath(vm, filename)); err == nil {
|
|
var r any
|
|
if strings.HasSuffix(filename, ".yml") || strings.HasSuffix(filename, ".yaml") {
|
|
err = yaml.Unmarshal(data, &r)
|
|
} else {
|
|
err = json.Unmarshal(data, &r)
|
|
}
|
|
if err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"base64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.Base64(u.Bytes(args.Arguments[0].Export())))
|
|
},
|
|
"unBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.UnBase64(args.Str(0)))
|
|
},
|
|
"urlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.UrlBase64String(args.Str(0)))
|
|
},
|
|
"unUrlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.UnUrlBase64(args.Str(0)))
|
|
},
|
|
"hex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(hex.EncodeToString(u.Bytes(args.Arguments[0].Export())))
|
|
},
|
|
"unHex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
if r, err := hex.DecodeString(args.Str(0)); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"aes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(3)
|
|
if r, err := u.EncryptAesBytes(u.Bytes(args.Arguments[0].Export()), u.Bytes(args.Arguments[1].Export()), u.Bytes(args.Arguments[2].Export())); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"unAes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(3)
|
|
if r, err := u.DecryptAesBytes(u.Bytes(args.Arguments[0].Export()), u.Bytes(args.Arguments[1].Export()), u.Bytes(args.Arguments[2].Export())); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"sm4": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(3)
|
|
if r, err := sm4.CBCEncrypt(u.Bytes(args.Arguments[1].Export())[0:16], u.Bytes(args.Arguments[2].Export())[0:16], util.PKCS5Padding(u.Bytes(args.Arguments[0].Export()), 16)); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"unSM4": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(3)
|
|
if r, err := sm4.CBCDecrypt(u.Bytes(args.Arguments[1].Export())[0:16], u.Bytes(args.Arguments[2].Export())[0:16], u.Bytes(args.Arguments[0].Export())); err == nil {
|
|
if length := len(r); length > 0 {
|
|
if unpadding := int(r[length-1]); length-unpadding >= 0 {
|
|
r = util.PKCS5UnPadding(r)
|
|
}
|
|
}
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"genECDSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
var curve elliptic.Curve
|
|
switch args.Int(0) {
|
|
case 521:
|
|
curve = elliptic.P521()
|
|
case 384:
|
|
curve = elliptic.P384()
|
|
default:
|
|
curve = elliptic.P256()
|
|
}
|
|
pri, err := ecdsa.GenerateKey(curve, u.GlobalRand2)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
var buf bytes.Buffer
|
|
buf.WriteByte(byte(len(pri.X.Bytes())))
|
|
buf.Write(pri.X.Bytes())
|
|
buf.Write(pri.Y.Bytes())
|
|
return vm.ToValue([][]byte{pri.D.Bytes(), buf.Bytes()})
|
|
},
|
|
"exportECDSAPrivateKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
priKey := makeECDSAPriKey(args.Bytes(0))
|
|
priBytes, err := x509.MarshalPKCS8PrivateKey(priKey)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
pemBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PRIVATE KEY",
|
|
Bytes: priBytes,
|
|
})
|
|
return vm.ToValue(string(pemBytes))
|
|
},
|
|
"exportECDSAPublicKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
pubKey := makeECDSAPubKey(args.Bytes(0))
|
|
pubBytes, err := x509.MarshalPKIXPublicKey(pubKey)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
pemBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: pubBytes,
|
|
})
|
|
return vm.ToValue(string(pemBytes))
|
|
},
|
|
"importECDSAKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
keyText := args.Str(0)
|
|
keyType := args.Str(1)
|
|
var keyBytes []byte
|
|
if strings.Contains(keyText, "-----BEGIN PRIVATE KEY-----") {
|
|
keyType = "private"
|
|
if block, _ := pem.Decode([]byte(keyText)); block == nil {
|
|
panic(vm.NewGoError(errors.New("bad private pem key")))
|
|
} else {
|
|
keyBytes = block.Bytes
|
|
}
|
|
} else if strings.Contains(keyText, "-----BEGIN PUBLIC KEY-----") {
|
|
keyType = "public"
|
|
if block, _ := pem.Decode([]byte(keyText)); block == nil {
|
|
panic(vm.NewGoError(errors.New("bad public pem key")))
|
|
} else {
|
|
keyBytes = block.Bytes
|
|
}
|
|
} else {
|
|
var err error
|
|
if keyBytes, err = base64.StdEncoding.DecodeString(keyText); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
}
|
|
|
|
if keyType == "private" {
|
|
if priKey, err := x509.ParsePKCS8PrivateKey(keyBytes); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
if ecdsaPriKey, ok := priKey.(*ecdsa.PrivateKey); !ok {
|
|
panic(vm.NewGoError(errors.New("bad private key")))
|
|
} else {
|
|
return vm.ToValue(ecdsaPriKey.D.Bytes())
|
|
}
|
|
}
|
|
} else {
|
|
if pubKey, err := x509.ParsePKIXPublicKey(keyBytes); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
if ecdsaPubKey, ok := pubKey.(*ecdsa.PublicKey); !ok {
|
|
panic(vm.NewGoError(errors.New("bad public key")))
|
|
} else {
|
|
var buf bytes.Buffer
|
|
buf.WriteByte(byte(len(ecdsaPubKey.X.Bytes())))
|
|
buf.Write(ecdsaPubKey.X.Bytes())
|
|
buf.Write(ecdsaPubKey.Y.Bytes())
|
|
return vm.ToValue(buf.Bytes())
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"signECDSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
priKey := makeECDSAPriKey(args.Bytes(1))
|
|
r, s, err := ecdsa.Sign(u.GlobalRand1, priKey, u.Sha256(data))
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
var buf bytes.Buffer
|
|
buf.WriteByte(byte(len(r.Bytes())))
|
|
buf.Write(r.Bytes())
|
|
buf.Write(s.Bytes())
|
|
return vm.ToValue(buf.Bytes())
|
|
},
|
|
"verifyECDSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(3)
|
|
data := args.Bytes(0)
|
|
signature := args.Bytes(1)
|
|
pubKey := makeECDSAPubKey(args.Bytes(2))
|
|
byteLen := signature[0]
|
|
r := new(big.Int)
|
|
s := new(big.Int)
|
|
r.SetBytes(signature[1 : byteLen+1])
|
|
s.SetBytes(signature[byteLen+1:])
|
|
return vm.ToValue(ecdsa.Verify(pubKey, u.Sha256(data), r, s))
|
|
},
|
|
"encryptECDSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
pubKey := makeECDSAPubKey(args.Bytes(1))
|
|
eciesPubKey := ecies.ImportECDSAPublic(pubKey)
|
|
if r, err := ecies.Encrypt(u.GlobalRand1, eciesPubKey, data, nil, nil); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
return vm.ToValue(r)
|
|
}
|
|
},
|
|
"decryptECDSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
priKey := makeECDSAPriKey(args.Bytes(1))
|
|
eciesPriKey := ecies.ImportECDSA(priKey)
|
|
if r, err := eciesPriKey.Decrypt(u.GlobalRand1, data, nil, nil); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
return vm.ToValue(r)
|
|
}
|
|
},
|
|
"genSM2": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
if pri, err := sm2.GenerateKey(u.GlobalRand2); err == nil {
|
|
var buf bytes.Buffer
|
|
buf.WriteByte(byte(len(pri.X.Bytes())))
|
|
buf.Write(pri.X.Bytes())
|
|
buf.Write(pri.Y.Bytes())
|
|
return vm.ToValue([][]byte{pri.D.Bytes(), buf.Bytes()})
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"exportSM2PrivateKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
priKey := makePriKey(args.Bytes(0), sm2.P256())
|
|
priBytes, err := smx509.MarshalECPrivateKey(priKey)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
pemBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PRIVATE KEY",
|
|
Bytes: priBytes,
|
|
})
|
|
return vm.ToValue(string(pemBytes))
|
|
},
|
|
"exportSM2PublicKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
pubKey := makePubKey(args.Bytes(0), sm2.P256())
|
|
pubBytes, err := smx509.MarshalPKIXPublicKey(pubKey)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
pemBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: pubBytes,
|
|
})
|
|
return vm.ToValue(string(pemBytes))
|
|
},
|
|
"importSM2Key": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
keyText := args.Str(0)
|
|
keyType := args.Str(1)
|
|
var keyBytes []byte
|
|
if strings.Contains(keyText, "-----BEGIN PRIVATE KEY-----") {
|
|
keyType = "private"
|
|
if block, _ := pem.Decode([]byte(keyText)); block == nil {
|
|
panic(vm.NewGoError(errors.New("bad private pem key")))
|
|
} else {
|
|
keyBytes = block.Bytes
|
|
}
|
|
} else if strings.Contains(keyText, "-----BEGIN PUBLIC KEY-----") {
|
|
keyType = "public"
|
|
if block, _ := pem.Decode([]byte(keyText)); block == nil {
|
|
panic(vm.NewGoError(errors.New("bad public pem key")))
|
|
} else {
|
|
keyBytes = block.Bytes
|
|
}
|
|
} else {
|
|
var err error
|
|
if keyBytes, err = base64.StdEncoding.DecodeString(keyText); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
}
|
|
|
|
if keyType == "private" {
|
|
if priKey, err := smx509.ParseECPrivateKey(keyBytes); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
return vm.ToValue(priKey.D.Bytes())
|
|
}
|
|
} else {
|
|
if pubKey, err := smx509.ParsePKIXPublicKey(keyBytes); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
if sm2PubKey, ok := pubKey.(*ecdsa.PublicKey); !ok {
|
|
panic(vm.NewGoError(errors.New("bad public key")))
|
|
} else {
|
|
var buf bytes.Buffer
|
|
buf.WriteByte(byte(len(sm2PubKey.X.Bytes())))
|
|
buf.Write(sm2PubKey.X.Bytes())
|
|
buf.Write(sm2PubKey.Y.Bytes())
|
|
return vm.ToValue(buf.Bytes())
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"signSM2": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
priKey := makePriKey(args.Bytes(1), sm2.P256())
|
|
if r, s, err := sm2.SignWithSM2(u.GlobalRand1, priKey, nil, data); err == nil {
|
|
var buf bytes.Buffer
|
|
buf.WriteByte(byte(len(r.Bytes())))
|
|
buf.Write(r.Bytes())
|
|
buf.Write(s.Bytes())
|
|
return vm.ToValue(buf.Bytes())
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"verifySM2": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(3)
|
|
data := args.Bytes(0)
|
|
signature := args.Bytes(1)
|
|
pubKey := makePubKey(args.Bytes(2), sm2.P256())
|
|
byteLen := signature[0]
|
|
r := new(big.Int)
|
|
s := new(big.Int)
|
|
r.SetBytes(signature[1 : byteLen+1])
|
|
s.SetBytes(signature[byteLen+1:])
|
|
return vm.ToValue(sm2.VerifyWithSM2(pubKey, nil, data, r, s))
|
|
},
|
|
"encryptSM2": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
pubKey := makePubKey(args.Bytes(1), sm2.P256())
|
|
if r, err := sm2.Encrypt(u.GlobalRand1, pubKey, data, nil); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"decryptSM2": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
priKey := makePriKey(args.Bytes(1), sm2.P256())
|
|
if r, err := sm2.Decrypt(&sm2.PrivateKey{PrivateKey: *priKey}, data); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
|
|
"genRSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
size := args.Int(0)
|
|
if size == 0 {
|
|
size = 2048
|
|
}
|
|
key, err := rsa.GenerateKey(rand.Reader, size)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
priBytes := x509.MarshalPKCS1PrivateKey(key)
|
|
pubBytes := x509.MarshalPKCS1PublicKey(&key.PublicKey)
|
|
return vm.ToValue([][]byte{priBytes, pubBytes})
|
|
},
|
|
"exportRSAPrivateKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
priKey := makeRSAPriKey(args.Bytes(0))
|
|
priBytes := x509.MarshalPKCS1PrivateKey(priKey)
|
|
pemBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PRIVATE KEY",
|
|
Bytes: priBytes,
|
|
})
|
|
return vm.ToValue(string(pemBytes))
|
|
},
|
|
"exportRSAPublicKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
pubKey := makeRSAPubKey(args.Bytes(0))
|
|
pubBytes := x509.MarshalPKCS1PublicKey(pubKey)
|
|
pemBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PUBLIC KEY",
|
|
Bytes: pubBytes,
|
|
})
|
|
return vm.ToValue(string(pemBytes))
|
|
},
|
|
"importRSAKey": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
keyText := args.Str(0)
|
|
keyType := args.Str(1)
|
|
var keyBytes []byte
|
|
if strings.Contains(keyText, "-----BEGIN RSA PRIVATE KEY-----") {
|
|
keyType = "private"
|
|
if block, _ := pem.Decode([]byte(keyText)); block == nil {
|
|
panic(vm.NewGoError(errors.New("bad private pem key")))
|
|
} else {
|
|
keyBytes = block.Bytes
|
|
}
|
|
} else if strings.Contains(keyText, "-----BEGIN RSA PUBLIC KEY-----") {
|
|
keyType = "public"
|
|
if block, _ := pem.Decode([]byte(keyText)); block == nil {
|
|
panic(vm.NewGoError(errors.New("bad public pem key")))
|
|
} else {
|
|
keyBytes = block.Bytes
|
|
}
|
|
} else {
|
|
var err error
|
|
if keyBytes, err = base64.StdEncoding.DecodeString(keyText); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
}
|
|
|
|
if keyType == "private" {
|
|
if priKey, err := x509.ParsePKCS1PrivateKey(keyBytes); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
return vm.ToValue(x509.MarshalPKCS1PrivateKey(priKey))
|
|
}
|
|
} else {
|
|
if pubKey, err := x509.ParsePKCS1PublicKey(keyBytes); err != nil {
|
|
panic(vm.NewGoError(err))
|
|
} else {
|
|
return vm.ToValue(x509.MarshalPKCS1PublicKey(pubKey))
|
|
}
|
|
}
|
|
},
|
|
"signRSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
priKey := makeRSAPriKey(args.Bytes(1))
|
|
signature, err := rsa.SignPKCS1v15(rand.Reader, priKey, crypto.SHA256, u.Sha256(data))
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
return vm.ToValue(signature)
|
|
},
|
|
"verifyRSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(3)
|
|
data := args.Bytes(0)
|
|
signature := args.Bytes(1)
|
|
pubKey := makeRSAPubKey(args.Bytes(2))
|
|
err := rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, u.Sha256(data), signature)
|
|
return vm.ToValue(err == nil)
|
|
},
|
|
"encryptRSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
pubKey := makeRSAPubKey(args.Bytes(1))
|
|
encryptedData, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, data, nil)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
return vm.ToValue(encryptedData)
|
|
},
|
|
"decryptRSA": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
data := args.Bytes(0)
|
|
priKey := makeRSAPriKey(args.Bytes(1))
|
|
decryptedData, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priKey, data, nil)
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
return vm.ToValue(decryptedData)
|
|
},
|
|
|
|
"gzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
if r, err := u.Gzip(u.Bytes(args.Arguments[0].Export())); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"gunzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
if r, err := u.Gunzip(u.Bytes(args.Arguments[0].Export())); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"uniqueId": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
size := args.Int(0)
|
|
var id string
|
|
if size >= 20 {
|
|
id = u.UniqueId()
|
|
} else if size >= 16 {
|
|
id = u.UniqueId()[0:16]
|
|
} else if size >= 14 {
|
|
id = u.ShortUniqueId()
|
|
} else if size >= 12 {
|
|
id = u.ShortUniqueId()[0:12]
|
|
} else {
|
|
id = u.UniqueId()
|
|
}
|
|
return vm.ToValue(id)
|
|
},
|
|
"uniqueIdL": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
size := args.Int(0)
|
|
var id string
|
|
if size >= 20 {
|
|
id = u.UniqueId()
|
|
} else if size >= 16 {
|
|
id = u.UniqueId()[0:16]
|
|
} else if size >= 14 {
|
|
id = u.ShortUniqueId()
|
|
} else if size >= 12 {
|
|
id = u.ShortUniqueId()[0:12]
|
|
} else {
|
|
id = u.UniqueId()
|
|
}
|
|
return vm.ToValue(strings.ToLower(id))
|
|
},
|
|
"id": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
size := args.Int(0)
|
|
var id string
|
|
if size >= 12 {
|
|
id = u.Id12()
|
|
} else if size >= 10 {
|
|
id = u.Id10()
|
|
} else if size >= 8 {
|
|
id = u.Id8()
|
|
} else {
|
|
id = u.Id6()
|
|
}
|
|
return vm.ToValue(id)
|
|
},
|
|
"idL": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
size := args.Int(0)
|
|
var id string
|
|
if size >= 12 {
|
|
id = u.Id12()
|
|
} else if size >= 10 {
|
|
id = u.Id10()
|
|
} else if size >= 8 {
|
|
id = u.Id8()
|
|
} else {
|
|
id = u.Id6()
|
|
}
|
|
return vm.ToValue(strings.ToLower(id))
|
|
},
|
|
"token": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
size := args.Int(0)
|
|
if size == 0 {
|
|
size = 20
|
|
}
|
|
return vm.ToValue(u.MakeToken(size))
|
|
},
|
|
"md5": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
hash := md5.New()
|
|
for _, v := range args.Array(0) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"sha1": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
hash := sha1.New()
|
|
for _, v := range args.Array(0) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"sha256": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
hash := sha256.New()
|
|
for _, v := range args.Array(0) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"sha512": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
hash := sha512.New()
|
|
for _, v := range args.Array(0) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"sm3": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
hash := sm3.New()
|
|
for _, v := range args.Array(0) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"hmacMD5": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
hash := hmac.New(md5.New, args.Bytes(0))
|
|
for _, v := range args.Array(1) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"hmacSHA1": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
hash := hmac.New(sha1.New, args.Bytes(0))
|
|
for _, v := range args.Array(1) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"hmacSHA256": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
hash := hmac.New(sha256.New, args.Bytes(0))
|
|
for _, v := range args.Array(1) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"hmacSHA512": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
hash := hmac.New(sha512.New, args.Bytes(0))
|
|
for _, v := range args.Array(1) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"hmacSM3": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
hash := hmac.New(sm3.New, args.Bytes(0))
|
|
for _, v := range args.Array(1) {
|
|
hash.Write(u.Bytes(v))
|
|
}
|
|
return vm.ToValue(hash.Sum(nil))
|
|
},
|
|
"tpl": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(2)
|
|
var functions = map[string]any{}
|
|
if len(argsIn.Arguments) > 2 {
|
|
obj := argsIn.Arguments[2].ToObject(vm)
|
|
for _, k := range obj.Keys() {
|
|
v := obj.Get(k)
|
|
if cb, ok := goja.AssertFunction(v); ok {
|
|
functions[k] = func(in string) string {
|
|
if r, err := cb(argsIn.This, vm.ToValue(in)); err == nil {
|
|
return r.String()
|
|
}
|
|
return ""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
buf := bytes.NewBuffer(make([]byte, 0))
|
|
var err error
|
|
tpl := template.New("tpl")
|
|
if len(functions) > 0 {
|
|
tpl.Funcs(functions)
|
|
}
|
|
if tpl, err = tpl.Parse(args.Str(0)); err == nil {
|
|
err = tpl.Execute(buf, args.Arguments[1].Export())
|
|
}
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
return vm.ToValue(buf.String())
|
|
},
|
|
"sleep": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
time.Sleep(time.Duration(args.Int64(0)) * time.Millisecond)
|
|
return nil
|
|
},
|
|
"setTimeout": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
callback := args.Func(0)
|
|
timeout := time.Duration(args.Int64(1)) * time.Millisecond
|
|
if callback != nil {
|
|
go func() {
|
|
if timeout > 0 {
|
|
time.Sleep(timeout)
|
|
}
|
|
if _, err := callback(args.This, args.Arguments[2:]...); err != nil {
|
|
args.Logger.Error(err.Error())
|
|
}
|
|
}()
|
|
}
|
|
return nil
|
|
},
|
|
"shell": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
a := make([]string, len(args.Arguments)-1)
|
|
for i := 1; i < len(args.Arguments); i++ {
|
|
a[i-1] = args.Str(i)
|
|
}
|
|
|
|
if r, err := u.RunCommand(args.Str(0), a...); err == nil {
|
|
return vm.ToValue(r)
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"formatDate": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
format := args.Str(0)
|
|
var tm time.Time
|
|
if timestamp := args.Int64(1); timestamp > 0 {
|
|
if timestamp < 10000000000 {
|
|
timestamp *= 1000
|
|
}
|
|
tm = time.UnixMilli(timestamp)
|
|
} else {
|
|
tm = time.Now()
|
|
}
|
|
return vm.ToValue(tm.Format(format))
|
|
},
|
|
"timestampMS": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
return vm.ToValue(time.Now().UnixMilli())
|
|
},
|
|
"timestamp": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
return vm.ToValue(time.Now().Unix())
|
|
},
|
|
"toDatetime": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
var tm time.Time
|
|
if timestamp := args.Int64(0); timestamp > 0 {
|
|
if timestamp < 10000000000 {
|
|
timestamp *= 1000
|
|
}
|
|
tm = time.UnixMilli(timestamp)
|
|
} else {
|
|
tm = time.Now()
|
|
}
|
|
return vm.ToValue(tm.Format("2006-01-02 15:04:05"))
|
|
},
|
|
"fromDatetime": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
timeStr := args.Str(0)
|
|
if len(timeStr) > 19 {
|
|
timeStr = timeStr[0:19]
|
|
}
|
|
if strings.ContainsRune(timeStr, 'T') {
|
|
timeStr = strings.ReplaceAll(timeStr, "T", " ")
|
|
}
|
|
if tm, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local); err == nil {
|
|
return vm.ToValue(tm.UnixMilli())
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"toDate": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm)
|
|
var tm time.Time
|
|
if timestamp := args.Int64(0); timestamp > 0 {
|
|
if timestamp < 10000000000 {
|
|
timestamp *= 1000
|
|
}
|
|
tm = time.UnixMilli(timestamp)
|
|
} else {
|
|
tm = time.Now()
|
|
}
|
|
return vm.ToValue(tm.Format("2006-01-02"))
|
|
},
|
|
"fromDate": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
timeStr := args.Str(0)
|
|
if len(timeStr) > 10 {
|
|
timeStr = timeStr[0:10]
|
|
}
|
|
if tm, err := time.ParseInLocation("2006-01-02", timeStr, time.Local); err == nil {
|
|
return vm.ToValue(tm.UnixMilli())
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
},
|
|
"os": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
return vm.ToValue(runtime.GOOS)
|
|
},
|
|
"arch": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
return vm.ToValue(runtime.GOARCH)
|
|
},
|
|
"joinPath": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(filepath.Join(args.StrArray(0)...))
|
|
},
|
|
"getPathDir": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(filepath.Dir(args.Str(0)))
|
|
},
|
|
"getPathBase": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(filepath.Base(args.Str(0)))
|
|
},
|
|
"getPathVolume": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(filepath.VolumeName(args.Str(0)))
|
|
},
|
|
"absPath": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
r, err := filepath.Abs(args.Str(0))
|
|
if err != nil {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
return vm.ToValue(r)
|
|
},
|
|
"cleanPath": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(filepath.Clean(args.Str(0)))
|
|
},
|
|
"isLocalPath": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(filepath.IsLocal(args.Str(0)))
|
|
},
|
|
"string": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.String(args.Any(0)))
|
|
},
|
|
"int": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.Int64(args.Any(0)))
|
|
},
|
|
"float": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.Float64(args.Any(0)))
|
|
},
|
|
"bytes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.Bytes(args.Any(0)))
|
|
},
|
|
"bool": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
return vm.ToValue(u.Bool(args.Any(0)))
|
|
},
|
|
"searchFile": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
filename := args.Str(0)
|
|
searchPath := args.Str(1)
|
|
findFile := ""
|
|
if searchPath != "" {
|
|
findFile = searchFile(searchPath, filename)
|
|
} else {
|
|
findFile = searchFileFromCurrent(vm, filename)
|
|
}
|
|
return vm.ToValue(findFile)
|
|
},
|
|
"loadConfig": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
if envConfigs == nil {
|
|
envConfigs = map[string]map[string]any{}
|
|
envFile := searchFileFromCurrent(vm, "env.yml")
|
|
if envFile == "" {
|
|
envFile = searchFileFromCurrent(vm, "env.json")
|
|
}
|
|
if envFile != "" {
|
|
u.LoadX(envFile, &envConfigs)
|
|
}
|
|
}
|
|
|
|
args := gojs.MakeArgs(&argsIn, vm).Check(1)
|
|
confName := args.Str(0)
|
|
conf := map[string]any{}
|
|
confFile := searchFileFromCurrent(vm, confName+".yml")
|
|
if confFile == "" {
|
|
confFile = searchFileFromCurrent(vm, confName+".json")
|
|
}
|
|
if confFile != "" {
|
|
u.LoadX(confFile, &conf)
|
|
}
|
|
if envConf, ok := envConfigs[confName]; ok {
|
|
u.Convert(envConf, &conf)
|
|
}
|
|
|
|
decTimes := 0
|
|
confStr := encryptdMatcher.ReplaceAllStringFunc(u.Json(conf), func(str string) string {
|
|
if buf, err := base64.URLEncoding.DecodeString(str[1 : len(str)-1]); err == nil {
|
|
if buf1, err1 := confAes.DecryptBytes(buf); err1 == nil && len(buf1) > 0 {
|
|
decTimes++
|
|
return "\"" + string(buf1) + "\""
|
|
}
|
|
}
|
|
return str
|
|
})
|
|
if decTimes > 0 {
|
|
u.UnJson(confStr, &conf)
|
|
}
|
|
|
|
return vm.ToValue(conf)
|
|
},
|
|
}
|
|
|
|
gojs.Register("apigo.cc/gojs/util", gojs.Module{
|
|
Object: obj,
|
|
TsCode: utilTS,
|
|
Example: utilMD,
|
|
SetSSKey: SetSSKey,
|
|
JsCode: `
|
|
$MOD$.keysBy = function (obj, ...fieldAndValues) {
|
|
let keys = []
|
|
for (let k in obj) {
|
|
let match = true
|
|
if (fieldAndValues.length === 1) {
|
|
// 查找一位数组
|
|
if (obj[k] != fieldAndValues[0]) {
|
|
match = false
|
|
}
|
|
} else {
|
|
// 查找二维数组
|
|
for (let i = 0; i < fieldAndValues.length; i += 2) {
|
|
if (obj[k][fieldAndValues[i]] != fieldAndValues[i + 1]) {
|
|
match = false
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if (match) {
|
|
keys.push(k)
|
|
}
|
|
}
|
|
return keys
|
|
}
|
|
|
|
$MOD$.countBy = function (obj, ...fieldAndValues) {
|
|
let keys = $MOD$.keysBy(obj, ...fieldAndValues)
|
|
l(obj, keys)
|
|
return keys.length
|
|
}
|
|
|
|
$MOD$.listBy = function (obj, ...fieldAndValues) {
|
|
let list = obj.length !== undefined ? [] : {}
|
|
let keys = $MOD$.keysBy(obj, ...fieldAndValues)
|
|
for (let k of keys) {
|
|
if (obj.length !== undefined) {
|
|
list.push(obj[k])
|
|
} else {
|
|
list[k] = obj[k]
|
|
}
|
|
}
|
|
return list
|
|
}
|
|
|
|
$MOD$.hasBy = function (obj, ...fieldAndValues) {
|
|
let keys = $MOD$.keysBy(obj, ...fieldAndValues)
|
|
return keys.length > 0
|
|
}
|
|
|
|
$MOD$.getBy = function (obj, ...fieldAndValues) {
|
|
let keys = $MOD$.keysBy(obj, ...fieldAndValues)
|
|
if (keys.length > 0) return obj[keys[0]]
|
|
return null
|
|
}
|
|
|
|
$MOD$.setBy = function (obj, value, ...fieldAndValues) {
|
|
let keys = $MOD$.keysBy(obj, ...fieldAndValues)
|
|
if (keys.length > 0) obj[keys[0]] = value
|
|
}
|
|
|
|
$MOD$.indexBy = function (obj, ...fieldAndValues) {
|
|
let keys = $MOD$.keysBy(obj, ...fieldAndValues)
|
|
if (keys.length > 0) {
|
|
return obj.length !== undefined ? $MOD$.int(keys[0]) : keys[0]
|
|
}
|
|
return -1
|
|
}
|
|
|
|
$MOD$.removeBy = function (obj, ...fieldAndValues) {
|
|
let keys = $MOD$.keysBy(obj, ...fieldAndValues)
|
|
let n = 0
|
|
for (let i = keys.length - 1; i >= 0; i--) {
|
|
let k = keys[i]
|
|
if (obj.length !== undefined) {
|
|
obj.splice(k, 1)
|
|
} else {
|
|
delete obj[k]
|
|
}
|
|
n++
|
|
}
|
|
return n
|
|
}
|
|
|
|
$MOD$.removeArrayItem = function (list, item) {
|
|
let pos = list.indexOf(item)
|
|
if (pos !== -1) list.splice(pos, 1)
|
|
}
|
|
|
|
$MOD$.last = function (arr) {
|
|
if (arr && arr.length) {
|
|
return arr[arr.length - 1]
|
|
}
|
|
return null
|
|
}
|
|
|
|
$MOD$.len = function (obj) {
|
|
if (obj.length !== undefined) {
|
|
return obj.length
|
|
} else {
|
|
let n = 0
|
|
for (let k in obj) n++
|
|
return n
|
|
}
|
|
}
|
|
|
|
$MOD$.mergeBy = function (olds, news, ...fields) {
|
|
if (!olds) return news
|
|
for (let newItem of news) {
|
|
let fieldAndValues = []
|
|
for (let field of fields) {
|
|
fieldAndValues.push(field, newItem[field])
|
|
}
|
|
let oldIndex = $MOD$.indexBy(olds, ...fieldAndValues)
|
|
if (oldIndex === -1) {
|
|
olds.push(newItem)
|
|
} else {
|
|
olds[oldIndex] = newItem
|
|
}
|
|
}
|
|
return olds
|
|
}
|
|
|
|
$MOD$.sortBy = function (obj, field, isReverse = false, sortType) {
|
|
let list = obj.length !== undefined ? [] : {}
|
|
let sortedKeys = {}
|
|
let sortArr = []
|
|
for (let k in obj) {
|
|
let v = ''
|
|
if (field.length !== undefined) {
|
|
for (let f of field) v += obj[k][f]
|
|
} else {
|
|
v = obj[k][field]
|
|
}
|
|
if (!sortedKeys[v]) {
|
|
sortedKeys[v] = true
|
|
sortArr.push(v)
|
|
}
|
|
}
|
|
sortArr.sort((a, b) => {
|
|
if (sortType === 'int') {
|
|
a = $MOD$.int(a)
|
|
b = $MOD$.int(b)
|
|
} else if (sortType === 'float') {
|
|
a = $MOD$.float(a)
|
|
b = $MOD$.float(b)
|
|
}
|
|
if (a == b) return 0
|
|
if (typeof a === 'number' && typeof b === 'number') {
|
|
return isReverse ? b - a : a - b
|
|
} else {
|
|
return (isReverse ? a < b : a > b) ? 1 : -1
|
|
}
|
|
})
|
|
for (let sortKey of sortArr) {
|
|
for (let k in obj) {
|
|
let v = ''
|
|
if (field.length !== undefined) {
|
|
for (let f of field) v += obj[k][f]
|
|
} else {
|
|
v = obj[k][field]
|
|
}
|
|
|
|
if (obj.length !== undefined) {
|
|
if (v == sortKey) list.push(obj[k])
|
|
} else {
|
|
if (v == sortKey) list[k] = obj[k]
|
|
}
|
|
}
|
|
}
|
|
return list
|
|
}
|
|
|
|
$MOD$.in = function (v1, v2) {
|
|
if (!(v1.length !== undefined)) v1 = $MOD$.split(v1, /,\s*/)
|
|
return v1.indexOf(String(v2)) !== -1
|
|
}
|
|
|
|
$MOD$.uniquePush = function (arr, ...values) {
|
|
for (let v of values) {
|
|
if (arr.indexOf(v) === -1) arr.push(v)
|
|
}
|
|
}
|
|
|
|
$MOD$.clearEmpty = function (arr) {
|
|
let a = []
|
|
for (let v of arr) if (v) a.push(v)
|
|
return a
|
|
}
|
|
|
|
$MOD$.split = function (v1, v2, n) {
|
|
let a = $MOD$.string(v1).split(v2)
|
|
if (!n || n < a.length - 1) return a
|
|
let a2 = a.slice(0, n)
|
|
a2[n - 1] = a.slice(n - 1).join(v2)
|
|
return a2
|
|
}
|
|
|
|
$MOD$.splitWithoutEmpty = function (v1, v2, n) {
|
|
let a = $MOD$.clearEmpty($MOD$.string(v1).split(v2))
|
|
if (!n || n < a.length - 1) return a
|
|
let a2 = a.slice(0, n)
|
|
a2[n - 1] = a.slice(n - 1).join(v2)
|
|
return a2
|
|
}
|
|
|
|
$MOD$.joinWithoutEmpty = function (arr, separator) {
|
|
return $MOD$.clearEmpty(arr).join(separator)
|
|
}
|
|
|
|
$MOD$.makeDefault = function (item, defaults) {
|
|
for (let k in defaults) {
|
|
if (!item[k]) item[k] = defaults[k]
|
|
}
|
|
}
|
|
|
|
$MOD$._copy = function (obj, isDeepCopy) {
|
|
let newObj
|
|
if (obj.length !== undefined) {
|
|
newObj = []
|
|
for (let o of obj) {
|
|
if (isDeepCopy && typeof o === 'object' && o) o = $MOD$.copy(o)
|
|
newObj.push(o)
|
|
}
|
|
} else {
|
|
newObj = {}
|
|
for (let k in obj) {
|
|
let v = obj[k]
|
|
if (isDeepCopy && typeof v === 'object' && v) v = $MOD$.copy(v)
|
|
newObj[k] = v
|
|
}
|
|
}
|
|
|
|
return newObj
|
|
}
|
|
|
|
$MOD$.copy = function (obj) {
|
|
return $MOD$._copy(obj, false)
|
|
}
|
|
|
|
$MOD$.deepCopy = function (obj) {
|
|
return $MOD$._copy(obj, true)
|
|
}
|
|
|
|
$MOD$.isNumber = function (v) {
|
|
const numberMatcher = /^\d*\.?\d+$/
|
|
if (typeof v === 'number' || v instanceof Number) return true
|
|
if (typeof v === 'string') return numberMatcher.test(v)
|
|
if (typeof v === 'object' && v.toString) numberMatcher.test(v.toString())
|
|
return false
|
|
}
|
|
|
|
$MOD$.isInt = function (v) {
|
|
const intMatcher = /^\d+$/
|
|
if (typeof v === 'number' || v instanceof Number) return $MOD$.int(v) === v
|
|
if (typeof v === 'string') return intMatcher.test(v)
|
|
if (typeof v === 'object' && v.toString) intMatcher.test(v.toString())
|
|
return false
|
|
}
|
|
|
|
$MOD$.isFloat = function (v) {
|
|
const floatMatcher = /^\d*\.\d+$/
|
|
if (typeof v === 'float' || v instanceof Number) return $MOD$.int(v) !== v
|
|
if (typeof v === 'string') return floatMatcher.test(v)
|
|
if (typeof v === 'object' && v.toString) floatMatcher.test(v.toString())
|
|
return false
|
|
}
|
|
|
|
$MOD$.getByKey = function (obj, ...keys) {
|
|
if( keys.length === 1 && keys[0].length ) keys = keys[0]
|
|
let o = {}
|
|
for (let k in obj) {
|
|
if (keys.indexOf(k) >= 0) {
|
|
o[k] = obj[k]
|
|
}
|
|
}
|
|
return o
|
|
}
|
|
|
|
$MOD$.excludeByKey = function (obj, ...keys) {
|
|
if( keys.length === 1 && keys[0].length ) keys = keys[0]
|
|
let o = {}
|
|
for (let k in obj) {
|
|
if (keys.indexOf(k) < 0) {
|
|
o[k] = obj[k]
|
|
}
|
|
}
|
|
return o
|
|
}
|
|
`,
|
|
})
|
|
}
|
|
|
|
var encryptdMatcher = regexp.MustCompile(`"([\w-=]+)"`)
|
|
|
|
func makeECDSAPriKey(priKey []byte) *ecdsa.PrivateKey {
|
|
if len(priKey) >= 60 {
|
|
return makePriKey(priKey, elliptic.P521())
|
|
} else if len(priKey) >= 40 {
|
|
return makePriKey(priKey, elliptic.P384())
|
|
} else {
|
|
return makePriKey(priKey, elliptic.P256())
|
|
}
|
|
}
|
|
|
|
func makeECDSAPubKey(pubKey []byte) *ecdsa.PublicKey {
|
|
if len(pubKey) >= 130 {
|
|
return makePubKey(pubKey, elliptic.P521())
|
|
} else if len(pubKey) >= 90 {
|
|
return makePubKey(pubKey, elliptic.P384())
|
|
} else {
|
|
return makePubKey(pubKey, elliptic.P256())
|
|
}
|
|
}
|
|
|
|
func makePriKey(priKey []byte, curve elliptic.Curve) *ecdsa.PrivateKey {
|
|
x, y := curve.ScalarBaseMult(priKey)
|
|
return &ecdsa.PrivateKey{
|
|
D: new(big.Int).SetBytes(priKey),
|
|
PublicKey: ecdsa.PublicKey{
|
|
Curve: curve,
|
|
X: x,
|
|
Y: y,
|
|
},
|
|
}
|
|
}
|
|
|
|
func makePubKey(pubKey []byte, curve elliptic.Curve) *ecdsa.PublicKey {
|
|
keyLen := pubKey[0]
|
|
x := new(big.Int)
|
|
y := new(big.Int)
|
|
x.SetBytes(pubKey[1 : keyLen+1])
|
|
y.SetBytes(pubKey[keyLen+1:])
|
|
return &ecdsa.PublicKey{Curve: curve, X: x, Y: y}
|
|
}
|
|
|
|
func makeRSAPriKey(keyBytes []byte) *rsa.PrivateKey {
|
|
priKey, err := x509.ParsePKCS1PrivateKey(keyBytes)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return priKey
|
|
}
|
|
|
|
func makeRSAPubKey(keyBytes []byte) *rsa.PublicKey {
|
|
pubKey, err := x509.ParsePKCS1PublicKey(keyBytes)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return pubKey
|
|
}
|
|
|
|
func searchFile(searchPath, name string) string {
|
|
searched := map[string]bool{}
|
|
return _searchFile(searchPath, name, &searched)
|
|
}
|
|
|
|
func searchFileFromCurrent(vm *goja.Runtime, name string) string {
|
|
searched := map[string]bool{}
|
|
startPath := u.String(vm.GoData["startPath"])
|
|
filename := _searchFile(startPath, name, &searched)
|
|
if filename == "" {
|
|
currentPath, _ := os.Getwd()
|
|
filename = _searchFile(currentPath, name, &searched)
|
|
}
|
|
return filename
|
|
}
|
|
|
|
func _searchFile(checkPath, name string, searched *map[string]bool) string {
|
|
for {
|
|
if !(*searched)[checkPath] {
|
|
(*searched)[checkPath] = true
|
|
filename := filepath.Join(checkPath, name)
|
|
if u.FileExists(filename) {
|
|
return filename
|
|
}
|
|
}
|
|
oldPath := checkPath
|
|
checkPath = filepath.Dir(oldPath)
|
|
if oldPath == checkPath {
|
|
return ""
|
|
}
|
|
}
|
|
}
|