feat: publish sanitized custom.97 source

This commit is contained in:
cneicy committed 2026-10-27 20:43:39 +08:00
1 parent 8e6ed0317b
commit 86c0276156
1022 files changed
+69903 -19207

No files matched your search

+199 -46
View File
@@ -6,15 +6,17 @@ import (
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"math"
"net/url"
"sort"
"strings"
"time"
"github.com/Calcium-Ion/moejs"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
"github.com/grafana/sobek"
)
type volcSignRequest struct {
@@ -29,65 +31,216 @@ type volcSignRequest struct {
Timestamp int64 `json:"timestamp"`
}
func injectGlobals(runtime *sobek.Runtime, identity func() string, now func() time.Time, logOutput func(string)) error {
// injectGlobals installs utils and console. currentCall returns the hook call
// running on runtime, or nil outside one; utils.fetch reads its fetcher and
// budget there, so no request data lives in the runtime's globals.
func injectGlobals(runtime *moejs.Runtime, identity func() string, now func() time.Time, logOutput func(string), currentCall func() *runtimeCall) error {
utils := map[string]any{
"hasCapability": HasCapability,
"fetch": runtime.Function("fetch", 1, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
call := currentCall()
if call == nil {
return moejs.Undefined(), fmt.Errorf("utils.fetch is not available outside hooks")
}
return call.fetch(r, moejs.Arg(args, 0))
}),
"hasCapability": runtime.Function("hasCapability", 1, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
name, err := stringValue(r, moejs.Arg(args, 0))
if err != nil {
return moejs.Undefined(), err
}
return moejs.Bool(HasCapability(name)), nil
}),
"json": map[string]any{
"clone": func(call sobek.FunctionCall) sobek.Value {
if sobek.IsUndefined(call.Argument(0)) {
panic(runtime.NewTypeError("json.clone requires a JSON value"))
"clone": runtime.Function("clone", 1, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
if moejs.Arg(args, 0).IsUndefined() {
return moejs.Undefined(), r.TypeError("json.clone requires a JSON value")
}
budget := &jsonStateBudget{ctx: context.Background(), bytes: MaxJSONToolBytes, nodes: maxJSONToolNodes}
value, err := newJSONStateNode(call.Argument(0), 0, budget)
budget := &jsonStateBudget{ctx: context.Background(), bytes: MaxJSONToolBytes, nodes: maxJSONToolNodes, realm: r}
value, err := newJSONStateNode(moejs.Arg(args, 0), 0, budget)
if err != nil {
panic(runtime.NewTypeError("json.clone: %s", err))
var exception *moejs.Exception
var interrupted *moejs.InterruptedError
if errors.As(err, &exception) || errors.As(err, &interrupted) {
return moejs.Undefined(), err
}
return moejs.Undefined(), r.TypeError("json.clone: %s", err)
}
cloned, err := value.jsValue(runtime)
return value.jsValue(r)
}),
},
"unixNow": runtime.Function("unixNow", 0, func(*moejs.Realm, moejs.Value, []moejs.Value) (moejs.Value, error) {
return moejs.Int(now().Unix()), nil
}),
"jwtSignHS256": runtime.Function("jwtSignHS256", 2, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
var claims map[string]any
if argument := moejs.Arg(args, 0); !argument.IsNullish() {
exported, err := r.ToGoStrict(argument)
if err != nil {
panic(runtime.NewGoError(err))
return moejs.Undefined(), err
}
return cloned
},
},
"unixNow": func() int64 { return now().Unix() },
"jwtSignHS256": func(claims map[string]any, secret string) (string, error) {
return jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims(claims)).SignedString([]byte(secret))
},
"hmacSHA256": func(message, secret string) string {
var ok bool
if claims, ok = exported.(map[string]any); !ok {
return moejs.Undefined(), r.TypeError("jwtSignHS256 claims must be an object")
}
}
secret, err := stringValue(r, moejs.Arg(args, 1))
if err != nil {
return moejs.Undefined(), err
}
token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims(claims)).SignedString([]byte(secret))
if err != nil {
return moejs.Undefined(), err
}
return moejs.String(token), nil
}),
"hmacSHA256": runtime.Function("hmacSHA256", 2, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
message, err := stringValue(r, moejs.Arg(args, 0))
if err != nil {
return moejs.Undefined(), err
}
secret, err := stringValue(r, moejs.Arg(args, 1))
if err != nil {
return moejs.Undefined(), err
}
mac := hmac.New(sha256.New, []byte(secret))
_, _ = mac.Write([]byte(message))
return hex.EncodeToString(mac.Sum(nil))
},
"base64": func(value string) string { return base64.StdEncoding.EncodeToString([]byte(value)) },
"base64URL": func(value string) string {
return base64.RawURLEncoding.EncodeToString([]byte(value))
},
"base64URLDecode": func(value string) (string, error) {
return moejs.String(hex.EncodeToString(mac.Sum(nil))), nil
}),
"base64": runtime.Function("base64", 1, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
value, err := stringValue(r, moejs.Arg(args, 0))
if err != nil {
return moejs.Undefined(), err
}
return moejs.String(base64.StdEncoding.EncodeToString([]byte(value))), nil
}),
"base64URL": runtime.Function("base64URL", 1, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
value, err := stringValue(r, moejs.Arg(args, 0))
if err != nil {
return moejs.Undefined(), err
}
return moejs.String(base64.RawURLEncoding.EncodeToString([]byte(value))), nil
}),
"base64URLDecode": runtime.Function("base64URLDecode", 1, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
value, err := stringValue(r, moejs.Arg(args, 0))
if err != nil {
return moejs.Undefined(), err
}
decoded, err := base64.RawURLEncoding.DecodeString(value)
return string(decoded), err
},
"uuid": func() string { return uuid.NewString() },
"volcSignV4": func(request volcSignRequest) (map[string]string, error) {
return signVolcV4(request, now)
},
if err != nil {
return moejs.Undefined(), err
}
return moejs.String(string(decoded)), nil
}),
"uuid": runtime.Function("uuid", 0, func(*moejs.Realm, moejs.Value, []moejs.Value) (moejs.Value, error) {
return moejs.String(uuid.NewString()), nil
}),
"volcSignV4": runtime.Function("volcSignV4", 1, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
// Fields are read by their Go names, as plugins have always
// passed them.
var request volcSignRequest
argument := moejs.Arg(args, 0)
if !argument.IsNullish() && !argument.IsObject() {
return moejs.Undefined(), r.TypeError("volcSignV4 request must be an object")
}
if argument.IsObject() {
object := argument.AsObject()
fields := []struct {
name string
target *string
}{
{"Method", &request.Method}, {"URL", &request.URL}, {"Body", &request.Body},
{"AccessKey", &request.AccessKey}, {"SecretKey", &request.SecretKey},
{"Region", &request.Region}, {"Service", &request.Service},
}
for _, field := range fields {
value, err := object.GetProp(r, r.KeyFromGoString(field.name))
if err != nil {
return moejs.Undefined(), err
}
if *field.target, err = stringValue(r, value); err != nil {
return moejs.Undefined(), err
}
}
headers, err := object.GetProp(r, r.KeyFromGoString("Headers"))
if err != nil {
return moejs.Undefined(), err
}
if headers.IsObject() {
keys, err := r.EnumerableOwnKeys(headers.AsObject())
if err != nil {
return moejs.Undefined(), err
}
request.Headers = make(map[string]string, len(keys))
for _, key := range keys {
value, err := headers.AsObject().GetProp(r, key)
if err != nil {
return moejs.Undefined(), err
}
if request.Headers[key.GoString()], err = stringValue(r, value); err != nil {
return moejs.Undefined(), err
}
}
}
timestamp, err := object.GetProp(r, r.KeyFromGoString("Timestamp"))
if err != nil {
return moejs.Undefined(), err
}
if !timestamp.IsNullish() {
seconds, err := r.ToNumber(timestamp)
if err != nil {
return moejs.Undefined(), err
}
if !math.IsNaN(seconds) && !math.IsInf(seconds, 0) {
request.Timestamp = int64(seconds)
}
}
}
signed, err := signVolcV4(request, now)
if err != nil {
return moejs.Undefined(), err
}
return r.FromGo(signed)
}),
}
if err := runtime.Set("utils", utils); err != nil {
if err := runtime.SetGlobal("utils", utils); err != nil {
return err
}
console := runtime.NewObject()
if err := console.Set("log", func(call sobek.FunctionCall) sobek.Value {
parts := make([]string, len(call.Arguments))
for i, argument := range call.Arguments {
parts[i] = argument.String()
}
if logOutput != nil {
logOutput(identity() + " " + strings.Join(parts, " "))
}
return sobek.Undefined()
}); err != nil {
return err
return runtime.SetGlobal("console", map[string]any{
"log": runtime.Function("log", 0, func(r *moejs.Realm, _ moejs.Value, args []moejs.Value) (moejs.Value, error) {
parts := make([]string, len(args))
for i, argument := range args {
if argument.IsSymbol() {
parts[i] = argument.String()
continue
}
text, err := r.ToString(argument)
if err != nil {
return moejs.Undefined(), err
}
parts[i] = text.GoString()
}
if logOutput != nil {
logOutput(identity() + " " + strings.Join(parts, " "))
}
return moejs.Undefined(), nil
}),
})
}
// stringValue reads a host function's string parameter: undefined and null
// read as "", other values as JavaScript's String(value).
func stringValue(r *moejs.Realm, value moejs.Value) (string, error) {
if value.IsNullish() {
return "", nil
}
return runtime.Set("console", console)
if value.IsString() {
return value.AsString().GoString(), nil
}
text, err := r.ToString(value)
if err != nil {
return "", err
}
return text.GoString(), nil
}
func signVolcV4(request volcSignRequest, now func() time.Time) (map[string]string, error) {