mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
Add garble support (#1793)
Co-authored-by: AlbinoDrought <sean@albinodrought.com> Co-authored-by: stffabi <stffabi@users.noreply.github.com>
This commit is contained in:
co-authored by
AlbinoDrought
stffabi
parent
eef99ee577
commit
052b9222c1
@@ -2,6 +2,7 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -75,7 +76,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
|
||||
// tags to pass to `go`
|
||||
tags := ""
|
||||
command.StringFlag("tags", "tags to pass to Go compiler (quoted and space separated)", &tags)
|
||||
command.StringFlag("tags", "Build tags to pass to Go compiler. Must be quoted. Space or comma (but not both) separated", &tags)
|
||||
|
||||
outputFilename := ""
|
||||
command.StringFlag("o", "Output filename", &outputFilename)
|
||||
@@ -111,9 +112,18 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
windowsConsole := false
|
||||
command.BoolFlag("windowsconsole", "Keep the console when building for Windows", &windowsConsole)
|
||||
|
||||
obfuscated := false
|
||||
command.BoolFlag("obfuscated", "Code obfuscation of bound Wails methods", &obfuscated)
|
||||
|
||||
garbleargs := "-literals -tiny -seed=random"
|
||||
command.StringFlag("garbleargs", "Arguments to pass to garble", &garbleargs)
|
||||
|
||||
dryRun := false
|
||||
command.BoolFlag("dryrun", "Dry run, prints the config for the command that would be executed", &dryRun)
|
||||
|
||||
skipBindings := false
|
||||
command.BoolFlag("skipbindings", "Skips generation of bindings", &skipBindings)
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
quiet := verbosity == 0
|
||||
@@ -137,13 +147,10 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
return fmt.Errorf("unable to find compiler: %s", compilerCommand)
|
||||
}
|
||||
|
||||
// Tags
|
||||
userTags := []string{}
|
||||
for _, tag := range strings.Split(tags, " ") {
|
||||
thisTag := strings.TrimSpace(tag)
|
||||
if thisTag != "" {
|
||||
userTags = append(userTags, thisTag)
|
||||
}
|
||||
// Process User Tags
|
||||
userTags, err := buildtags.Parse(tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Webview2 installer strategy (download by default)
|
||||
@@ -176,6 +183,15 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
targets.AddSlice(strings.Split(platform, ","))
|
||||
targets.Deduplicate()
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
projectOptions, err := project.Load(cwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create BuildOptions
|
||||
buildOptions := &build.Options{
|
||||
Logger: logger,
|
||||
@@ -197,6 +213,9 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
TrimPath: trimpath,
|
||||
RaceDetector: raceDetector,
|
||||
WindowsConsole: windowsConsole,
|
||||
Obfuscated: obfuscated,
|
||||
GarbleArgs: garbleargs,
|
||||
SkipBindings: skipBindings,
|
||||
}
|
||||
|
||||
// Start a new tabwriter
|
||||
@@ -208,7 +227,12 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
_, _ = fmt.Fprintf(w, "App Type: \t%s\n", buildOptions.OutputType)
|
||||
_, _ = fmt.Fprintf(w, "Platforms: \t%s\n", platform)
|
||||
_, _ = fmt.Fprintf(w, "Compiler: \t%s\n", compilerPath)
|
||||
_, _ = fmt.Fprintf(w, "Skip Bindings: \t%t\n", skipBindings)
|
||||
_, _ = fmt.Fprintf(w, "Build Mode: \t%s\n", modeString)
|
||||
_, _ = fmt.Fprintf(w, "Obfuscated: \t%t\n", buildOptions.Obfuscated)
|
||||
if buildOptions.Obfuscated {
|
||||
_, _ = fmt.Fprintf(w, "Garble Args: \t%s\n", buildOptions.GarbleArgs)
|
||||
}
|
||||
_, _ = fmt.Fprintf(w, "Skip Frontend: \t%t\n", skipFrontend)
|
||||
_, _ = fmt.Fprintf(w, "Compress: \t%t\n", buildOptions.Compress)
|
||||
_, _ = fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
||||
@@ -230,15 +254,6 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
return err
|
||||
}
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
projectOptions, err := project.Load(cwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check platform
|
||||
validPlatformArch := slicer.String([]string{
|
||||
"darwin",
|
||||
@@ -329,6 +344,11 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
buildOptions.OutputFile = outputFilename
|
||||
}
|
||||
|
||||
if obfuscated && skipBindings {
|
||||
logger.Println("Warning: obfuscated flag overrides skipbindings flag.")
|
||||
buildOptions.SkipBindings = false
|
||||
}
|
||||
|
||||
if !dryRun {
|
||||
// Start Time
|
||||
start := time.Now()
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/bindings"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -77,7 +79,7 @@ type devFlags struct {
|
||||
reloadDirs string
|
||||
openBrowser bool
|
||||
noReload bool
|
||||
noGen bool
|
||||
skipBindings bool
|
||||
wailsjsdir string
|
||||
tags string
|
||||
verbosity int
|
||||
@@ -106,9 +108,9 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
command.StringFlag("reloaddirs", "Additional directories to trigger reloads (comma separated)", &flags.reloadDirs)
|
||||
command.BoolFlag("browser", "Open application in browser", &flags.openBrowser)
|
||||
command.BoolFlag("noreload", "Disable reload on asset change", &flags.noReload)
|
||||
command.BoolFlag("nogen", "Disable generate module", &flags.noGen)
|
||||
command.BoolFlag("skipbindings", "Skip bindings generation", &flags.skipBindings)
|
||||
command.StringFlag("wailsjsdir", "Directory to generate the Wails JS modules", &flags.wailsjsdir)
|
||||
command.StringFlag("tags", "tags to pass to Go compiler (quoted and space separated)", &flags.tags)
|
||||
command.StringFlag("tags", "Build tags to pass to Go compiler. Must be quoted. Space or comma (but not both) separated", &flags.tags)
|
||||
command.IntFlag("v", "Verbosity level (0 - silent, 1 - standard, 2 - verbose)", &flags.verbosity)
|
||||
command.StringFlag("loglevel", "Loglevel to use - Trace, Debug, Info, Warning, Error", &flags.loglevel)
|
||||
command.BoolFlag("f", "Force build application", &flags.forceBuild)
|
||||
@@ -125,14 +127,6 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
logger := clilogger.New(w)
|
||||
app.PrintBanner()
|
||||
|
||||
userTags := []string{}
|
||||
for _, tag := range strings.Split(flags.tags, " ") {
|
||||
thisTag := strings.TrimSpace(tag)
|
||||
if thisTag != "" {
|
||||
userTags = append(userTags, thisTag)
|
||||
}
|
||||
}
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -159,28 +153,37 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run go mod tidy to ensure we're up to date
|
||||
err = runCommand(cwd, false, "go", "mod", "tidy", "-compat=1.17")
|
||||
// Run go mod tidy to ensure we're up-to-date
|
||||
err = runCommand(cwd, false, "go", "mod", "tidy")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !flags.noGen {
|
||||
self := os.Args[0]
|
||||
if flags.tags != "" {
|
||||
err = runCommand(cwd, true, self, "generate", "module", "-tags", flags.tags)
|
||||
} else {
|
||||
err = runCommand(cwd, true, self, "generate", "module")
|
||||
buildOptions := generateBuildOptions(flags)
|
||||
buildOptions.Logger = logger
|
||||
|
||||
userTags, err := buildtags.Parse(flags.tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buildOptions.UserTags = userTags
|
||||
|
||||
if !flags.skipBindings {
|
||||
if flags.verbosity == build.VERBOSE {
|
||||
LogGreen("Generating Bindings...")
|
||||
}
|
||||
stdout, err := bindings.GenerateBindings(bindings.Options{
|
||||
Tags: buildOptions.UserTags,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if flags.verbosity == build.VERBOSE {
|
||||
LogGreen(stdout)
|
||||
}
|
||||
}
|
||||
|
||||
buildOptions := generateBuildOptions(flags)
|
||||
buildOptions.Logger = logger
|
||||
buildOptions.UserTags = internal.ParseUserTags(flags.tags)
|
||||
|
||||
// Setup signal handler
|
||||
quitChannel := make(chan os.Signal, 1)
|
||||
signal.Notify(quitChannel, os.Interrupt, os.Kill, syscall.SIGTERM)
|
||||
@@ -269,7 +272,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reset the process and the binary so the defer knows about it and is a nop.
|
||||
// Reset the process and the binary so defer knows about it and is a nop.
|
||||
debugBinaryProcess = nil
|
||||
appBinary = ""
|
||||
|
||||
@@ -654,7 +657,7 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
}
|
||||
|
||||
if flags.frontendDevServerURL != "" {
|
||||
// If we are using an external dev server all the reload of the frontend part can be skipped
|
||||
// If we are using an external dev server, the reloading of the frontend part can be skipped
|
||||
continue
|
||||
}
|
||||
if len(changedPaths) != 0 {
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal"
|
||||
"github.com/wailsapp/wails/v2/internal/shell"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/bindings"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
"io"
|
||||
)
|
||||
|
||||
// AddModuleCommand adds the `module` subcommand for the `generate` command
|
||||
@@ -22,37 +16,18 @@ func AddModuleCommand(app *clir.Cli, parent *clir.Command, w io.Writer) error {
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
filename := "wailsbindings"
|
||||
if runtime.GOOS == "windows" {
|
||||
filename += ".exe"
|
||||
}
|
||||
// go build -tags bindings -o bindings.exe
|
||||
tempDir := os.TempDir()
|
||||
filename = filepath.Join(tempDir, filename)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
buildTags, err := buildtags.Parse(tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tagList := internal.ParseUserTags(tags)
|
||||
tagList = append(tagList, "bindings")
|
||||
|
||||
stdout, stderr, err := shell.RunCommand(cwd, "go", "build", "-tags", strings.Join(tagList, ","), "-o", filename)
|
||||
_, err = bindings.GenerateBindings(bindings.Options{
|
||||
Tags: buildTags,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s\n%s\n%s", stdout, stderr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
stdout, stderr, err = shell.RunCommand(cwd, filename)
|
||||
println(stdout)
|
||||
println(stderr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s\n%s\n%s", stdout, stderr, err)
|
||||
}
|
||||
|
||||
// Best effort removal of temp file
|
||||
_ = os.Remove(filename)
|
||||
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
|
||||
@@ -186,7 +186,7 @@ func Install(options *Options) (bool, *Template, error) {
|
||||
}
|
||||
} else {
|
||||
// Get the absolute path of the given directory
|
||||
targetDir, err := filepath.Abs(filepath.Join(cwd, options.TargetDir))
|
||||
targetDir, err := filepath.Abs(options.TargetDir)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package internal
|
||||
|
||||
import "strings"
|
||||
|
||||
// ParseUserTags takes the string form of tags and converts to a slice of strings
|
||||
func ParseUserTags(tagString string) []string {
|
||||
userTags := make([]string, 0)
|
||||
for _, tag := range strings.Split(tagString, " ") {
|
||||
thisTag := strings.TrimSpace(tag)
|
||||
if thisTag != "" {
|
||||
userTags = append(userTags, thisTag)
|
||||
}
|
||||
}
|
||||
return userTags
|
||||
}
|
||||
@@ -31,7 +31,8 @@ func (a *App) Run() error {
|
||||
a.appoptions.OnDomReady,
|
||||
a.appoptions.OnBeforeClose,
|
||||
}
|
||||
appBindings := binding.NewBindings(a.logger, a.appoptions.Bind, bindingExemptions)
|
||||
|
||||
appBindings := binding.NewBindings(a.logger, a.appoptions.Bind, bindingExemptions, IsObfuscated())
|
||||
|
||||
err := generateBindings(appBindings)
|
||||
if err != nil {
|
||||
|
||||
@@ -191,7 +191,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
appoptions.OnDomReady,
|
||||
appoptions.OnBeforeClose,
|
||||
}
|
||||
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions)
|
||||
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions, false)
|
||||
|
||||
err = generateBindings(appBindings)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
//go:build !obfuscated
|
||||
|
||||
package app
|
||||
|
||||
// IsObfuscated returns false if the obfuscated build tag is not set
|
||||
func IsObfuscated() bool {
|
||||
return false
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
//go:build obfuscated
|
||||
|
||||
package app
|
||||
|
||||
// IsObfuscated returns true if the obfuscated build tag is set
|
||||
func IsObfuscated() bool {
|
||||
return true
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build production
|
||||
// +build production
|
||||
|
||||
package app
|
||||
|
||||
@@ -65,6 +64,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
myLogger.SetLogLevel(appoptions.LogLevelProduction)
|
||||
}
|
||||
ctx = context.WithValue(ctx, "logger", myLogger)
|
||||
ctx = context.WithValue(ctx, "obfuscated", IsObfuscated())
|
||||
|
||||
// Preflight Checks
|
||||
err = PreflightChecks(appoptions, myLogger)
|
||||
@@ -90,7 +90,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
appoptions.OnDomReady,
|
||||
appoptions.OnBeforeClose,
|
||||
}
|
||||
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions)
|
||||
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions, IsObfuscated())
|
||||
eventHandler := runtime.NewEvents(myLogger)
|
||||
ctx = context.WithValue(ctx, "events", eventHandler)
|
||||
// Attach logger to context
|
||||
|
||||
@@ -22,14 +22,16 @@ type Bindings struct {
|
||||
exemptions slicer.StringSlicer
|
||||
|
||||
structsToGenerateTS map[string]map[string]interface{}
|
||||
obfuscate bool
|
||||
}
|
||||
|
||||
// NewBindings returns a new Bindings object
|
||||
func NewBindings(logger *logger.Logger, structPointersToBind []interface{}, exemptions []interface{}) *Bindings {
|
||||
func NewBindings(logger *logger.Logger, structPointersToBind []interface{}, exemptions []interface{}, obfuscate bool) *Bindings {
|
||||
result := &Bindings{
|
||||
db: newDB(),
|
||||
logger: logger.CustomLogger("Bindings"),
|
||||
structsToGenerateTS: make(map[string]map[string]interface{}),
|
||||
obfuscate: obfuscate,
|
||||
}
|
||||
|
||||
for _, exemption := range exemptions {
|
||||
|
||||
@@ -2,6 +2,7 @@ package binding
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
@@ -15,14 +16,18 @@ type DB struct {
|
||||
// It used for performance gains at runtime
|
||||
methodMap map[string]*BoundMethod
|
||||
|
||||
// This uses ids to reference bound methods at runtime
|
||||
obfuscatedMethodMap map[int]*BoundMethod
|
||||
|
||||
// Lock to ensure sync access to the data
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func newDB() *DB {
|
||||
return &DB{
|
||||
store: make(map[string]map[string]map[string]*BoundMethod),
|
||||
methodMap: make(map[string]*BoundMethod),
|
||||
store: make(map[string]map[string]map[string]*BoundMethod),
|
||||
methodMap: make(map[string]*BoundMethod),
|
||||
obfuscatedMethodMap: make(map[int]*BoundMethod),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,11 +61,18 @@ func (d *DB) GetMethod(qualifiedMethodName string) *BoundMethod {
|
||||
return d.methodMap[qualifiedMethodName]
|
||||
}
|
||||
|
||||
// GetObfuscatedMethod returns the method for the given ID
|
||||
func (d *DB) GetObfuscatedMethod(id int) *BoundMethod {
|
||||
// Lock the db whilst processing and unlock on return
|
||||
d.lock.RLock()
|
||||
defer d.lock.RUnlock()
|
||||
|
||||
return d.obfuscatedMethodMap[id]
|
||||
}
|
||||
|
||||
// AddMethod adds the given method definition to the db using the given qualified path: packageName.structName.methodName
|
||||
func (d *DB) AddMethod(packageName string, structName string, methodName string, methodDefinition *BoundMethod) {
|
||||
|
||||
// TODO: Validate inputs?
|
||||
|
||||
// Lock the db whilst processing and unlock on return
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
@@ -97,8 +109,31 @@ func (d *DB) ToJSON() (string, error) {
|
||||
d.lock.RLock()
|
||||
defer d.lock.RUnlock()
|
||||
|
||||
d.UpdateObfuscatedCallMap()
|
||||
|
||||
bytes, err := json.Marshal(&d.store)
|
||||
|
||||
// Return zero copy string as this string will be read only
|
||||
return *(*string)(unsafe.Pointer(&bytes)), err
|
||||
result := *(*string)(unsafe.Pointer(&bytes))
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UpdateObfuscatedCallMap sets up the secure call mappings
|
||||
func (d *DB) UpdateObfuscatedCallMap() map[string]int {
|
||||
|
||||
var mappings = make(map[string]int)
|
||||
|
||||
// Iterate map keys and sort them
|
||||
keys := make([]string, 0, len(d.methodMap))
|
||||
for k := range d.methodMap {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
// Iterate sorted keys and add to obfuscated method map
|
||||
for id, k := range keys {
|
||||
mappings[k] = id
|
||||
d.obfuscatedMethodMap[id] = d.methodMap[k]
|
||||
}
|
||||
return mappings
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@ import (
|
||||
|
||||
func (b *Bindings) GenerateGoBindings(baseDir string) error {
|
||||
store := b.db.store
|
||||
var obfuscatedBindings map[string]int
|
||||
if b.obfuscate {
|
||||
obfuscatedBindings = b.db.UpdateObfuscatedCallMap()
|
||||
}
|
||||
for packageName, structs := range store {
|
||||
packageDir := filepath.Join(baseDir, packageName)
|
||||
err := fs.Mkdir(packageDir)
|
||||
@@ -54,7 +58,12 @@ func (b *Bindings) GenerateGoBindings(baseDir string) error {
|
||||
argsString := args.Join(", ")
|
||||
jsoutput.WriteString(fmt.Sprintf("\nexport function %s(%s) {", methodName, argsString))
|
||||
jsoutput.WriteString("\n")
|
||||
jsoutput.WriteString(fmt.Sprintf(" return window['go']['%s']['%s']['%s'](%s);", packageName, structName, methodName, argsString))
|
||||
if b.obfuscate {
|
||||
id := obfuscatedBindings[strings.Join([]string{packageName, structName, methodName}, ".")]
|
||||
jsoutput.WriteString(fmt.Sprintf(" return ObfuscatedCall(%d, [%s]);", id, argsString))
|
||||
} else {
|
||||
jsoutput.WriteString(fmt.Sprintf(" return window['go']['%s']['%s']['%s'](%s);", packageName, structName, methodName, argsString))
|
||||
}
|
||||
jsoutput.WriteString("\n")
|
||||
jsoutput.WriteString(fmt.Sprintf("}"))
|
||||
jsoutput.WriteString("\n")
|
||||
|
||||
@@ -25,7 +25,7 @@ type B struct {
|
||||
|
||||
func TestNestedStruct(t *testing.T) {
|
||||
bind := &BindForTest{}
|
||||
testBindings := NewBindings(logger.New(nil), []interface{}{bind}, []interface{}{})
|
||||
testBindings := NewBindings(logger.New(nil), []interface{}{bind}, []interface{}{}, false)
|
||||
|
||||
namesStrSlicer := testBindings.getAllStructNames()
|
||||
names := []string{}
|
||||
|
||||
@@ -42,7 +42,9 @@ func NewAssetServer(ctx context.Context, options *options.App, bindingsJSON stri
|
||||
|
||||
func NewAssetServerWithHandler(ctx context.Context, handler http.Handler, bindingsJSON string) (*AssetServer, error) {
|
||||
var buffer bytes.Buffer
|
||||
buffer.WriteString(`window.wailsbindings='` + bindingsJSON + `';` + "\n")
|
||||
if bindingsJSON != "" {
|
||||
buffer.WriteString(`window.wailsbindings='` + bindingsJSON + `';` + "\n")
|
||||
}
|
||||
buffer.Write(runtime.RuntimeDesktopJS)
|
||||
|
||||
result := &AssetServer{
|
||||
|
||||
@@ -72,12 +72,17 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
if _starturl, _ := ctx.Value("starturl").(*url.URL); _starturl != nil {
|
||||
result.startURL = _starturl
|
||||
} else {
|
||||
bindingsJSON, err := appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
var bindings string
|
||||
var err error
|
||||
if _obfuscated, _ := ctx.Value("obfuscated").(bool); !_obfuscated {
|
||||
bindings, err = appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
appBindings.DB().UpdateObfuscatedCallMap()
|
||||
}
|
||||
|
||||
assets, err := assetserver.NewAssetServer(ctx, appoptions, bindingsJSON)
|
||||
assets, err := assetserver.NewAssetServer(ctx, appoptions, bindings)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -75,12 +75,17 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
if _starturl, _ := ctx.Value("starturl").(*url.URL); _starturl != nil {
|
||||
result.startURL = _starturl
|
||||
} else {
|
||||
bindingsJSON, err := appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
var bindings string
|
||||
var err error
|
||||
if _obfuscated, _ := ctx.Value("obfuscated").(bool); !_obfuscated {
|
||||
bindings, err = appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
appBindings.DB().UpdateObfuscatedCallMap()
|
||||
}
|
||||
|
||||
assets, err := assetserver.NewAssetServer(ctx, appoptions, bindingsJSON)
|
||||
assets, err := assetserver.NewAssetServer(ctx, appoptions, bindings)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -91,12 +91,18 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
return result
|
||||
}
|
||||
|
||||
bindingsJSON, err := appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
var bindings string
|
||||
var err error
|
||||
if _obfuscated, _ := ctx.Value("obfuscated").(bool); !_obfuscated {
|
||||
bindings, err = appBindings.ToJSON()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
appBindings.DB().UpdateObfuscatedCallMap()
|
||||
}
|
||||
|
||||
assets, err := assetserver.NewAssetServer(ctx, appoptions, bindingsJSON)
|
||||
assets, err := assetserver.NewAssetServer(ctx, appoptions, bindings)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ func (d *Dispatcher) ProcessMessage(message string, sender frontend.Frontend) (s
|
||||
return d.processEventMessage(message, sender)
|
||||
case 'C':
|
||||
return d.processCallMessage(message, sender)
|
||||
case 'c':
|
||||
return d.processSecureCallMessage(message, sender)
|
||||
case 'W':
|
||||
return d.processWindowMessage(message, sender)
|
||||
case 'B':
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package dispatcher
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
)
|
||||
|
||||
type secureCallMessage struct {
|
||||
ID int `json:"id"`
|
||||
Args []json.RawMessage `json:"args"`
|
||||
CallbackID string `json:"callbackID"`
|
||||
}
|
||||
|
||||
func (d *Dispatcher) processSecureCallMessage(message string, sender frontend.Frontend) (string, error) {
|
||||
|
||||
var payload secureCallMessage
|
||||
err := json.Unmarshal([]byte(message[1:]), &payload)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var result interface{}
|
||||
|
||||
// Lookup method
|
||||
registeredMethod := d.bindingsDB.GetObfuscatedMethod(payload.ID)
|
||||
|
||||
// Check we have it
|
||||
if registeredMethod == nil {
|
||||
return "", fmt.Errorf("method '%d' not registered", payload.ID)
|
||||
}
|
||||
|
||||
args, err2 := registeredMethod.ParseArgs(payload.Args)
|
||||
if err2 != nil {
|
||||
errmsg := fmt.Errorf("error parsing arguments: %s", err2.Error())
|
||||
result, _ := d.NewErrorCallback(errmsg.Error(), payload.CallbackID)
|
||||
return result, errmsg
|
||||
}
|
||||
result, err = registeredMethod.Call(args)
|
||||
|
||||
callbackMessage := &CallbackMessage{
|
||||
CallbackID: payload.CallbackID,
|
||||
}
|
||||
if err != nil {
|
||||
callbackMessage.Err = err.Error()
|
||||
} else {
|
||||
callbackMessage.Result = result
|
||||
}
|
||||
messageData, err := json.Marshal(callbackMessage)
|
||||
d.log.Trace("json call result data: %+v\n", string(messageData))
|
||||
if err != nil {
|
||||
// what now?
|
||||
d.log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
return "c" + string(messageData), nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user