From 813776fd7a1a49eba8f08a054341e73bda493c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20Cie=C5=9Blak?= <27113+ravicious@users.noreply.github.com> Date: Tue, 16 Jun 2026 19:29:26 +0200 Subject: [PATCH] Add Xcode project for Teleport Verify; add gomobile as tool dep (#67750) * Generate Xcode project for Verify * Set Swift version to 6; remove macOS and Vision as destinations * Handle `teleport://` links and add enrollment screen * Avoid building macOS-specific stuff on iOS This is needed for gomobile to build our stuff from lib/mobile from the next commit. * Add `lib/mobile/verify/enroll` compiled with gomobile * `lib/mobile`: Temporarily use private Device Trust service The public gRPC service exists on the demo branch but not on this branch. In order to make it possible to compile `lib/mobile/verify/enroll`, temporarily use the private service which has similar RPCs. * Run `make go-mod-tidy-all` * Make Swift app connect to public DT service on "Request Now" tap * mobile: Add sheet for enroll request status * Revert go.mod changes This reverts commit b9af7a761419d5f34a552feffbf3831aa3fdb3a1 and 2c00ecd7fab0fd4d60bdf4926ac354f95c0fa10d. * Add `build.assets/tools/gomobile` * Move gomobile back to main go.mod This reverts commits 9b2a6c4ea351921f96aaa011a4c56a898141e444 and a83c2959fa5e11d00094c76574d709482f1dceca. --- Makefile | 4 + build.assets/tooling/go.mod | 8 +- build.assets/tooling/go.sum | 16 +- e2e/runner/go.mod | 8 +- e2e/runner/go.sum | 16 +- go.mod | 13 +- go.sum | 22 +- integrations/event-handler/go.mod | 8 +- integrations/event-handler/go.sum | 16 +- integrations/terraform-mwi/go.mod | 8 +- integrations/terraform-mwi/go.sum | 20 +- integrations/terraform/go.mod | 8 +- integrations/terraform/go.sum | 20 +- lib/mobile/verify/enroll/enroll.go | 118 +++++ lib/utils/log/oslog/oslog_darwin.go | 1 + lib/utils/log/slog_text_handler_darwin.go | 2 +- lib/utils/log/slog_text_handler_other.go | 2 +- mobile/.gitignore | 18 + .../Verify/Verify.xcodeproj/project.pbxproj | 407 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 35 ++ .../Verify/Assets.xcassets/Contents.json | 6 + .../logo.imageset/Contents.json | 82 ++++ .../logo.imageset/enterprise-dark.svg | 1 + .../logo.imageset/enterprise-light.svg | 1 + mobile/Verify/Verify/ContentView.swift | 102 +++++ mobile/Verify/Verify/DeepLink.swift | 103 +++++ .../Verify/EnrollMobileDeviceView.swift | 126 ++++++ .../Verify/EnrollMobileDeviceViewModel.swift | 68 +++ .../Verify/EnrollRequestStatusView.swift | 115 +++++ mobile/Verify/Verify/Info.plist | 19 + mobile/Verify/Verify/LandingView.swift | 30 ++ mobile/Verify/Verify/VerifyApp.swift | 33 ++ 34 files changed, 1373 insertions(+), 81 deletions(-) create mode 100644 lib/mobile/verify/enroll/enroll.go create mode 100644 mobile/.gitignore create mode 100644 mobile/Verify/Verify.xcodeproj/project.pbxproj create mode 100644 mobile/Verify/Verify.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 mobile/Verify/Verify/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 mobile/Verify/Verify/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 mobile/Verify/Verify/Assets.xcassets/Contents.json create mode 100644 mobile/Verify/Verify/Assets.xcassets/logo.imageset/Contents.json create mode 100644 mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-dark.svg create mode 100644 mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-light.svg create mode 100644 mobile/Verify/Verify/ContentView.swift create mode 100644 mobile/Verify/Verify/DeepLink.swift create mode 100644 mobile/Verify/Verify/EnrollMobileDeviceView.swift create mode 100644 mobile/Verify/Verify/EnrollMobileDeviceViewModel.swift create mode 100644 mobile/Verify/Verify/EnrollRequestStatusView.swift create mode 100644 mobile/Verify/Verify/Info.plist create mode 100644 mobile/Verify/Verify/LandingView.swift create mode 100644 mobile/Verify/Verify/VerifyApp.swift diff --git a/Makefile b/Makefile index ee6a434909c..5b5e52ce057 100644 --- a/Makefile +++ b/Makefile @@ -2131,3 +2131,7 @@ ifndef BENCH_FILES $(error "Please provide BENCH_FILES= ...") endif @$(BENCHSTAT) $(BENCH_FILES) | tee test-logs/benchstat.txt + +.PHONY: mobile/Verify/Verify/gen/Enroll.xcframework +mobile/Verify/Verify/gen/Enroll.xcframework: + go tool gomobile bind -target=ios -o $@ github.com/gravitational/teleport/lib/mobile/verify/enroll diff --git a/build.assets/tooling/go.mod b/build.assets/tooling/go.mod index 509d943ca3a..87c60f22975 100644 --- a/build.assets/tooling/go.mod +++ b/build.assets/tooling/go.mod @@ -18,9 +18,9 @@ require ( github.com/gravitational/trace v1.5.4 github.com/stretchr/testify v1.11.1 github.com/waigani/diffparser v0.0.0-20190828052634-7391f219313d - golang.org/x/mod v0.36.0 + golang.org/x/mod v0.37.0 golang.org/x/oauth2 v0.36.0 - golang.org/x/tools v0.45.0 + golang.org/x/tools v0.46.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.21.0 @@ -270,8 +270,8 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.53.0 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect - golang.org/x/image v0.41.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/image v0.42.0 // indirect + golang.org/x/net v0.56.0 // indirect golang.org/x/sync v0.21.0 // indirect golang.org/x/sys v0.46.0 // indirect golang.org/x/term v0.44.0 // indirect diff --git a/build.assets/tooling/go.sum b/build.assets/tooling/go.sum index 7df52b1994d..c02c30b4a28 100644 --- a/build.assets/tooling/go.sum +++ b/build.assets/tooling/go.sum @@ -889,14 +889,14 @@ golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= -golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= -golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= +golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY= +golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -908,8 +908,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -960,8 +960,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= -golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= +golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/e2e/runner/go.mod b/e2e/runner/go.mod index 53db6228d0d..0b239cff27f 100644 --- a/e2e/runner/go.mod +++ b/e2e/runner/go.mod @@ -264,14 +264,14 @@ require ( go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect - golang.org/x/image v0.41.0 // indirect - golang.org/x/mod v0.36.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/image v0.42.0 // indirect + golang.org/x/mod v0.37.0 // indirect + golang.org/x/net v0.56.0 // indirect golang.org/x/sys v0.46.0 // indirect golang.org/x/term v0.44.0 // indirect golang.org/x/text v0.38.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.45.0 // indirect + golang.org/x/tools v0.46.0 // indirect google.golang.org/api v0.272.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect diff --git a/e2e/runner/go.sum b/e2e/runner/go.sum index 80d1c337fb7..b97b21e47bf 100644 --- a/e2e/runner/go.sum +++ b/e2e/runner/go.sum @@ -895,14 +895,14 @@ golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= -golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= -golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= +golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY= +golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -913,8 +913,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -963,8 +963,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= -golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= +golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/go.mod b/go.mod index fd4efbd7999..561d0a77a96 100644 --- a/go.mod +++ b/go.mod @@ -247,16 +247,16 @@ require ( go.uber.org/goleak v1.3.0 golang.org/x/crypto v0.53.0 golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f - golang.org/x/image v0.41.0 - golang.org/x/mod v0.36.0 - golang.org/x/net v0.55.0 + golang.org/x/image v0.42.0 + golang.org/x/mod v0.37.0 + golang.org/x/net v0.56.0 golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.21.0 golang.org/x/sys v0.46.0 golang.org/x/term v0.44.0 golang.org/x/text v0.38.0 golang.org/x/time v0.15.0 - golang.org/x/tools v0.45.0 + golang.org/x/tools v0.46.0 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 google.golang.org/api v0.272.0 @@ -598,7 +598,8 @@ require ( go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6 // indirect + golang.org/x/mobile v0.0.0-20260611195102-4dd8f1dbf5d2 // indirect + golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect @@ -642,3 +643,5 @@ replace ( github.com/redis/go-redis/v9 => github.com/gravitational/redis/v9 v9.6.1-teleport.1 github.com/vulcand/predicate => github.com/gravitational/predicate v1.4.0 ) + +tool golang.org/x/mobile/cmd/gomobile diff --git a/go.sum b/go.sum index b950740940c..cfbd673d731 100644 --- a/go.sum +++ b/go.sum @@ -1526,18 +1526,20 @@ golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsi golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= -golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= -golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= +golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY= +golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20260611195102-4dd8f1dbf5d2 h1:zoM1gIKhVkcQNm43kad8OHLgPNoJ12xIqmxHtKr8Mug= +golang.org/x/mobile v0.0.0-20260611195102-4dd8f1dbf5d2/go.mod h1:QGMqsqLn6orFQ/ksqYMf+Fa33Soa1vPoHEd0Pj7N+lQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1560,8 +1562,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -1607,8 +1609,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6 h1:HjU6IWBiAgRIdAJ9/y1rwCn+UELEmwV+VsTLzj/W4sE= -golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6/go.mod h1:Eqhaxk/wZsWEH8CRxLwj6xzEJbz7k1EFGqx7nyCoabE= +golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9 h1:FjUup8XrRy7lv+XHONi6KKUSizeF2NnVrTnz/HhbohQ= +golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= @@ -1643,8 +1645,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= -golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= +golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= diff --git a/integrations/event-handler/go.mod b/integrations/event-handler/go.mod index 1efbf14eef6..4f0abf4e16c 100644 --- a/integrations/event-handler/go.mod +++ b/integrations/event-handler/go.mod @@ -15,7 +15,7 @@ require ( github.com/peterbourgon/diskv/v3 v3.0.1 github.com/sethvargo/go-limiter v1.1.0 github.com/stretchr/testify v1.11.1 - golang.org/x/net v0.55.0 + golang.org/x/net v0.56.0 golang.org/x/time v0.15.0 google.golang.org/protobuf v1.36.11 ) @@ -350,14 +350,14 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.53.0 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect - golang.org/x/image v0.41.0 // indirect - golang.org/x/mod v0.36.0 // indirect + golang.org/x/image v0.42.0 // indirect + golang.org/x/mod v0.37.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.21.0 // indirect golang.org/x/sys v0.46.0 // indirect golang.org/x/term v0.44.0 // indirect golang.org/x/text v0.38.0 // indirect - golang.org/x/tools v0.45.0 // indirect + golang.org/x/tools v0.46.0 // indirect google.golang.org/api v0.272.0 // indirect google.golang.org/genproto v0.0.0-20260316180232-0b37fe3546d5 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect diff --git a/integrations/event-handler/go.sum b/integrations/event-handler/go.sum index 37459fae660..972efe7dc81 100644 --- a/integrations/event-handler/go.sum +++ b/integrations/event-handler/go.sum @@ -1026,14 +1026,14 @@ golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= -golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= -golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= +golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY= +golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1044,8 +1044,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1096,8 +1096,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= -golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= +golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integrations/terraform-mwi/go.mod b/integrations/terraform-mwi/go.mod index 9cda1d18ffc..04c4044cc4b 100644 --- a/integrations/terraform-mwi/go.mod +++ b/integrations/terraform-mwi/go.mod @@ -474,16 +474,16 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.53.0 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect - golang.org/x/image v0.41.0 // indirect - golang.org/x/mod v0.36.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/image v0.42.0 // indirect + golang.org/x/mod v0.37.0 // indirect + golang.org/x/net v0.56.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.21.0 // indirect golang.org/x/sys v0.46.0 // indirect golang.org/x/term v0.44.0 // indirect golang.org/x/text v0.38.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.45.0 // indirect + golang.org/x/tools v0.46.0 // indirect google.golang.org/api v0.272.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20260316180232-0b37fe3546d5 // indirect diff --git a/integrations/terraform-mwi/go.sum b/integrations/terraform-mwi/go.sum index 9aa1c230308..0dc33e6a812 100644 --- a/integrations/terraform-mwi/go.sum +++ b/integrations/terraform-mwi/go.sum @@ -1450,8 +1450,8 @@ golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsi golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= -golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= -golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= +golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY= +golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -1460,8 +1460,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1479,8 +1479,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -1516,8 +1516,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6 h1:HjU6IWBiAgRIdAJ9/y1rwCn+UELEmwV+VsTLzj/W4sE= -golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6/go.mod h1:Eqhaxk/wZsWEH8CRxLwj6xzEJbz7k1EFGqx7nyCoabE= +golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9 h1:FjUup8XrRy7lv+XHONi6KKUSizeF2NnVrTnz/HhbohQ= +golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= @@ -1551,8 +1551,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= -golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= +golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integrations/terraform/go.mod b/integrations/terraform/go.mod index 204f4727b34..a86ac95c027 100644 --- a/integrations/terraform/go.mod +++ b/integrations/terraform/go.mod @@ -476,16 +476,16 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.53.0 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect - golang.org/x/image v0.41.0 // indirect - golang.org/x/mod v0.36.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/image v0.42.0 // indirect + golang.org/x/mod v0.37.0 // indirect + golang.org/x/net v0.56.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.21.0 // indirect golang.org/x/sys v0.46.0 // indirect golang.org/x/term v0.44.0 // indirect golang.org/x/text v0.38.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.45.0 // indirect + golang.org/x/tools v0.46.0 // indirect google.golang.org/api v0.272.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20260316180232-0b37fe3546d5 // indirect diff --git a/integrations/terraform/go.sum b/integrations/terraform/go.sum index e9e455af560..ef5edf6e38b 100644 --- a/integrations/terraform/go.sum +++ b/integrations/terraform/go.sum @@ -1648,8 +1648,8 @@ golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJk golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= -golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= +golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY= +golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1670,8 +1670,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1711,8 +1711,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1784,8 +1784,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6 h1:HjU6IWBiAgRIdAJ9/y1rwCn+UELEmwV+VsTLzj/W4sE= -golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6/go.mod h1:Eqhaxk/wZsWEH8CRxLwj6xzEJbz7k1EFGqx7nyCoabE= +golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9 h1:FjUup8XrRy7lv+XHONi6KKUSizeF2NnVrTnz/HhbohQ= +golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= @@ -1858,8 +1858,8 @@ golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= -golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= +golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/lib/mobile/verify/enroll/enroll.go b/lib/mobile/verify/enroll/enroll.go new file mode 100644 index 00000000000..777634346f1 --- /dev/null +++ b/lib/mobile/verify/enroll/enroll.go @@ -0,0 +1,118 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package enroll + +import ( + "context" + "log/slog" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "google.golang.org/protobuf/types/known/timestamppb" + + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + proxyinsecureclient "github.com/gravitational/teleport/lib/client/proxy/insecure" +) + +type Client struct { + proxyServer string + insecure bool +} + +// NewClient returns a Client configured to dial proxyServer. +// insecure must be false in release builds of the iOS app; it is intended +// only for development against local clusters. +func NewClient(proxyServer string, insecure bool) *Client { + return &Client{ + proxyServer: proxyServer, + insecure: insecure, + } +} + +// DeviceCollectedData mirrors the iOS-relevant subset of +// teleport.devicetrust.v1.DeviceCollectedData. The wrapper is required +// because gomobile only exports types from the bound package. +// +// Fields don't start with an acronym to dodge a gomobile bug +// (https://github.com/golang/go/issues/32008): VersionOS, not OSVersion. +type DeviceCollectedData struct { + SerialNumber string + ModelIdentifier string + VersionOS string + BuildOS string + SystemSerialNumber string +} + +// DeviceEnrollToken mirrors teleport.devicetrust.v1.DeviceEnrollToken. +// ExpireTime is dropped because gomobile doesn't support +// timestamppb.Timestamp. +type DeviceEnrollToken struct { + Token string +} + +// CreateMobileEnrollToken calls CreateMobileDeviceEnrollToken on the public +// Device Trust service. Populated fields of deviceData are forwarded as-is. +func (c *Client) CreateMobileEnrollToken(pairingToken string, deviceData *DeviceCollectedData) (*DeviceEnrollToken, error) { + // TODO(ravicious): Integrate Go's context with Swift's task cancellation + // See https://github.com/gravitational/teleport/pull/61278/changes/8980e91f611264bd760890316d49a842ded2aebb + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + grpcConn, err := proxyinsecureclient.NewConnection( + ctx, + proxyinsecureclient.ConnectionConfig{ + ProxyServer: c.proxyServer, + Clock: clockwork.NewRealClock(), + Insecure: c.insecure, + Log: slog.Default(), + }, + ) + if err != nil { + return nil, trace.Wrap(err) + } + defer grpcConn.Close() + + // TODO(ravicious): Replace this with a call to the public gRPC service. + client := devicepb.NewDeviceTrustServiceClient(grpcConn) + resp, err := client.CreateDeviceEnrollToken(ctx, + &devicepb.CreateDeviceEnrollTokenRequest{ + DeviceData: toPBDeviceData(deviceData), + }) + if err != nil { + return nil, trace.Wrap(err) + } + return &DeviceEnrollToken{ + Token: resp.GetToken(), + }, nil +} + +// toPBDeviceData translates DeviceCollectedData into the proto type. +// OsType stays UNSPECIFIED until OS_TYPE_IOS lands in +// teleport.devicetrust.v1.OSType (see RFD 32e). +func toPBDeviceData(d *DeviceCollectedData) *devicepb.DeviceCollectedData { + if d == nil { + d = &DeviceCollectedData{} + } + return &devicepb.DeviceCollectedData{ + CollectTime: timestamppb.Now(), + SerialNumber: d.SerialNumber, + ModelIdentifier: d.ModelIdentifier, + OsVersion: d.VersionOS, + OsBuild: d.BuildOS, + SystemSerialNumber: d.SystemSerialNumber, + } +} diff --git a/lib/utils/log/oslog/oslog_darwin.go b/lib/utils/log/oslog/oslog_darwin.go index 4e4f024b735..ad8dd5251ad 100644 --- a/lib/utils/log/oslog/oslog_darwin.go +++ b/lib/utils/log/oslog/oslog_darwin.go @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +//go:build darwin && !ios package oslog // #cgo CFLAGS: -Wall -xobjective-c -fblocks -fobjc-arc -mmacosx-version-min=11.0 diff --git a/lib/utils/log/slog_text_handler_darwin.go b/lib/utils/log/slog_text_handler_darwin.go index e030660001a..b98991d5f88 100644 --- a/lib/utils/log/slog_text_handler_darwin.go +++ b/lib/utils/log/slog_text_handler_darwin.go @@ -1,4 +1,4 @@ -//go:build darwin && cgo +//go:build darwin && cgo && !ios // Teleport // Copyright (C) 2025 Gravitational, Inc. diff --git a/lib/utils/log/slog_text_handler_other.go b/lib/utils/log/slog_text_handler_other.go index 7e6ac08ee0d..32bc56b66b3 100644 --- a/lib/utils/log/slog_text_handler_other.go +++ b/lib/utils/log/slog_text_handler_other.go @@ -1,4 +1,4 @@ -//go:build !(darwin && cgo) +//go:build !(darwin && cgo && !ios) // Teleport // Copyright (C) 2025 Gravitational, Inc. diff --git a/mobile/.gitignore b/mobile/.gitignore new file mode 100644 index 00000000000..a39fc3fbeea --- /dev/null +++ b/mobile/.gitignore @@ -0,0 +1,18 @@ +## User settings +xcuserdata + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +.build/ + +**/gen/*.xcframework/ diff --git a/mobile/Verify/Verify.xcodeproj/project.pbxproj b/mobile/Verify/Verify.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..c16b22f05e7 --- /dev/null +++ b/mobile/Verify/Verify.xcodeproj/project.pbxproj @@ -0,0 +1,407 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 0C94C8CE2FA35F3D00C13C9A /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C94C8CD2FA35ED900C13C9A /* libresolv.9.tbd */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 0C94C8CA2FA35ECB00C13C9A /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 0C94C8522FA232E600C13C9A /* Verify.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Verify.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0C94C8CD2FA35ED900C13C9A /* libresolv.9.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.9.tbd; path = usr/lib/libresolv.9.tbd; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 0C94C8612FA2365300C13C9A /* Exceptions for "Verify" folder in "Verify" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 0C94C8512FA232E600C13C9A /* Verify */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */ + 0C94C8CB2FA35ECC00C13C9A /* Exceptions for "Verify" folder in "Embed Frameworks" phase from "Verify" target */ = { + isa = PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet; + attributesByRelativePath = { + gen/Enroll.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, ); + }; + buildPhase = 0C94C8CA2FA35ECB00C13C9A /* Embed Frameworks */; + membershipExceptions = ( + gen/Enroll.xcframework, + ); + }; +/* End PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 0C94C8542FA232E600C13C9A /* Verify */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 0C94C8612FA2365300C13C9A /* Exceptions for "Verify" folder in "Verify" target */, + 0C94C8CB2FA35ECC00C13C9A /* Exceptions for "Verify" folder in "Embed Frameworks" phase from "Verify" target */, + ); + path = Verify; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 0C94C84F2FA232E600C13C9A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C94C8CE2FA35F3D00C13C9A /* libresolv.9.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0C94C8492FA232E600C13C9A = { + isa = PBXGroup; + children = ( + 0C94C8542FA232E600C13C9A /* Verify */, + 0C94C8CC2FA35ED900C13C9A /* Frameworks */, + 0C94C8532FA232E600C13C9A /* Products */, + ); + sourceTree = ""; + }; + 0C94C8532FA232E600C13C9A /* Products */ = { + isa = PBXGroup; + children = ( + 0C94C8522FA232E600C13C9A /* Verify.app */, + ); + name = Products; + sourceTree = ""; + }; + 0C94C8CC2FA35ED900C13C9A /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0C94C8CD2FA35ED900C13C9A /* libresolv.9.tbd */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 0C94C8512FA232E600C13C9A /* Verify */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0C94C85D2FA232E700C13C9A /* Build configuration list for PBXNativeTarget "Verify" */; + buildPhases = ( + 0C94C84E2FA232E600C13C9A /* Sources */, + 0C94C84F2FA232E600C13C9A /* Frameworks */, + 0C94C8502FA232E600C13C9A /* Resources */, + 0C94C8CA2FA35ECB00C13C9A /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 0C94C8542FA232E600C13C9A /* Verify */, + ); + name = Verify; + packageProductDependencies = ( + ); + productName = Verify; + productReference = 0C94C8522FA232E600C13C9A /* Verify.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0C94C84A2FA232E600C13C9A /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2640; + LastUpgradeCheck = 2640; + TargetAttributes = { + 0C94C8512FA232E600C13C9A = { + CreatedOnToolsVersion = 26.4.1; + }; + }; + }; + buildConfigurationList = 0C94C84D2FA232E600C13C9A /* Build configuration list for PBXProject "Verify" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 0C94C8492FA232E600C13C9A; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 0C94C8532FA232E600C13C9A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 0C94C8512FA232E600C13C9A /* Verify */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 0C94C8502FA232E600C13C9A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 0C94C84E2FA232E600C13C9A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 0C94C85B2FA232E700C13C9A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = K497G57PDJ; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.4; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 6.0; + }; + name = Debug; + }; + 0C94C85C2FA232E700C13C9A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = K497G57PDJ; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.4; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_VERSION = 6.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 0C94C85E2FA232E700C13C9A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = K497G57PDJ; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Verify/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Teleport Verify"; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gravitational.Verify; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 0C94C85F2FA232E700C13C9A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = K497G57PDJ; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Verify/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Teleport Verify"; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gravitational.Verify; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0C94C84D2FA232E600C13C9A /* Build configuration list for PBXProject "Verify" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0C94C85B2FA232E700C13C9A /* Debug */, + 0C94C85C2FA232E700C13C9A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0C94C85D2FA232E700C13C9A /* Build configuration list for PBXNativeTarget "Verify" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0C94C85E2FA232E700C13C9A /* Debug */, + 0C94C85F2FA232E700C13C9A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0C94C84A2FA232E600C13C9A /* Project object */; +} diff --git a/mobile/Verify/Verify.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/mobile/Verify/Verify.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..919434a6254 --- /dev/null +++ b/mobile/Verify/Verify.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/mobile/Verify/Verify/Assets.xcassets/AccentColor.colorset/Contents.json b/mobile/Verify/Verify/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000000..eb878970081 --- /dev/null +++ b/mobile/Verify/Verify/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/mobile/Verify/Verify/Assets.xcassets/AppIcon.appiconset/Contents.json b/mobile/Verify/Verify/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..2305880107d --- /dev/null +++ b/mobile/Verify/Verify/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/mobile/Verify/Verify/Assets.xcassets/Contents.json b/mobile/Verify/Verify/Assets.xcassets/Contents.json new file mode 100644 index 00000000000..73c00596a7f --- /dev/null +++ b/mobile/Verify/Verify/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/mobile/Verify/Verify/Assets.xcassets/logo.imageset/Contents.json b/mobile/Verify/Verify/Assets.xcassets/logo.imageset/Contents.json new file mode 100644 index 00000000000..a07d4059250 --- /dev/null +++ b/mobile/Verify/Verify/Assets.xcassets/logo.imageset/Contents.json @@ -0,0 +1,82 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "filename" : "enterprise-light.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "enterprise-dark.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-dark.svg b/mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-dark.svg new file mode 100644 index 00000000000..d23f3f13f65 --- /dev/null +++ b/mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-light.svg b/mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-light.svg new file mode 100644 index 00000000000..feb4d5ebe1b --- /dev/null +++ b/mobile/Verify/Verify/Assets.xcassets/logo.imageset/enterprise-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile/Verify/Verify/ContentView.swift b/mobile/Verify/Verify/ContentView.swift new file mode 100644 index 00000000000..0dc420600a9 --- /dev/null +++ b/mobile/Verify/Verify/ContentView.swift @@ -0,0 +1,102 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import SwiftUI +import os + +private let logger = Logger( + subsystem: Bundle.main.bundleIdentifier ?? "com.gravitational.verify", + category: String(describing: ContentView.self) +) + +enum AppScreen { + case landing + case enroll(EnrollMobileDeviceDeepURL) +} + +struct ContentView: View { + @State private var screen: AppScreen + @State private var parseError: DeepLinkParseError? + + init(initialScreen: AppScreen = .landing) { + _screen = State(initialValue: initialScreen) + } + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + Image("logo") + .resizable() + .scaledToFit() + .frame(height: 32) + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color(.systemBackground)) + Group { + switch screen { + case .landing: + LandingView() + case .enroll(let deepURL): + EnrollMobileDeviceView( + deepURL: deepURL, + onCancel: { screen = .landing } + ) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + .onOpenURL { url in + let result = parseDeepLink(url) + logger + .debug( + "Got URL: \(url, privacy: .public), parsed: \(String(describing: result), privacy: .public)" + ) + switch result { + case .success(.enrollMobileDevice(let deepURL)): + parseError = nil + screen = .enroll(deepURL) + case .failure(let error): + parseError = error + } + } + .alert( + "Cannot open the link", + isPresented: Binding( + get: { parseError != nil }, + set: { if !$0 { parseError = nil } } + ), + presenting: parseError + ) { _ in + Button("Dismiss", role: .cancel) {} + } message: { error in + switch error { + case .unsupportedPath: + Text( + "This version of the app does not support the action represented by this link." + ) + case .urlComponentsFailed: + Text( + "The link appears to be malformed and could not be parsed." + ) + case .missingPart(let part): + Text("The \(part) part of the link is missing.") + } + } + } +} + +#Preview { + ContentView() +} diff --git a/mobile/Verify/Verify/DeepLink.swift b/mobile/Verify/Verify/DeepLink.swift new file mode 100644 index 00000000000..06a31bec0b6 --- /dev/null +++ b/mobile/Verify/Verify/DeepLink.swift @@ -0,0 +1,103 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import Foundation +import os + +private let logger = Logger( + subsystem: Bundle.main.bundleIdentifier ?? "com.gravitational.verify", + category: "deep_link" +) + +func parseDeepLink(_ url: URL) -> DeepLinkParseResult { + let path = url.path(percentEncoded: false) + switch path { + case "/enroll_mobile_device": + // Make sure to first switch on the path and only then attempt to parse out individual fields + // out of the URL. This way this function always returns the most important error first, + // which is the error about the unsupported path. + return parseDeepURL(url) { deepURL, parts in + guard + let enrollPairingToken = getQueryParam( + parts, + "enroll_pairing_token" + ) + else { + return .failure(.missingPart("enroll pairing token")) + } + return .success( + .enrollMobileDevice( + EnrollMobileDeviceDeepURL( + url: deepURL, + enrollPairingToken: enrollPairingToken + ) + ) + ) + } + default: + logger.warning("Unsupported path: \(path, privacy: .public)") + return .failure(.unsupportedPath) + } +} + +typealias DeepLinkParseResult = Result + +enum ParsedDeepLink { + case enrollMobileDevice(EnrollMobileDeviceDeepURL) +} + +enum DeepLinkParseError: Error { + case unsupportedPath + case urlComponentsFailed + case missingPart(String) +} + +struct DeepURL { + /// hostname is just the name of the host without the port. + var hostname: String + /// port of the host. + var port: Int? +} + +struct EnrollMobileDeviceDeepURL { + var url: DeepURL + /// user_token query params from the deep link. + var enrollPairingToken: String +} + +/// parseDeepURL could return Result<(DeepURL, URLComponents), DeepLinkParseError> instead, but +/// there's no convienient way to unwrap it, that's why it accepts a trailing closure instead. +func parseDeepURL( + _ url: URL, + toParsedDeepLink: (_ deepURL: DeepURL, _ parts: URLComponents) -> + DeepLinkParseResult +) -> DeepLinkParseResult { + guard let parts = URLComponents(string: url.absoluteString) else { + return .failure(.urlComponentsFailed) + } + guard let hostname = parts.host, hostname != "" else { + return .failure(.missingPart("hostname")) + } + let port = parts.port + + return toParsedDeepLink(DeepURL(hostname: hostname, port: port), parts) +} + +func getQueryParam(_ parts: URLComponents, _ param: String) -> String? { + parts.queryItems? + .first(where: { $0.name == param && $0.value != nil && $0.value != "" } + )?.value +} diff --git a/mobile/Verify/Verify/EnrollMobileDeviceView.swift b/mobile/Verify/Verify/EnrollMobileDeviceView.swift new file mode 100644 index 00000000000..95017de3fdf --- /dev/null +++ b/mobile/Verify/Verify/EnrollMobileDeviceView.swift @@ -0,0 +1,126 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import SwiftUI + +struct EnrollMobileDeviceView: View { + let deepURL: EnrollMobileDeviceDeepURL + let onCancel: () -> Void + @State private var viewModel: EnrollMobileDeviceViewModel + + init(deepURL: EnrollMobileDeviceDeepURL, onCancel: @escaping () -> Void) { + self.deepURL = deepURL + self.onCancel = onCancel + _viewModel = State( + initialValue: EnrollMobileDeviceViewModel(deepURL: deepURL) + ) + } + + var body: some View { + VStack(spacing: 16) { + Spacer() + Image(systemName: "ipad.and.iphone") + .font(.system(size: 37)) + .foregroundStyle(.primary) + .frame(width: 75, height: 75) + .background( + RoundedRectangle(cornerRadius: 16) + .fill(Color(.systemBackground)) + ) + .overlay( + RoundedRectangle(cornerRadius: 16) + .strokeBorder(Color(.separator), lineWidth: 1) + ) + VStack(spacing: 8) { + Text("Enroll Your Device") + .font(.title2) + .fontWeight(.semibold) + Text( + "To finish enrolling this device, approve the request from your account settings on another device." + ) + .multilineTextAlignment(.center) + .foregroundStyle(.secondary) + } + Spacer() + VStack(spacing: 16) { + Button { + Task { await viewModel.requestEnrollToken() } + } label: { + Group { + if viewModel.attempt.isLoading { + Label( + "Request in progress", + systemImage: "progress.indicator" + ) + .labelStyle(.iconOnly) + .symbolEffect( + .variableColor.iterative, + options: .repeat(.continuous), + isActive: true + ) + } else { + Text("Request Now") + } + } + .frame(maxWidth: .infinity) + } + .buttonStyle(.borderedProminent) + .controlSize(.large) + .animation(.easeInOut, value: viewModel.attempt.isLoading) + .disabled(viewModel.attempt.isLoading) + + Button(role: .cancel, action: onCancel) { + Text("Cancel").frame(maxWidth: .infinity) + } + .buttonStyle(.bordered) + .controlSize(.large) + .disabled(viewModel.attempt.isLoading) + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(.systemGroupedBackground)) + .sheet( + isPresented: Binding( + get: { + switch viewModel.attempt { + case .idle: false + default: true + } + }, + set: { if !$0 { viewModel.attempt = .idle } } + ) + ) { + EnrollRequestStatusView( + attempt: viewModel.attempt, + onDismiss: { viewModel.attempt = .idle } + ) + .presentationDetents([.medium]) + .interactiveDismissDisabled(viewModel.attempt.isLoading) + } + } +} + +#Preview("In ContentView") { + ContentView( + initialScreen: .enroll( + EnrollMobileDeviceDeepURL( + url: DeepURL(hostname: "example.com", port: 3080), + enrollPairingToken: "abc123" + ) + ) + ) +} diff --git a/mobile/Verify/Verify/EnrollMobileDeviceViewModel.swift b/mobile/Verify/Verify/EnrollMobileDeviceViewModel.swift new file mode 100644 index 00000000000..4918aed02a7 --- /dev/null +++ b/mobile/Verify/Verify/EnrollMobileDeviceViewModel.swift @@ -0,0 +1,68 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import Enroll +import Observation + +@Observable +@MainActor +class EnrollMobileDeviceViewModel { + enum Attempt { + case idle + case loading + case success(token: String) + case failure(Error) + + var isLoading: Bool { + if case .loading = self { return true } + return false + } + } + + var attempt: Attempt = .idle + private let deepURL: EnrollMobileDeviceDeepURL + + init(deepURL: EnrollMobileDeviceDeepURL) { + self.deepURL = deepURL + } + + func requestEnrollToken() async { + attempt = .loading + let proxyServer = "\(deepURL.url.hostname):\(deepURL.url.port ?? 443)" + let pairingToken = deepURL.enrollPairingToken + + let outcome: Attempt = await Task.detached(priority: .userInitiated) { + guard let client = EnrollClient(proxyServer, insecure: false) else { + return .failure(EnrollViewModelError.clientCreationFailed) + } + do { + let token = try client.createMobileEnrollToken( + pairingToken, + deviceData: EnrollDeviceCollectedData() + ) + return .success(token: token.token) + } catch { + return .failure(error) + } + }.value + + attempt = outcome + } +} + +enum EnrollViewModelError: Error { + case clientCreationFailed +} diff --git a/mobile/Verify/Verify/EnrollRequestStatusView.swift b/mobile/Verify/Verify/EnrollRequestStatusView.swift new file mode 100644 index 00000000000..6c49c5dfc5d --- /dev/null +++ b/mobile/Verify/Verify/EnrollRequestStatusView.swift @@ -0,0 +1,115 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import SwiftUI + +struct EnrollRequestStatusView: View { + let attempt: EnrollMobileDeviceViewModel.Attempt + let onDismiss: () -> Void + + var body: some View { + VStack(spacing: 24) { + Spacer() + Image(systemName: iconName) + .font(.system(size: 60)) + .foregroundStyle(.primary) + .contentTransition(.symbolEffect(.replace)) + VStack(spacing: 8) { + Text(title) + .font(.title2) + .fontWeight(.semibold) + .contentTransition(.opacity) + Text(message) + .multilineTextAlignment(.center) + .foregroundStyle(.secondary) + .contentTransition(.opacity) + } + Spacer() + switch attempt { + case .success: + Button { + // TODO: Navigate to the cluster. + } label: { + HStack { + Text("Go to Cluster") + Image(systemName: "arrow.right") + } + .frame(maxWidth: .infinity) + } + .buttonStyle(.borderedProminent) + .controlSize(.large) + case .failure: + Button("Dismiss", action: onDismiss) + .buttonStyle(.bordered) + .controlSize(.large) + .frame(maxWidth: .infinity) + case .idle, .loading: + EmptyView() + } + } + .padding() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .animation(.default, value: iconName) + } + + private var iconName: String { + switch attempt { + case .idle, .loading: "clock" + case .success: "checkmark.circle" + case .failure: "exclamationmark.triangle" + } + } + + private var title: String { + switch attempt { + case .idle, .loading: "Request Sent" + case .success: "Request Approved" + case .failure: "Request Failed" + } + } + + private var message: String { + switch attempt { + case .idle, .loading: + "Your enrollment request has been sent. Approve it from the Web UI to continue." + case .success: + "This device is now trusted and can access protected resources." + case .failure(let error): + error.localizedDescription + } + } +} + +#Preview("Request Sent") { + EnrollRequestStatusView(attempt: .loading, onDismiss: {}) +} + +#Preview("Request Approved") { + EnrollRequestStatusView( + attempt: .success(token: "demo-placeholder-token"), + onDismiss: {} + ) +} + +#Preview("Request Failed") { + struct DemoError: LocalizedError { + var errorDescription: String? { "Network unreachable" } + } + return EnrollRequestStatusView( + attempt: .failure(DemoError()), + onDismiss: {} + ) +} diff --git a/mobile/Verify/Verify/Info.plist b/mobile/Verify/Verify/Info.plist new file mode 100644 index 00000000000..fa817fb9227 --- /dev/null +++ b/mobile/Verify/Verify/Info.plist @@ -0,0 +1,19 @@ + + + + + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + com.gravitational.Verify + CFBundleURLSchemes + + teleport + + + + + diff --git a/mobile/Verify/Verify/LandingView.swift b/mobile/Verify/Verify/LandingView.swift new file mode 100644 index 00000000000..a970474c956 --- /dev/null +++ b/mobile/Verify/Verify/LandingView.swift @@ -0,0 +1,30 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import SwiftUI + +struct LandingView: View { + var body: some View { + Text("Open the Camera app\nto scan a QR code in the Web UI.") + .multilineTextAlignment(.center) + .frame(maxWidth: .infinity) + .padding() + } +} + +#Preview("In ContentView") { + ContentView() +} diff --git a/mobile/Verify/Verify/VerifyApp.swift b/mobile/Verify/Verify/VerifyApp.swift new file mode 100644 index 00000000000..81b77decacd --- /dev/null +++ b/mobile/Verify/Verify/VerifyApp.swift @@ -0,0 +1,33 @@ +// Teleport +// Copyright (C) 2026 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// +// VerifyApp.swift +// Verify +// +// Created by Maja Cieślak on 2026-04-29. +// + +import SwiftUI + +@main +struct VerifyApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +}