Skip to content

Commit 2e790c6

Browse files
fix(session-replay): Add redaction for SFSafariView (#5408)
1 parent 8df2e0d commit 2e790c6

File tree

8 files changed

+208
-59
lines changed

8 files changed

+208
-59
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- Fix usage of `@available` to be `iOS` instead of `iOSApplicationExtension` (#5361)
1414
- Move SentryExperimentalOptions to a property defined in Swift (#5329)
1515
- Fix building with Xcode 26 (#5386)
16+
- Add redaction in session replay for `SFSafariView` used by `SFSafariViewController` and `ASWebAuthenticationSession` (#5408)
1617

1718
## 8.52.1
1819

Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard

Lines changed: 47 additions & 19 deletions
Large diffs are not rendered by default.

Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
// swiftlint:disable file_length
2+
import AuthenticationServices
13
import Foundation
4+
import SafariServices
25
import Sentry
36
import SentrySampleShared
47
import UIKit
@@ -138,6 +141,31 @@ class ExtraViewController: UIViewController {
138141
navigationController?.pushViewController(WebViewController(), animated: true)
139142
}
140143

144+
@IBAction func openSafariWebView(_ sender: UIButton) {
145+
guard let url = URL(string: "https://docs.sentry.io/platforms/apple/guides/ios/") else {
146+
fatalError("The hard-coded URL is invalid.")
147+
}
148+
let safariVC = SFSafariViewController(url: url)
149+
safariVC.modalPresentationStyle = .pageSheet
150+
self.present(safariVC, animated: true)
151+
}
152+
153+
@available(iOS 13.0, *)
154+
@IBAction func openAuthenticationServicesWebView(_ sender: UIButton) {
155+
let url = URL(string: "https://sentry.io/auth/login/")!
156+
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: "sentry-callback") { url, error in
157+
if let error = error {
158+
print("[iOS-Swift] ASWebAuthenticationSession failed with error: \(error.localizedDescription)")
159+
} else if let url = url {
160+
print("[iOS-Swift] ASWebAuthenticationSession completed with URL: \(url)")
161+
} else {
162+
print("[iOS-Swift] ASWebAuthenticationSession completed without URL or error.")
163+
}
164+
}
165+
session.presentationContextProvider = self
166+
session.start()
167+
}
168+
141169
@IBAction func captureUserFeedbackV2(_ sender: UIButton) {
142170
highlightButton(sender)
143171
var attachments: [Data]?
@@ -359,3 +387,14 @@ class ExtraViewController: UIViewController {
359387
}
360388
}
361389
}
390+
391+
@available(iOS 13.0, *)
392+
extension ExtraViewController: ASWebAuthenticationPresentationContextProviding {
393+
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
394+
guard let window = view.window else {
395+
fatalError("No window available for ASAuthorizationControllerPresentationContextProviding.")
396+
}
397+
return window
398+
}
399+
}
400+
// swiftlint:enable file_length

Sentry.xcodeproj/project.pbxproj

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,7 @@
842842
D456B4322D706BDF007068CB /* SentrySpanOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = D456B4312D706BDD007068CB /* SentrySpanOperation.h */; };
843843
D456B4362D706BF2007068CB /* SentryTraceOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = D456B4352D706BEE007068CB /* SentryTraceOrigin.h */; };
844844
D456B4382D706BFE007068CB /* SentrySpanDataKey.h in Headers */ = {isa = PBXBuildFile; fileRef = D456B4372D706BFB007068CB /* SentrySpanDataKey.h */; };
845+
D45E2D772E003EBF0072A6B7 /* TestRedactOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D45E2D762E003EBF0072A6B7 /* TestRedactOptions.swift */; };
845846
D467125E2DCCFF2500D4074A /* SentryReplayOptionsObjcTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D467125D2DCCFF2500D4074A /* SentryReplayOptionsObjcTests.m */; };
846847
D46712622DCD059900D4074A /* SentryRedactDefaultOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46712612DCD059500D4074A /* SentryRedactDefaultOptionsTests.swift */; };
847848
D46712642DCD063800D4074A /* PreviewRedactOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46712632DCD062700D4074A /* PreviewRedactOptionsTests.swift */; };
@@ -1006,7 +1007,7 @@
10061007
D8DBE0CA2C0E093000FAB1FD /* SentryTouchTrackerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DBE0C92C0E093000FAB1FD /* SentryTouchTrackerTests.swift */; };
10071008
D8DBE0D22C0EFFC300FAB1FD /* SentryReplayOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DBE0D12C0EFFC300FAB1FD /* SentryReplayOptionsTests.swift */; };
10081009
D8F67AF12BE0D33F00C9197B /* UIImageHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F67AEF2BE0D31A00C9197B /* UIImageHelperTests.swift */; };
1009-
D8F67AF42BE10F9600C9197B /* UIRedactBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F67AF22BE10F7600C9197B /* UIRedactBuilderTests.swift */; };
1010+
D8F67AF42BE10F9600C9197B /* SentryUIRedactBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F67AF22BE10F7600C9197B /* SentryUIRedactBuilderTests.swift */; };
10101011
D8F67B1B2BE9728600C9197B /* SentrySRDefaultBreadcrumbConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F67B1A2BE9728600C9197B /* SentrySRDefaultBreadcrumbConverter.swift */; };
10111012
D8F67B222BEAB6CC00C9197B /* SentryRRWebEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F67B212BEAB6CC00C9197B /* SentryRRWebEvent.swift */; };
10121013
D8F6A2472885512100320515 /* SentryPredicateDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F6A2452885512100320515 /* SentryPredicateDescriptor.m */; };
@@ -2068,6 +2069,7 @@
20682069
D456B4312D706BDD007068CB /* SentrySpanOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySpanOperation.h; path = include/SentrySpanOperation.h; sourceTree = "<group>"; };
20692070
D456B4352D706BEE007068CB /* SentryTraceOrigin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryTraceOrigin.h; path = include/SentryTraceOrigin.h; sourceTree = "<group>"; };
20702071
D456B4372D706BFB007068CB /* SentrySpanDataKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySpanDataKey.h; path = include/SentrySpanDataKey.h; sourceTree = "<group>"; };
2072+
D45E2D762E003EBF0072A6B7 /* TestRedactOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestRedactOptions.swift; sourceTree = "<group>"; };
20712073
D467125D2DCCFF2500D4074A /* SentryReplayOptionsObjcTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryReplayOptionsObjcTests.m; sourceTree = "<group>"; };
20722074
D46712612DCD059500D4074A /* SentryRedactDefaultOptionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryRedactDefaultOptionsTests.swift; sourceTree = "<group>"; };
20732075
D46712632DCD062700D4074A /* PreviewRedactOptionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewRedactOptionsTests.swift; sourceTree = "<group>"; };
@@ -2252,7 +2254,7 @@
22522254
D8F01DE42A126B62008F4996 /* HybridPod.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = HybridPod.podspec; sourceTree = "<group>"; };
22532255
D8F01DE52A126BF5008F4996 /* HybridTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HybridTest.swift; sourceTree = "<group>"; };
22542256
D8F67AEF2BE0D31A00C9197B /* UIImageHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageHelperTests.swift; sourceTree = "<group>"; };
2255-
D8F67AF22BE10F7600C9197B /* UIRedactBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIRedactBuilderTests.swift; sourceTree = "<group>"; };
2257+
D8F67AF22BE10F7600C9197B /* SentryUIRedactBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUIRedactBuilderTests.swift; sourceTree = "<group>"; };
22562258
D8F67B1A2BE9728600C9197B /* SentrySRDefaultBreadcrumbConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySRDefaultBreadcrumbConverter.swift; sourceTree = "<group>"; };
22572259
D8F67B212BEAB6CC00C9197B /* SentryRRWebEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryRRWebEvent.swift; sourceTree = "<group>"; };
22582260
D8F6A2452885512100320515 /* SentryPredicateDescriptor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryPredicateDescriptor.m; sourceTree = "<group>"; };
@@ -3983,7 +3985,8 @@
39833985
isa = PBXGroup;
39843986
children = (
39853987
D82915622C85EF0C00A6CDD4 /* SentryViewPhotographerTests.swift */,
3986-
D8F67AF22BE10F7600C9197B /* UIRedactBuilderTests.swift */,
3988+
D8F67AF22BE10F7600C9197B /* SentryUIRedactBuilderTests.swift */,
3989+
D45E2D762E003EBF0072A6B7 /* TestRedactOptions.swift */,
39873990
);
39883991
path = ViewCapture;
39893992
sourceTree = "<group>";
@@ -5617,7 +5620,7 @@
56175620
7BF9EF742722A85B00B5BBEF /* SentryClassRegistrator.m in Sources */,
56185621
D82915632C85EF0C00A6CDD4 /* SentryViewPhotographerTests.swift in Sources */,
56195622
D8DBE0CA2C0E093000FAB1FD /* SentryTouchTrackerTests.swift in Sources */,
5620-
D8F67AF42BE10F9600C9197B /* UIRedactBuilderTests.swift in Sources */,
5623+
D8F67AF42BE10F9600C9197B /* SentryUIRedactBuilderTests.swift in Sources */,
56215624
63B819141EC352A7002FDF4C /* SentryInterfacesTests.m in Sources */,
56225625
62F05D2B2C0DB1F100916E3F /* SentryLogTestHelper.m in Sources */,
56235626
7B68345128F7EB3D00FB7064 /* SentryMeasurementUnitTests.swift in Sources */,
@@ -5682,6 +5685,7 @@
56825685
0ADC33F128D9BE940078D980 /* TestSentryUIDeviceWrapper.swift in Sources */,
56835686
63FE721420DA66EC00CDBAE8 /* SentryCrashMemory_Tests.m in Sources */,
56845687
62885DA729E946B100554F38 /* TestConncurrentModifications.swift in Sources */,
5688+
D45E2D772E003EBF0072A6B7 /* TestRedactOptions.swift in Sources */,
56855689
63FE720520DA66EC00CDBAE8 /* FileBasedTestCase.m in Sources */,
56865690
51B15F802BE88D510026A2F2 /* URLSessionTaskHelperTests.swift in Sources */,
56875691
63EED6C32237989300E02400 /* SentryOptionsTest.m in Sources */,

