From b3fe3aafc95a2d14f08bf03bc92e7d5ef5deaeac Mon Sep 17 00:00:00 2001 From: Adam Fisk Date: Mon, 16 Dec 2024 10:36:30 -0700 Subject: [PATCH 1/6] hot fix for ios config transport --- internalsdk/ios/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internalsdk/ios/config.go b/internalsdk/ios/config.go index 933cfb921..7985e4c6a 100644 --- a/internalsdk/ios/config.go +++ b/internalsdk/ios/config.go @@ -73,7 +73,7 @@ func Configure(configFolderPath string, userID int, proToken, deviceID string, r configFolderPath: configFolderPath, hardcodedProxies: hardcodedProxies, uc: uc, - rt: proxied.ParallelPreferChained(), + rt: proxied.Fronted("ios-configure"), } return cf.Configure(userID, proToken, refreshProxies) } From 494b9dfa3679535cd45446522bfeb7b1bb195961 Mon Sep 17 00:00:00 2001 From: atavism Date: Mon, 16 Dec 2024 12:01:25 -0800 Subject: [PATCH 2/6] Add CLI program (#1260) * Add CLI program * move logging * Remove extra logging * add small delay when we stop Lantern * clean-ups * clean-ups * fix formatting * use flashlight flags * Add comments * run go mod tidy * support running lantern desktop app * clean-ups * add cliClient and run go mod tidy * clean-ups * use go 1.22.6 * remove unused, merge latest, improve error handling * Fix test --- cli/cli.go | 80 ++++++++++++++++ desktop/app/app.go | 158 ++++++++++++++++---------------- desktop/app/integration_test.go | 3 +- desktop/lib.go | 7 +- go.mod | 19 +++- go.sum | 76 ++++++++++++--- 6 files changed, 241 insertions(+), 102 deletions(-) create mode 100644 cli/cli.go diff --git a/cli/cli.go b/cli/cli.go new file mode 100644 index 000000000..0a11ce9b1 --- /dev/null +++ b/cli/cli.go @@ -0,0 +1,80 @@ +package main + +import ( + "context" + "os" + "os/signal" + "sync" + "syscall" + "time" + + "github.com/getlantern/golog" + "github.com/getlantern/lantern-client/desktop/app" + + "github.com/pterm/pterm" +) + +var ( + log = golog.LoggerFor("lantern") +) + +type cliClient struct { + app *app.App + mu sync.Mutex +} + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) + go func() { + <-signalChan + pterm.Warning.Println("Received shutdown signal.") + cancel() + }() + + client := &cliClient{} + client.start(ctx) + defer client.stop() + + <-ctx.Done() +} + +func (client *cliClient) start(ctx context.Context) { + client.mu.Lock() + defer client.mu.Unlock() + if client.app != nil { + pterm.Warning.Println("Lantern is already running") + return + } + + // create new instance of Lantern app + app, err := app.NewApp() + if err != nil { + pterm.Error.Printf("Unable to initialize app: %v", err) + return + } + client.app = app + + // Run Lantern in the background + go app.Run(ctx) +} + +func (client *cliClient) stop() { + client.mu.Lock() + defer client.mu.Unlock() + if client.app == nil { + // Lantern is not running, no cleanup needed + return + } + + pterm.Info.Println("Stopping Lantern...") + client.app.Exit(nil) + client.app = nil + + // small delay to give Lantern time to cleanup + time.Sleep(1 * time.Second) + pterm.Success.Println("Lantern stopped successfully.") +} diff --git a/desktop/app/app.go b/desktop/app/app.go index 06dd0e9ad..0ba46b06f 100644 --- a/desktop/app/app.go +++ b/desktop/app/app.go @@ -93,17 +93,17 @@ type App struct { } // NewApp creates a new desktop app that initializes the app and acts as a moderator between all desktop components. -func NewApp() *App { +func NewApp() (*App, error) { // initialize app config and flags based on environment variables flags, err := initializeAppConfig() if err != nil { - log.Fatalf("failed to initialize app config: %w", err) + return nil, fmt.Errorf("failed to initialize app config: %w", err) } return NewAppWithFlags(flags, flags.ConfigDir) } // NewAppWithFlags creates a new instance of App initialized with the given flags and configDir -func NewAppWithFlags(flags flashlight.Flags, configDir string) *App { +func NewAppWithFlags(flags flashlight.Flags, configDir string) (*App, error) { if configDir == "" { log.Debug("Config directory is empty, using default location") configDir = appdir.General(common.DefaultAppName) @@ -141,10 +141,10 @@ func NewAppWithFlags(flags flashlight.Flags, configDir string) *App { app.translations.Set(os.DirFS("locale/translation")) if e := app.configService.StartService(app.ws); e != nil { - app.Exit(fmt.Errorf("unable to register config service: %q", e)) + return nil, fmt.Errorf("unable to register config service: %q", e) } - return app + return app, nil } // Run starts the app. @@ -156,88 +156,84 @@ func (app *App) Run(ctx context.Context) { } }() - // Run below in separate goroutine as config.Init() can potentially block when Lantern runs - // for the first time. User can still quit Lantern through systray menu when it happens. - go func() { - log.Debug(app.Flags) - userConfig := func() common.UserConfig { - return settings.UserConfig(app.Settings()) - } - proClient := proclient.NewClient(fmt.Sprintf("https://%s", common.ProAPIHost), userConfig) - authClient := auth.NewClient(fmt.Sprintf("https://%s", common.DFBaseUrl), userConfig) + log.Debug(app.Flags) + userConfig := func() common.UserConfig { + return settings.UserConfig(app.Settings()) + } + proClient := proclient.NewClient(fmt.Sprintf("https://%s", common.ProAPIHost), userConfig) + authClient := auth.NewClient(fmt.Sprintf("https://%s", common.DFBaseUrl), userConfig) - app.mu.Lock() - app.proClient = proClient - app.authClient = authClient - app.mu.Unlock() + app.mu.Lock() + app.proClient = proClient + app.authClient = authClient + app.mu.Unlock() - settings := app.Settings() + settings := app.Settings() - if app.Flags.ProxyAll { - // If proxyall flag was supplied, force proxying of all - settings.SetProxyAll(true) - } + if app.Flags.ProxyAll { + // If proxyall flag was supplied, force proxying of all + settings.SetProxyAll(true) + } - listenAddr := app.Flags.Addr - if listenAddr == "" { - listenAddr = settings.GetAddr() - } - if listenAddr == "" { - listenAddr = defaultHTTPProxyAddress - } + listenAddr := app.Flags.Addr + if listenAddr == "" { + listenAddr = settings.GetAddr() + } + if listenAddr == "" { + listenAddr = defaultHTTPProxyAddress + } - socksAddr := app.Flags.SocksAddr - if socksAddr == "" { - socksAddr = settings.GetSOCKSAddr() - } - if socksAddr == "" { - socksAddr = defaultSOCKSProxyAddress - } + socksAddr := app.Flags.SocksAddr + if socksAddr == "" { + socksAddr = settings.GetSOCKSAddr() + } + if socksAddr == "" { + socksAddr = defaultSOCKSProxyAddress + } - if app.Flags.Timeout > 0 { - go func() { - time.AfterFunc(app.Flags.Timeout, func() { - app.Exit(errors.New("No succeeding proxy got after running for %v, global config fetched: %v, proxies fetched: %v", - app.Flags.Timeout, app.fetchedGlobalConfig.Load(), app.fetchedProxiesConfig.Load())) - }) - }() - } - var err error - app.flashlight, err = flashlight.New( - common.DefaultAppName, - common.ApplicationVersion, - common.RevisionDate, - app.configDir, - app.Flags.VPN, - func() bool { return settings.GetDisconnected() }, // check whether we're disconnected - settings.GetProxyAll, - func() bool { return false }, // on desktop, we do not allow private hosts - settings.IsAutoReport, - app.Flags.AsMap(), - settings, - app.statsTracker, - app.IsPro, - settings.GetLanguage, - func(addr string) (string, error) { return addr, nil }, // no dnsgrab reverse lookups on desktop - // Dummy analytics function - func(category, action, label string) {}, - flashlight.WithOnConfig(app.onConfigUpdate), - flashlight.WithOnProxies(app.onProxiesUpdate), - flashlight.WithOnSucceedingProxy(app.onSucceedingProxy), - ) - if err != nil { - app.Exit(err) - return - } - app.beforeStart(ctx, listenAddr) - - app.flashlight.Run( - listenAddr, - socksAddr, - app.afterStart, - func(err error) { _ = app.Exit(err) }, - ) - }() + if app.Flags.Timeout > 0 { + go func() { + time.AfterFunc(app.Flags.Timeout, func() { + app.Exit(errors.New("No succeeding proxy got after running for %v, global config fetched: %v, proxies fetched: %v", + app.Flags.Timeout, app.fetchedGlobalConfig.Load(), app.fetchedProxiesConfig.Load())) + }) + }() + } + var err error + app.flashlight, err = flashlight.New( + common.DefaultAppName, + common.ApplicationVersion, + common.RevisionDate, + app.configDir, + app.Flags.VPN, + func() bool { return settings.GetDisconnected() }, // check whether we're disconnected + settings.GetProxyAll, + func() bool { return false }, // on desktop, we do not allow private hosts + settings.IsAutoReport, + app.Flags.AsMap(), + settings, + app.statsTracker, + app.IsPro, + settings.GetLanguage, + func(addr string) (string, error) { return addr, nil }, // no dnsgrab reverse lookups on desktop + // Dummy analytics function + func(category, action, label string) {}, + flashlight.WithOnConfig(app.onConfigUpdate), + flashlight.WithOnProxies(app.onProxiesUpdate), + flashlight.WithOnSucceedingProxy(app.onSucceedingProxy), + ) + if err != nil { + app.Exit(err) + return + } + app.beforeStart(ctx, listenAddr) + + app.flashlight.Run( + listenAddr, + socksAddr, + app.afterStart, + func(err error) { _ = app.Exit(err) }, + ) } // IsFeatureEnabled checks whether or not the given feature is enabled by flashlight diff --git a/desktop/app/integration_test.go b/desktop/app/integration_test.go index e8fceee40..7206c894a 100644 --- a/desktop/app/integration_test.go +++ b/desktop/app/integration_test.go @@ -190,7 +190,8 @@ func startApp(t *testing.T, helper *integrationtest.Helper) (*App, error) { Timeout: time.Duration(0), } ss := settings.EmptySettings() - a := NewAppWithFlags(flags, helper.ConfigDir) + a, err := NewAppWithFlags(flags, helper.ConfigDir) + require.NoError(t, err) id := ss.GetUserID() if id == 0 { ss.SetUserIDAndToken(1, "token") diff --git a/desktop/lib.go b/desktop/lib.go index 0b0621137..4dec9adc6 100644 --- a/desktop/lib.go +++ b/desktop/lib.go @@ -80,8 +80,11 @@ func start() *C.char { } golog.SetPrepender(logging.Timestamped) - a = app.NewApp() - a.Run(context.Background()) + a, err = app.NewApp() + if err != nil { + log.Fatal(err) + } + go a.Run(context.Background()) return C.CString("") } diff --git a/go.mod b/go.mod index 5bc0b480c..5f12b4a4b 100644 --- a/go.mod +++ b/go.mod @@ -68,22 +68,33 @@ require ( github.com/joho/godotenv v1.5.1 github.com/leekchan/accounting v1.0.0 github.com/moul/http2curl v1.0.0 + github.com/pterm/pterm v0.12.80 github.com/shopspring/decimal v1.4.0 github.com/stretchr/testify v1.9.0 - golang.org/x/crypto v0.31.0 + golang.org/x/crypto v0.28.0 golang.org/x/mobile v0.0.0-20241016134751-7ff83004ec2c golang.org/x/net v0.30.0 - golang.org/x/sys v0.28.0 + golang.org/x/sys v0.27.0 google.golang.org/protobuf v1.35.2 nhooyr.io/websocket v1.8.17 ) require ( + atomicgo.dev/cursor v0.2.0 // indirect + atomicgo.dev/keyboard v0.2.9 // indirect + atomicgo.dev/schedule v0.1.0 // indirect github.com/alitto/pond/v2 v2.1.5 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/coder/websocket v1.8.12 // indirect + github.com/containerd/console v1.0.3 // indirect github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/gookit/color v1.5.4 // indirect + github.com/lithammer/fuzzysearch v1.1.8 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/term v0.26.0 // indirect ) require ( @@ -332,8 +343,8 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/text v0.20.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.26.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240808171019-573a1156607a // indirect diff --git a/go.sum b/go.sum index 96091176f..4f8a4026e 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,11 @@ +atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg= +atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ= +atomicgo.dev/cursor v0.2.0 h1:H6XN5alUJ52FZZUkI7AlJbUc1aW38GWZalpYRPpoPOw= +atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= +atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= +atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= +atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= +atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -16,6 +24,15 @@ github.com/Jigsaw-Code/outline-sdk v0.0.16 h1:WbHmv80FKDIpzEmR3GehTbq5CibYTLvcxI github.com/Jigsaw-Code/outline-sdk v0.0.16/go.mod h1:e1oQZbSdLJBBuHgfeQsgEkvkuyIePPwstUeZRGq0KO8= github.com/Jigsaw-Code/outline-ss-server v1.5.0 h1:Vz+iS0xR7i3PrLD82pzFFwZ9fsh6zrNawMeYERR8VTc= github.com/Jigsaw-Code/outline-ss-server v1.5.0/go.mod h1:KaebwBiCWDSkgsJrJIbGH0szON8CZq4LgQaFV8v3RM4= +github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= +github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= +github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= +github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= +github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= +github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= +github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= +github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4= +github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= @@ -123,6 +140,7 @@ github.com/aristanetworks/goarista v0.0.0-20190628000427-15fc8b0bfcde/go.mod h1: github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -161,6 +179,8 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -559,6 +579,10 @@ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -626,6 +650,9 @@ github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= @@ -653,12 +680,17 @@ github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= +github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/Dav/9Z58LGpk7U= github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -833,6 +865,15 @@ github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= +github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= +github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= +github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= +github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= +github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= +github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= +github.com/pterm/pterm v0.12.80 h1:mM55B+GnKUnLMUSqhdINe4s6tOuVQIetQ3my8JGyAIg= +github.com/pterm/pterm v0.12.80/go.mod h1:c6DeF9bSnOSeFPZlfs4ZRAFcf5SCoTwvwQ5xaKGQlHo= github.com/quic-go/quic-go v0.48.0 h1:2TCyvBrMu1Z25rvIAlnp2dPT4lgh/uTqLqiXVpp5AeU= github.com/quic-go/quic-go v0.48.0/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -846,6 +887,9 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= @@ -858,6 +902,8 @@ github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28= github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= @@ -958,6 +1004,9 @@ github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguH github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E= github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0= @@ -1035,8 +1084,6 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= @@ -1110,10 +1157,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1140,13 +1185,16 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1160,12 +1208,12 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -1175,6 +1223,8 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1187,10 +1237,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= From fc6a4367226ab3cd745fbce2960e3cbf673e062e Mon Sep 17 00:00:00 2001 From: garmr-ulfr <104022054+garmr-ulfr@users.noreply.github.com> Date: Mon, 16 Dec 2024 23:38:43 -0800 Subject: [PATCH 3/6] use previous geolookup for ios (#1267) * use previous geolookup for ios * Call geolookup Refresh before getting country. --------- Co-authored-by: Jigar-f --- go.mod | 1 + go.sum | 2 + internalsdk/ios/config.go | 6 +- internalsdk/ios/geolookup/geolookup.go | 262 ++++++++++++++++++++ internalsdk/ios/geolookup/geolookup_test.go | 223 +++++++++++++++++ 5 files changed, 491 insertions(+), 3 deletions(-) create mode 100644 internalsdk/ios/geolookup/geolookup.go create mode 100644 internalsdk/ios/geolookup/geolookup_test.go diff --git a/go.mod b/go.mod index 5f12b4a4b..4ea2fae86 100644 --- a/go.mod +++ b/go.mod @@ -88,6 +88,7 @@ require ( github.com/coder/websocket v1.8.12 // indirect github.com/containerd/console v1.0.3 // indirect github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e // indirect + github.com/getlantern/geolookup v0.0.0-20230327091034-aebe73c6eef4 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/gookit/color v1.5.4 // indirect github.com/lithammer/fuzzysearch v1.1.8 // indirect diff --git a/go.sum b/go.sum index 4f8a4026e..8ae0313a7 100644 --- a/go.sum +++ b/go.sum @@ -323,6 +323,8 @@ github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e h1:qk62Xhg+ha1s github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e/go.mod h1:UOynqDcVIlDMFk3sdUyHzNyY1cz4GHtJ+8qvWESHWhg= github.com/getlantern/geo v0.0.0-20241129152027-2fc88c10f91e h1:vpikNz6IzvEoqVYmiK5Uq+lE4TCzvMDqbZdxFbtGK1g= github.com/getlantern/geo v0.0.0-20241129152027-2fc88c10f91e/go.mod h1:RjQ0krF8NTCc5xo2Q1995/vZBnYg33h8svn15do7dLg= +github.com/getlantern/geolookup v0.0.0-20230327091034-aebe73c6eef4 h1:Ju9l1RretVWJTNo2vpl/xAW8Dcuiyg5kJC6LRBpCigw= +github.com/getlantern/geolookup v0.0.0-20230327091034-aebe73c6eef4/go.mod h1:4UNvIsawdB8WclVxqYv46Oe1zzWJ8wMhUO+q6tUzATo= github.com/getlantern/go-socks5 v0.0.0-20171114193258-79d4dd3e2db5 h1:RBKofGGMt2k6eGBwX8mky9qunjL+KnAp9JdzXjiRkRw= github.com/getlantern/go-socks5 v0.0.0-20171114193258-79d4dd3e2db5/go.mod h1:kGHRXch95rnGLHjER/GhhFiHvfnqNz7KqWD9kGfATHY= github.com/getlantern/go-tun2socks v1.16.12-0.20201218023150-b68f09e5ae93 h1:CFLw2b6vgOmpxsRWRiTd46tiR6YKg2crIuTu4cINYcY= diff --git a/internalsdk/ios/config.go b/internalsdk/ios/config.go index 7985e4c6a..05e385b42 100644 --- a/internalsdk/ios/config.go +++ b/internalsdk/ios/config.go @@ -21,9 +21,10 @@ import ( "github.com/getlantern/flashlight/v7/config" "github.com/getlantern/flashlight/v7/email" "github.com/getlantern/flashlight/v7/embeddedconfig" - "github.com/getlantern/flashlight/v7/geolookup" "github.com/getlantern/flashlight/v7/proxied" + "github.com/getlantern/lantern-client/internalsdk/ios/geolookup" + "context" "github.com/getlantern/lantern-client/internalsdk/common" @@ -140,9 +141,8 @@ func (cf *configurer) Configure(userID int, proToken string, refreshProxies bool if frontingErr := setupFronting(); frontingErr != nil { log.Errorf("Unable to configure fronting, sticking with embedded configuration: %v", err) } else { - log.Debug("Refreshing geolookup") - go func() { + go geolookup.Refresh() cf.uc.Country = geolookup.GetCountry(1 * time.Minute) log.Debugf("Successful geolookup: country %s", cf.uc.Country) cf.uc.AllowProbes = global.FeatureEnabled( diff --git a/internalsdk/ios/geolookup/geolookup.go b/internalsdk/ios/geolookup/geolookup.go new file mode 100644 index 000000000..60e2e024d --- /dev/null +++ b/internalsdk/ios/geolookup/geolookup.go @@ -0,0 +1,262 @@ +package geolookup + +import ( + "context" + "encoding/json" + "fmt" + "math" + "net/http" + "os" + "sync" + "time" + + "github.com/getlantern/eventual/v2" + geo "github.com/getlantern/geolookup" + "github.com/getlantern/golog" + + "github.com/getlantern/flashlight/v7/ops" + "github.com/getlantern/flashlight/v7/proxied" +) + +var ( + log = golog.LoggerFor("ios.geolookup") + + refreshRequest = make(chan interface{}, 1) + currentGeoInfo = eventual.NewValue() + watchers []chan bool + persistToFile string + mx sync.Mutex + roundTripper http.RoundTripper +) + +const ( + maxTimeout = 10 * time.Minute + retryWaitMillis = 100 + maxRetryWait = 30 * time.Second +) + +type GeoInfo struct { + IP string + City *geo.City + FromDisk bool +} + +func init() { + SetDefaultRoundTripper() +} + +// GetIP gets the IP. If the IP hasn't been determined yet, waits up to the +// given timeout for an IP to become available. +func GetIP(timeout time.Duration) string { + gi, err := GetGeoInfo(timeout) + if err != nil { + log.Debugf("Could not get IP: %v", err) + return "" + } + return gi.IP +} + +// GetCountry gets the country. If the country hasn't been determined yet, waits +// up to the given timeout for a country to become available. +func GetCountry(timeout time.Duration) string { + gi, err := GetGeoInfo(timeout) + if err != nil { + log.Debugf("Could not get country: %v", err) + return "" + } + return gi.City.Country.IsoCode +} + +func GetGeoInfo(timeout time.Duration) (*GeoInfo, error) { + // We need to specially handle negative timeouts because some callers may use + // eventual.Forever (aka -1), expecting it to block forever. + if timeout < 0 { + timeout = maxTimeout + } + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + gi, err := currentGeoInfo.Get(ctx) + if err != nil { + return nil, fmt.Errorf( + "could not get geoinfo with timeout %v: %w", + timeout, + err, + ) + } + if gi == nil { + return nil, fmt.Errorf("no geo info after %v", timeout) + } + return gi.(*GeoInfo), nil +} + +// EnablePersistence enables persistence of the current geo info to disk at the named file and +// initializes current geo info from that file if necessary. +func EnablePersistence(geoFile string) { + mx.Lock() + defer mx.Unlock() + + // use this file going forward + persistToFile = geoFile + + log.Debugf("Will persist geolocation info to %v", persistToFile) + + // initialize from file if necessary + knownCountry := GetCountry(0) + if knownCountry == "" { + file, err := os.Open(persistToFile) + if err == nil { + log.Debugf("Initializing geolocation info from %v", persistToFile) + dec := json.NewDecoder(file) + gi := &GeoInfo{ + FromDisk: true, + } + decodeErr := dec.Decode(gi) + if decodeErr != nil { + log.Errorf( + "Error initializing geolocation info from %v: %v", + persistToFile, + decodeErr, + ) + return + } + setGeoInfo(gi, false) + } + } +} + +// Refresh refreshes the geolookup information by calling the remote geolookup +// service. It will keep calling the service until it's able to determine an IP +// and country. +func Refresh() { + select { + case refreshRequest <- true: + log.Debug("Requested refresh") + default: + log.Debug("Refresh already in progress") + } +} + +// OnRefresh creates a channel that caller can receive on when new geolocation +// information is got. +func OnRefresh() <-chan bool { + ch := make(chan bool, 1) + mx.Lock() + watchers = append(watchers, ch) + mx.Unlock() + return ch +} + +func init() { + go run() +} + +func run() { + for range refreshRequest { + log.Debug("Refreshing geolocation info") + geoInfo := lookup() + + // Check if the IP has changed and if the old IP is simply cached from + // disk. If it is cached, we should still notify anyone looking for + // a new IP because they won't have been notified of the IP on disk, + // as that is loaded very soon on startup. + if !isNew(geoInfo) { + log.Debug("public IP from network did not change - not notifying watchers") + continue + } + log.Debug("Setting new geolocation info") + mx.Lock() + setGeoInfo(geoInfo, true) + mx.Unlock() + } +} + +func isNew(newGeoInfo *GeoInfo) bool { + if newGeoInfo == nil { + return false + } + oldGeoInfo, err := GetGeoInfo(0) + if err != nil { + return true + } + if oldGeoInfo == nil { + return true + } + return oldGeoInfo.IP != newGeoInfo.IP || + oldGeoInfo.FromDisk != newGeoInfo.FromDisk +} + +func setGeoInfo(gi *GeoInfo, persist bool) { + currentGeoInfo.Set(gi) + w := watchers + for _, ch := range w { + select { + case ch <- true: + default: + } + } + if persist && persistToFile != "" { + b, err := json.Marshal(gi) + if err != nil { + log.Errorf( + "Unable to marshal geolocation info to JSON for persisting: %v", + err, + ) + return + } + writeErr := os.WriteFile(persistToFile, b, 0644) + if writeErr != nil { + log.Errorf( + "Error persisting geolocation info to %v: %v", + persistToFile, + err, + ) + } + } +} + +func lookup() *GeoInfo { + consecutiveFailures := 0 + + for { + gi, err := doLookup() + if err == nil { + return gi + } + log.Debugf("Unable to get current location: %s", err) + wait := time.Duration( + math.Pow( + 2, + float64(consecutiveFailures), + )*float64( + retryWaitMillis, + ), + ) * time.Millisecond + if wait > maxRetryWait { + wait = maxRetryWait + } + log.Debugf("Waiting %v before retrying", wait) + time.Sleep(wait) + consecutiveFailures++ + } +} + +func doLookup() (*GeoInfo, error) { + op := ops.Begin("geolookup") + defer op.End() + city, ip, err := geo.LookupIP("", roundTripper) + + if err != nil { + log.Errorf("Could not lookup IP %v", err) + return nil, op.FailIf(err) + } + return &GeoInfo{ + IP: ip, + City: city, + FromDisk: false}, + nil +} + +func SetDefaultRoundTripper() { + roundTripper = proxied.ParallelPreferChained() +} diff --git a/internalsdk/ios/geolookup/geolookup_test.go b/internalsdk/ios/geolookup/geolookup_test.go new file mode 100644 index 000000000..f0d3151ba --- /dev/null +++ b/internalsdk/ios/geolookup/geolookup_test.go @@ -0,0 +1,223 @@ +package geolookup + +import ( + "net" + "net/http" + "os" + "testing" + "time" + + "github.com/getlantern/eventual/v2" + "github.com/getlantern/fronted" + "github.com/stretchr/testify/require" +) + +const initialInfo = ` +{ + "City": { + "City": { + "GeoNameID": 4671654, + "Names": { + "de": "Austin", + "en": "Austin", + "es": "Austin", + "fr": "Austin", + "ja": "\u30aa\u30fc\u30b9\u30c6\u30a3\u30f3", + "pt-BR": "Austin", + "ru": "\u041e\u0441\u0442\u0438\u043d" + } + }, + "Continent": { + "Code": "NA", + "GeoNameID": 6255149, + "Names": { + "de": "Nordamerika", + "en": "North America", + "es": "Norteam\u00e9rica", + "fr": "Am\u00e9rique du Nord", + "ja": "\u5317\u30a2\u30e1\u30ea\u30ab", + "pt-BR": "Am\u00e9rica do Norte", + "ru": "\u0421\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u0410\u043c\u0435\u0440\u0438\u043a\u0430", + "zh-CN": "\u5317\u7f8e\u6d32" + } + }, + "Country": { + "GeoNameID": 6252001, + "IsoCode": "FM", + "Names": { + "de": "USA", + "en": "United States", + "es": "Estados Unidos", + "fr": "\u00c9tats Unis", + "ja": "\u30a2\u30e1\u30ea\u30ab", + "pt-BR": "EUA", + "ru": "\u0421\u0428\u0410", + "zh-CN": "\u7f8e\u56fd" + } + }, + "Location": { + "Latitude": 30.2095, + "Longitude": -97.7972, + "MetroCode": 635, + "TimeZone": "America/Chicago" + }, + "Postal": { + "Code": "78745" + }, + "RegisteredCountry": { + "GeoNameID": 6252001, + "IsoCode": "US", + "Names": { + "de": "USA", + "en": "United States", + "es": "Estados Unidos", + "fr": "\u00c9tats Unis", + "ja": "\u30a2\u30e1\u30ea\u30ab", + "pt-BR": "EUA", + "ru": "\u0421\u0428\u0410", + "zh-CN": "\u7f8e\u56fd" + } + }, + "RepresentedCountry": { + "GeoNameID": 0, + "IsoCode": "", + "Names": null, + "Type": "" + }, + "Subdivisions": [ + { + "GeoNameID": 4736286, + "IsoCode": "TX", + "Names": { + "en": "Texas", + "es": "Texas", + "fr": "Texas", + "ja": "\u30c6\u30ad\u30b5\u30b9\u5dde", + "ru": "\u0422\u0435\u0445\u0430\u0441", + "zh-CN": "\u5fb7\u514b\u8428\u65af\u5dde" + } + } + ], + "Traits": { + "IsAnonymousProxy": false, + "IsSatelliteProvider": false + } + }, + "IP": "999.999.999.999" +} +` + +func TestGetIP(t *testing.T) { + currentGeoInfo = eventual.NewValue() + roundTripper = &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 10 * time.Second, + }).Dial, + } + ip := GetIP(0) + require.Equal(t, "", ip) + go Refresh() + ip = GetIP(-1) + addr := net.ParseIP(ip) + require.NotNil(t, addr) +} + +func TestGetCountry(t *testing.T) { + currentGeoInfo = eventual.NewValue() + roundTripper = &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 10 * time.Second, + }).Dial, + } + + country := GetCountry(0) + require.Equal(t, "", country) + go Refresh() + country = GetCountry(-1) + require.NotEmpty(t, country) +} + +func TestFronted(t *testing.T) { + currentGeoInfo = eventual.NewValue() + geoFile, err := os.CreateTemp("", "") + require.NoError(t, err) + defer os.Remove(geoFile.Name()) + + os.WriteFile(geoFile.Name(), []byte(initialInfo), 0644) + + fronted.ConfigureHostAlaisesForTest(t, map[string]string{ + "geo.getiantem.org": "d3u5fqukq7qrhd.cloudfront.net", + }) + + // test persistence + ch := OnRefresh() + EnablePersistence(geoFile.Name()) + country := GetCountry(0) + require.Equal(t, "FM", country, "Should immediately get persisted country") + select { + case <-ch: + // okay + case <-time.After(5 * time.Second): + t.Error("should update watcher after enabling persistence") + } + + // clear initial value to make sure we read value from network + currentGeoInfo.Reset() + Refresh() + country = GetCountry(60 * time.Second) + ip := GetIP(5 * time.Second) + require.Len(t, country, 2, "Bad country '%v' for ip %v", country, ip) + require.NotEqual( + t, + "FM", + country, + "Should have gotten a new country from network (note, this test will fail if run in Micronesia)", + ) + require.True(t, len(ip) >= 7, "Bad IP %s", ip) + + t.Log("Waiting for refresh again") + select { + case <-ch: + // okay + case <-time.After(5 * time.Second): + t.Error("should update watcher after network refresh") + } + + // Give persistence time to finish + time.Sleep(1 * time.Second) + b, err := os.ReadFile(geoFile.Name()) + require.NoError(t, err) + require.NotEmpty(t, b) + require.NotEqual( + t, + initialInfo, + string(b), + "persisted geolocation information should have changed", + ) +} + +func TestIsNew(t *testing.T) { + type args struct { + newGeoInfo *GeoInfo + oldGeoInfo *GeoInfo + } + tests := []struct { + name string + args args + want bool + }{ + {"nil new should be not new", args{nil, &GeoInfo{FromDisk: true}}, false}, + {"nil existing should be new", args{&GeoInfo{}, nil}, true}, + {"old from disk should be new", args{&GeoInfo{IP: "1.1.1.1", FromDisk: false}, &GeoInfo{IP: "1.1.1.1", FromDisk: true}}, true}, + {"old not from disk should not be new", args{&GeoInfo{IP: "1.1.1.1", FromDisk: false}, &GeoInfo{IP: "1.1.1.1", FromDisk: false}}, false}, + {"new IP should be new", args{&GeoInfo{IP: "1.1.1.2", FromDisk: false}, &GeoInfo{IP: "1.1.1.1", FromDisk: false}}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + currentGeoInfo.Set(tt.args.oldGeoInfo) + if got := isNew(tt.args.newGeoInfo); got != tt.want { + t.Errorf("isNew() = %v, want %v", got, tt.want) + } + }) + } +} From c4b1e4351859d8f954ac28627f91f83b74d1688d Mon Sep 17 00:00:00 2001 From: hwh33 Date: Tue, 17 Dec 2024 11:36:26 -0700 Subject: [PATCH 4/6] Add documentation for command-line implementation (#1269) --- README.md | 11 +++++++++++ cli/cli.go | 2 ++ 2 files changed, 13 insertions(+) diff --git a/README.md b/README.md index 9b372eaee..322f28b4b 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,17 @@ All these dependencies must be in your PATH. Some of this is Android specific, s * `flutter pub get` * `flutter run --flavor prod` or if you are using android studio use desktop configuration +#### As a Command-Line Application + +A command-line implementation of Lantern is defined in the `cli` directory. + +* `go build -o lantern-cli ./cli` +* `./lantern-cli ` (run with `-h` or `--help` to see available arguments) + +You will likely want to specify the `-addr` argument (e.g. `-addr localhost:8080`) to define where the local proxy should be available. + +If you want to point at a specific remote proxy, consult `hit_proxy.bash` for an example on how to set up a config directory with specific proxy config. + ### Running on emulators You can easily run emulators directly from the command line with the following: diff --git a/cli/cli.go b/cli/cli.go index 0a11ce9b1..dd0f86567 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -1,3 +1,5 @@ +// Command cli provides a command-line implementation of the Lantern client. Run this command with +// -h or --help to see all available arguments. package main import ( From e9c9ecc7a0b2360d000a59808b29a0e8dc60f72b Mon Sep 17 00:00:00 2001 From: jigar-f <132374182+jigar-f@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:07:14 +0530 Subject: [PATCH 5/6] Report issue Fix (#1268) * Pass country to report issue on ios. * Update flashlight. --- desktop/lib.go | 1 + go.mod | 12 +++++++----- go.sum | 16 ++++++++++------ internalsdk/issue.go | 8 ++++++++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/desktop/lib.go b/desktop/lib.go index 4dec9adc6..095b09ef3 100644 --- a/desktop/lib.go +++ b/desktop/lib.go @@ -421,6 +421,7 @@ func reportIssue(email, issueType, description *C.char) *C.char { osVersion, "", nil, + "", ) if err != nil { return sendError(err) diff --git a/go.mod b/go.mod index 4ea2fae86..1b163576e 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,9 @@ require ( github.com/getlantern/eventual v1.0.0 github.com/getlantern/eventual/v2 v2.0.2 github.com/getlantern/filepersist v0.0.0-20210901195658-ed29a1cb0b7c - github.com/getlantern/flashlight/v7 v7.6.165 + github.com/getlantern/flashlight/v7 v7.6.168-0.20241217081327-6fc8e4f5835d + github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e + github.com/getlantern/geolookup v0.0.0-20230327091034-aebe73c6eef4 github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770 github.com/getlantern/i18n v0.0.0-20181205222232-2afc4f49bb1c @@ -71,7 +73,7 @@ require ( github.com/pterm/pterm v0.12.80 github.com/shopspring/decimal v1.4.0 github.com/stretchr/testify v1.9.0 - golang.org/x/crypto v0.28.0 + golang.org/x/crypto v0.29.0 golang.org/x/mobile v0.0.0-20241016134751-7ff83004ec2c golang.org/x/net v0.30.0 golang.org/x/sys v0.27.0 @@ -87,13 +89,13 @@ require ( github.com/cloudflare/circl v1.3.7 // indirect github.com/coder/websocket v1.8.12 // indirect github.com/containerd/console v1.0.3 // indirect - github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e // indirect - github.com/getlantern/geolookup v0.0.0-20230327091034-aebe73c6eef4 // indirect - github.com/golang/protobuf v1.5.4 // indirect + github.com/getlantern/sing-vmess v0.0.0-20241209111030-0f2c02b4eb9a // indirect + github.com/gofrs/uuid/v5 v5.3.0 // indirect github.com/gookit/color v1.5.4 // indirect github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/sagernet/sing v0.6.0-alpha.18 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/term v0.26.0 // indirect ) diff --git a/go.sum b/go.sum index 8ae0313a7..13cf4712b 100644 --- a/go.sum +++ b/go.sum @@ -315,8 +315,8 @@ github.com/getlantern/fdcount v0.0.0-20210503151800-5decd65b3731/go.mod h1:XZwE+ github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799/go.mod h1:8DGAx0LNUfXNnEH+fXI0s3OCBA/351kZCiz/8YSK3i8= github.com/getlantern/filepersist v0.0.0-20210901195658-ed29a1cb0b7c h1:mcz27xtAkb1OuOLBct/uFfL1p3XxAIcFct82GbT+UZM= github.com/getlantern/filepersist v0.0.0-20210901195658-ed29a1cb0b7c/go.mod h1:8DGAx0LNUfXNnEH+fXI0s3OCBA/351kZCiz/8YSK3i8= -github.com/getlantern/flashlight/v7 v7.6.165 h1:hsp69HtmglAJ0Y/bdRG6H4KgNWlqAji4ZbEsHbY9YlQ= -github.com/getlantern/flashlight/v7 v7.6.165/go.mod h1:+MgkTf2ulz2pYSTIDKLJjclERW4cv3cAtrA4ynSBjsM= +github.com/getlantern/flashlight/v7 v7.6.168-0.20241217081327-6fc8e4f5835d h1:wzFlenY9XR6rDdpJ2sQX0eR5076vpegKwxSWsSqzmB0= +github.com/getlantern/flashlight/v7 v7.6.168-0.20241217081327-6fc8e4f5835d/go.mod h1:bFJngz+QjTqbSJkYqxX1+xk5iV5Itt9lPTFnlNq8wLk= github.com/getlantern/framed v0.0.0-20190601192238-ceb6431eeede h1:yrU6Px3ZkvCsDLPryPGi6FN+2iqFPq+JeCb7EFoDBhw= github.com/getlantern/framed v0.0.0-20190601192238-ceb6431eeede/go.mod h1:nhnoiS6DE6zfe+BaCMU4YI01UpsuiXnDqM5S8jxHuuI= github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e h1:qk62Xhg+ha1sW6FhOmGPGbd3xnCC5n9Mr87vDToE0cM= @@ -447,6 +447,8 @@ github.com/getlantern/safechannels v0.0.0-20201218194342-b4e5383e9627 h1:eYXtxjR github.com/getlantern/safechannels v0.0.0-20201218194342-b4e5383e9627/go.mod h1:QJUudepmTj/KQXnReV6DZSJY/xO05fnfcZf3t8zkNLg= github.com/getlantern/shortcut v0.0.0-20211026183428-bf59a137fdec h1:8TfjIMydnhBs4edmXu2Nz1f2P0QOcXfol2rR1cxfrSs= github.com/getlantern/shortcut v0.0.0-20211026183428-bf59a137fdec/go.mod h1:3VQ6qvEBehqDBNbEKfNtSjK6MR5ydOdjMPgKjKay7vo= +github.com/getlantern/sing-vmess v0.0.0-20241209111030-0f2c02b4eb9a h1:EaWmH5vANbKEXCdfgTChyEpWWwLsSrLPKqO6j0h+IB8= +github.com/getlantern/sing-vmess v0.0.0-20241209111030-0f2c02b4eb9a/go.mod h1:eyj3LXZUf1aYph1WD19MKwbj5kMUQR92WBQfOAYpb/4= github.com/getlantern/sysproxy v0.0.0-20240711003440-384834c7b4cb h1:9eaFCu1MZ5yp1vpg6KNOkjTzQnfo2MAbgqOqL/AnmAw= github.com/getlantern/sysproxy v0.0.0-20240711003440-384834c7b4cb/go.mod h1:sIaf1EQGv8d+l71iPiFYiLJtBp9fRy5wgO3mTFXSPzM= github.com/getlantern/telemetry v0.0.0-20230523155019-be7c1d8cd8cb h1:6XZ3Q4oD6A1Tjq6QLgzzQrdQ8FvulzW16HhNQOSECAM= @@ -520,6 +522,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= +github.com/gofrs/uuid/v5 v5.3.0 h1:m0mUMr+oVYUdxpMLgSYCZiXe7PuVPnI94+OMeVBNedk= +github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -548,8 +552,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -902,6 +904,8 @@ github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 h1:18kd+8ZUlt/ARXhljq+ github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= +github.com/sagernet/sing v0.6.0-alpha.18 h1:ih4CurU8KvbhfagYjSqVrE2LR0oBSXSZTNH2sAGPGiM= +github.com/sagernet/sing v0.6.0-alpha.18/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= @@ -1084,8 +1088,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= diff --git a/internalsdk/issue.go b/internalsdk/issue.go index f162deb03..1be893ab0 100644 --- a/internalsdk/issue.go +++ b/internalsdk/issue.go @@ -2,9 +2,11 @@ package internalsdk import ( "strconv" + "time" "github.com/getlantern/flashlight/v7/issue" "github.com/getlantern/lantern-client/internalsdk/common" + "github.com/getlantern/lantern-client/internalsdk/ios/geolookup" ) var issueMap = map[string]string{ @@ -34,6 +36,11 @@ func SendIssueReport( if err != nil { return err } + var country string + if common.Platform == "ios" { + country = geolookup.GetCountry(5 * time.Second) + log.Debugf("Country For report issue %v", country) + } return issue.SendReport( &userConfig{&panickingSessionImpl{session}}, issueTypeInt, @@ -45,5 +52,6 @@ func SendIssueReport( model, osVersion, nil, + country, ) } From 71952080205560045ad9f0c2abe009dd7f20f8db Mon Sep 17 00:00:00 2001 From: Jigar-f Date: Wed, 18 Dec 2024 20:50:03 +0530 Subject: [PATCH 6/6] Updated flashlight, fronted and added null check. --- go.mod | 9 +++--- go.sum | 17 ++++++----- ios/Podfile.lock | 61 ++++++++++++++++++++------------------- lib/core/utils/utils.dart | 6 +++- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index 1b163576e..b8051e3bb 100644 --- a/go.mod +++ b/go.mod @@ -37,8 +37,8 @@ require ( github.com/getlantern/eventual v1.0.0 github.com/getlantern/eventual/v2 v2.0.2 github.com/getlantern/filepersist v0.0.0-20210901195658-ed29a1cb0b7c - github.com/getlantern/flashlight/v7 v7.6.168-0.20241217081327-6fc8e4f5835d - github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e + github.com/getlantern/flashlight/v7 v7.6.173 + github.com/getlantern/fronted v0.0.0-20241218113928-4db253857875 github.com/getlantern/geolookup v0.0.0-20230327091034-aebe73c6eef4 github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770 @@ -72,7 +72,7 @@ require ( github.com/moul/http2curl v1.0.0 github.com/pterm/pterm v0.12.80 github.com/shopspring/decimal v1.4.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 golang.org/x/crypto v0.29.0 golang.org/x/mobile v0.0.0-20241016134751-7ff83004ec2c golang.org/x/net v0.30.0 @@ -89,6 +89,7 @@ require ( github.com/cloudflare/circl v1.3.7 // indirect github.com/coder/websocket v1.8.12 // indirect github.com/containerd/console v1.0.3 // indirect + github.com/getlantern/lantern-water v0.0.0-20241218135103-60224336cf1d // indirect github.com/getlantern/sing-vmess v0.0.0-20241209111030-0f2c02b4eb9a // indirect github.com/gofrs/uuid/v5 v5.3.0 // indirect github.com/gookit/color v1.5.4 // indirect @@ -341,7 +342,7 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/mock v0.4.0 // indirect + go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect diff --git a/go.sum b/go.sum index 13cf4712b..fe369b9f5 100644 --- a/go.sum +++ b/go.sum @@ -315,12 +315,12 @@ github.com/getlantern/fdcount v0.0.0-20210503151800-5decd65b3731/go.mod h1:XZwE+ github.com/getlantern/filepersist v0.0.0-20160317154340-c5f0cd24e799/go.mod h1:8DGAx0LNUfXNnEH+fXI0s3OCBA/351kZCiz/8YSK3i8= github.com/getlantern/filepersist v0.0.0-20210901195658-ed29a1cb0b7c h1:mcz27xtAkb1OuOLBct/uFfL1p3XxAIcFct82GbT+UZM= github.com/getlantern/filepersist v0.0.0-20210901195658-ed29a1cb0b7c/go.mod h1:8DGAx0LNUfXNnEH+fXI0s3OCBA/351kZCiz/8YSK3i8= -github.com/getlantern/flashlight/v7 v7.6.168-0.20241217081327-6fc8e4f5835d h1:wzFlenY9XR6rDdpJ2sQX0eR5076vpegKwxSWsSqzmB0= -github.com/getlantern/flashlight/v7 v7.6.168-0.20241217081327-6fc8e4f5835d/go.mod h1:bFJngz+QjTqbSJkYqxX1+xk5iV5Itt9lPTFnlNq8wLk= +github.com/getlantern/flashlight/v7 v7.6.173 h1:JvFMZlysbBcURai0JsuIrnlku6EUsbWuqcSn3aTbcYI= +github.com/getlantern/flashlight/v7 v7.6.173/go.mod h1:2HDjD6lx7W5hbTh3Vg572bHVFd9YZ4YODLl2b+d7JBw= github.com/getlantern/framed v0.0.0-20190601192238-ceb6431eeede h1:yrU6Px3ZkvCsDLPryPGi6FN+2iqFPq+JeCb7EFoDBhw= github.com/getlantern/framed v0.0.0-20190601192238-ceb6431eeede/go.mod h1:nhnoiS6DE6zfe+BaCMU4YI01UpsuiXnDqM5S8jxHuuI= -github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e h1:qk62Xhg+ha1sW6FhOmGPGbd3xnCC5n9Mr87vDToE0cM= -github.com/getlantern/fronted v0.0.0-20241212194832-a55b6db2616e/go.mod h1:UOynqDcVIlDMFk3sdUyHzNyY1cz4GHtJ+8qvWESHWhg= +github.com/getlantern/fronted v0.0.0-20241218113928-4db253857875 h1:i87Jjwv5XdhTMWvkU3zZusp9A5NvSbX39x38UEuJ3cw= +github.com/getlantern/fronted v0.0.0-20241218113928-4db253857875/go.mod h1:UOynqDcVIlDMFk3sdUyHzNyY1cz4GHtJ+8qvWESHWhg= github.com/getlantern/geo v0.0.0-20241129152027-2fc88c10f91e h1:vpikNz6IzvEoqVYmiK5Uq+lE4TCzvMDqbZdxFbtGK1g= github.com/getlantern/geo v0.0.0-20241129152027-2fc88c10f91e/go.mod h1:RjQ0krF8NTCc5xo2Q1995/vZBnYg33h8svn15do7dLg= github.com/getlantern/geolookup v0.0.0-20230327091034-aebe73c6eef4 h1:Ju9l1RretVWJTNo2vpl/xAW8Dcuiyg5kJC6LRBpCigw= @@ -383,6 +383,8 @@ github.com/getlantern/lampshade v0.0.0-20201109225444-b06082e15f3a h1:z7G1v79GB1 github.com/getlantern/lampshade v0.0.0-20201109225444-b06082e15f3a/go.mod h1:cGOfTjvllC9bcwS7cVW6tGT6fXc8Dki384uFjm7XBnw= github.com/getlantern/lantern-algeneva v0.0.0-20240930181006-6d3c00db1d5d h1:ACBwPR4du54Qw+X5ajsbMqOFR8euGZRdMGkvTDS7I60= github.com/getlantern/lantern-algeneva v0.0.0-20240930181006-6d3c00db1d5d/go.mod h1:bDcK4RWBjBO+bBPLTCmaEyYK+n0/w0TrzvSCJOQmkgk= +github.com/getlantern/lantern-water v0.0.0-20241218135103-60224336cf1d h1:O/25LnEtZt11moaSfT7+XjTsxau4LJO8L/fguiRATUY= +github.com/getlantern/lantern-water v0.0.0-20241218135103-60224336cf1d/go.mod h1:ZpSOrcdJkmb8MvaQn6mxaidxshlyi+RJLUerhW4L5Lo= github.com/getlantern/launcher v0.0.0-20230622120034-fe87f9bff286 h1:b8XesQLtoq58M8FcYxxfWDUcBOzbGfBJGDOZDQ4PjYs= github.com/getlantern/launcher v0.0.0-20230622120034-fe87f9bff286/go.mod h1:pEDM+G+PFz616x02zkWcmhjaeZ9rHDKZL8stK3uE9J8= github.com/getlantern/mandrill v0.0.0-20221004112352-e7c04248adcb h1:oyEMOT9jn4bzKyivF2sVBogsXyL8fBCK7HIT/P6h64Y= @@ -970,8 +972,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/templexxx/cpu v0.1.1 h1:isxHaxBXpYFWnk2DReuKkigaZyrjs2+9ypIdGP4h+HI= @@ -1061,8 +1064,8 @@ go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0 go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2f58eb22d..6f8e66480 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -70,13 +70,13 @@ PODS: - fluttertoast (0.0.2): - Flutter - Toast - - Google-Mobile-Ads-SDK (11.2.0): + - Google-Mobile-Ads-SDK (11.10.0): - GoogleUserMessagingPlatform (>= 1.1) - - google_mobile_ads (5.1.0): + - google_mobile_ads (5.2.0): - Flutter - - Google-Mobile-Ads-SDK (~> 11.2.0) + - Google-Mobile-Ads-SDK (~> 11.10.0) - webview_flutter_wkwebview - - GoogleUserMessagingPlatform (2.6.0) + - GoogleUserMessagingPlatform (2.7.0) - in_app_purchase_storekit (0.0.1): - Flutter - FlutterMacOS @@ -109,23 +109,23 @@ PODS: - qr_code_scanner (0.2.0): - Flutter - MTBBarcodeScanner - - SDWebImage (5.19.7): - - SDWebImage/Core (= 5.19.7) - - SDWebImage/Core (5.19.7) + - SDWebImage (5.20.0): + - SDWebImage/Core (= 5.20.0) + - SDWebImage/Core (5.20.0) - SDWebImageWebPCoder (0.14.6): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.17) - - Sentry/HybridSDK (8.36.0) - - sentry_flutter (8.9.0): + - Sentry/HybridSDK (8.40.1) + - sentry_flutter (8.10.1): - Flutter - FlutterMacOS - - Sentry/HybridSDK (= 8.36.0) + - Sentry/HybridSDK (= 8.40.1) - share_plus (0.0.1): - Flutter - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - - sqflite (0.0.3): + - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS - SwiftyGif (5.4.5) @@ -141,6 +141,7 @@ PODS: - libwebp - webview_flutter_wkwebview (0.0.1): - Flutter + - FlutterMacOS DEPENDENCIES: - app_links (from `.symlinks/plugins/app_links/ios`) @@ -167,12 +168,12 @@ DEPENDENCIES: - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - - sqflite (from `.symlinks/plugins/sqflite/darwin`) + - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - Toast-Swift (~> 5.0.1) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`) - video_thumbnail (from `.symlinks/plugins/video_thumbnail/ios`) - - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`) SPEC REPOS: https://github.com/CocoaPods/Specs.git: @@ -241,8 +242,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" - sqflite: - :path: ".symlinks/plugins/sqflite/darwin" + sqflite_darwin: + :path: ".symlinks/plugins/sqflite_darwin/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" video_player_avfoundation: @@ -250,14 +251,14 @@ EXTERNAL SOURCES: video_thumbnail: :path: ".symlinks/plugins/video_thumbnail/ios" webview_flutter_wkwebview: - :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" + :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin" SPEC CHECKSUMS: Alamofire: 814429acc853c6c54ff123fc3d2ef66803823ce0 app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0 audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 - connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db - device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d + connectivity_plus: 4c41c08fc6d7c91f63bc7aec70ffe3730b04f563 + device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342 DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 emoji_picker_flutter: fe2e6151c5b548e975d546e6eeb567daf0962a58 @@ -266,38 +267,38 @@ SPEC CHECKSUMS: flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 - flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086 + flutter_local_notifications: df98d66e515e1ca797af436137b4459b160ad8c9 flutter_pdfview: 25f53dd6097661e6395b17de506e6060585946bd flutter_uploader: 2b07c4d41cf1218f25e6d5b8bcfa2d913838e27c fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c - Google-Mobile-Ads-SDK: 5a6d005a6cb5b5e8f4c7b69ca05cdea79c181139 - google_mobile_ads: 9379c80fdfa9988fb0e105a407890ff8deb3cf86 - GoogleUserMessagingPlatform: 0c3a08353e53ce8c2feab7addd0b652cde522450 + Google-Mobile-Ads-SDK: 13e6e98edfd78ad8d8a791edb927658cc260a56f + google_mobile_ads: 2a538d8e42b1813809782792e48f8cf4374c2180 + GoogleUserMessagingPlatform: a8b56893477f67212fbc8411c139e61d463349f5 in_app_purchase_storekit: 8c3b0b3eb1b0f04efbff401c3de6266d4258d433 integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 - package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c + package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e - SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3 + SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8 SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 - Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57 - sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe - share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad + Sentry: e9215d7b17f7902692b4f8700e061e4f853e3521 + sentry_flutter: 927eed60d66951d1b0f1db37fe94ff5cb7c80231 + share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec + sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e Toast-Swift: 9b6a70f28b3bf0b96c40d46c0c4b9d6639846711 url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 video_thumbnail: c4e2a3c539e247d4de13cd545344fd2d26ffafd1 - webview_flutter_wkwebview: 2a23822e9039b7b1bc52e5add778e5d89ad488d1 + webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4 PODFILE CHECKSUM: edbeaea3b499feb7b2b276309b09c237de1a6cff -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 9d16ed46a..4138846ce 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -188,7 +188,11 @@ Plan planFromJson(Map item) { return plan; } -Map paymentMethodsFromJson(List items) { +Map paymentMethodsFromJson(dynamic json) { + if(json == null) { + return {}; + } + List items = json as List; final paymentMethods = Map(); items.forEach((value) { final json = jsonDecode(jsonEncode(value));