Sources/Swift/Core/Tools/ViewCapture/SentryUIRedactBuilder.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,14 @@ class SentryUIRedactBuilder {
5959
#if os(iOS)
6060
redactClasses += [ WKWebView.self ]
6161

62-
//If we try to use 'UIWebView.self' it will not compile for macCatalyst, but the class does exists.
63-
redactClasses += [ "UIWebView" ].compactMap(NSClassFromString(_:))
62+
redactClasses += [
63+
// If we try to use 'UIWebView.self' it will not compile for macCatalyst, but the class does exists.
64+
"UIWebView",
65+
// Used by:
66+
// - https://developer.apple.com/documentation/SafariServices/SFSafariViewController
67+
// - https://developer.apple.com/documentation/AuthenticationServices/ASWebAuthenticationSession
68+
"SFSafariView"
69+
].compactMap(NSClassFromString(_:))
6470

6571
ignoreClassesIdentifiers = [ ObjectIdentifier(UISlider.self), ObjectIdentifier(UISwitch.self) ]
6672
#else
@@ -225,7 +231,7 @@ class SentryUIRedactBuilder {
225231
transform: newTransform,
226232
type: swiftUI ? .redactSwiftUI : .redact,
227233
color: self.color(for: view),
228-
name: layer.debugDescription
234+
name: layer.name ?? layer.debugDescription
229235
))
230236

231237
guard !view.clipsToBounds else {
@@ -242,7 +248,7 @@ class SentryUIRedactBuilder {
242248
size: layer.bounds.size,
243249
transform: newTransform,
244250
type: .clipOut,
245-
name: layer.debugDescription
251+
name: layer.name ?? layer.debugDescription
246252
))
247253
}
248254
}
@@ -258,7 +264,7 @@ class SentryUIRedactBuilder {
258264
size: layer.bounds.size,
259265
transform: newTransform,
260266
type: .clipEnd,
261-
name: layer.debugDescription
267+
name: layer.name ?? layer.debugDescription
262268
))
263269
}
264270
for subLayer in subLayers.sorted(by: { $0.zPosition < $1.zPosition }) {
@@ -269,7 +275,7 @@ class SentryUIRedactBuilder {
269275
size: layer.bounds.size,
270276
transform: newTransform,
271277
type: .clipBegin,
272-
name: layer.debugDescription
278+
name: layer.name ?? layer.debugDescription
273279
))
274280
}
275281
}

0 commit comments

Comments
 (0)