From 7091e276f8d721de1632f07071114f311eb9b672 Mon Sep 17 00:00:00 2001 From: Leslie Helou Date: Sat, 7 Feb 2026 20:57:08 -0500 Subject: [PATCH 1/5] removeObjects logging --- Replicator/Info.plist | 2 +- Replicator/RemoveObjects.swift | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Replicator/Info.plist b/Replicator/Info.plist index a9a8803..c841f38 100644 --- a/Replicator/Info.plist +++ b/Replicator/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 20260122-5EC + 20260208-7E LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/Replicator/RemoveObjects.swift b/Replicator/RemoveObjects.swift index d8260e7..41b8368 100644 --- a/Replicator/RemoveObjects.swift +++ b/Replicator/RemoveObjects.swift @@ -233,6 +233,7 @@ class RemoveObjects: NSObject, URLSessionDelegate { defer { semaphore.signal() } session.finishTasksAndInvalidate() if let httpResponse = response as? HTTPURLResponse { + if LogLevel.debug { WriteToLog.shared.message("[RemoveObjects.process] response statusCode: \(httpResponse.statusCode)") } if let _ = String(data: data!, encoding: .utf8) { responseData = String(data: data!, encoding: .utf8)! } else { From 79d020dc532212b048018bf944e282ca47d8061f Mon Sep 17 00:00:00 2001 From: Leslie Helou Date: Sun, 10 May 2026 10:42:58 -0400 Subject: [PATCH 2/5] address crash on sites/linited perms/policies with dependencies --- ChangeLog.md | 2 +- README.md | 2 +- Replicator/EndpointData.swift | 6 +++++- Replicator/Info.plist | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 094bdee..4788d8a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -13,7 +13,7 @@ To opt out of data the sending of data click 'Opt out of analytics' at the botto **v8.5.1**: 2026-01-04
Address issue removing jamf users/groups. -Starting with version 8.5.1 the application will submit basic hardware, OS, and Replicator application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anamously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the 'About Replicator' window. +Starting with version 8.5.1 the application will submit basic hardware, OS, and Replicator application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anonymously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the 'About Replicator' window. **v8.4.1**: 2025-11-06
Address issue #128 - app is now notarized. diff --git a/README.md b/README.md index 6ed27fc..7d451f1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ A tool to synchronize objects between Jamf Pro servers. Export objects and save ![image](./Replicator/images/replicator1.png "Replicator") -By default the application will submit basic hardware, OS, and jamfCPR application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anamously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the Settings --> app window. +By default the application will submit basic hardware, OS, and jamfCPR application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anonymously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the Settings --> app window. Replicate items from one Jamf server, or XML file(s), to another. If an object (based on name) exists on both source and destination, the destination object will be updated with values from the source server.

diff --git a/Replicator/EndpointData.swift b/Replicator/EndpointData.swift index c0b5683..85ffd70 100644 --- a/Replicator/EndpointData.swift +++ b/Replicator/EndpointData.swift @@ -319,7 +319,11 @@ class EndpointData: NSObject, URLSessionDelegate { if LogLevel.debug { WriteToLog.shared.message("[getById] Returned from cleanupXml") } } // check progress - Endpoints.countDict[endpoint]! -= 1 + if let _ = Endpoints.countDict[endpoint] { + Endpoints.countDict[endpoint]! -= 1 + } else { + Endpoints.countDict[endpoint] = 0 + } if Endpoints.countDict[endpoint] == 0 { Endpoints.countDict[endpoint] = nil diff --git a/Replicator/Info.plist b/Replicator/Info.plist index c841f38..e53da08 100644 --- a/Replicator/Info.plist +++ b/Replicator/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 20260208-7E + 20260510-59B LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion From 483bd5f0d2f0be8a840416b85119f290a7ea1023 Mon Sep 17 00:00:00 2001 From: Leslie Helou Date: Mon, 11 May 2026 10:33:17 -0400 Subject: [PATCH 3/5] version bump --- Replicator.xcodeproj/project.pbxproj | 4 ++-- Replicator/Info.plist | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Replicator.xcodeproj/project.pbxproj b/Replicator.xcodeproj/project.pbxproj index 88d9eb5..0211705 100755 --- a/Replicator.xcodeproj/project.pbxproj +++ b/Replicator.xcodeproj/project.pbxproj @@ -596,7 +596,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = 8.6.0; + MARKETING_VERSION = "8.6.1-b1"; PRODUCT_BUNDLE_IDENTIFIER = "com.jamf.jamf-migrator"; PRODUCT_NAME = Replicator; SWIFT_SWIFT3_OBJC_INFERENCE = Default; @@ -625,7 +625,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = 8.6.0; + MARKETING_VERSION = "8.6.1-b1"; PRODUCT_BUNDLE_IDENTIFIER = "com.jamf.jamf-migrator"; PRODUCT_NAME = Replicator; SWIFT_SWIFT3_OBJC_INFERENCE = Default; diff --git a/Replicator/Info.plist b/Replicator/Info.plist index e53da08..a2a71e8 100644 --- a/Replicator/Info.plist +++ b/Replicator/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 20260510-59B + 20260510-5A4 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion From fe8fcede9981b3e2af43a48b312586f22468bf1d Mon Sep 17 00:00:00 2001 From: Leslie Helou Date: Wed, 9 Sep 2026 18:42:22 -0400 Subject: [PATCH 4/5] allow untrusted certs --- Replicator.xcodeproj/project.pbxproj | 4 ++-- Replicator/CreateEndpoints.swift | 4 ++++ Replicator/EndpointData.swift | 4 ++++ Replicator/EndpointXml.swift | 4 ++++ Replicator/ExistingObjects.swift | 4 ++++ Replicator/IconDelegate.swift | 5 ++++- Replicator/Info.plist | 2 +- Replicator/Json.swift | 4 ++++ Replicator/ObjectDelegate.swift | 4 ++++ Replicator/PackagesDelegate.swift | 4 ++++ Replicator/RemoveObjects.swift | 4 ++++ 11 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Replicator.xcodeproj/project.pbxproj b/Replicator.xcodeproj/project.pbxproj index 0211705..f15728b 100755 --- a/Replicator.xcodeproj/project.pbxproj +++ b/Replicator.xcodeproj/project.pbxproj @@ -596,7 +596,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = "8.6.1-b1"; + MARKETING_VERSION = "8.6.1-gio"; PRODUCT_BUNDLE_IDENTIFIER = "com.jamf.jamf-migrator"; PRODUCT_NAME = Replicator; SWIFT_SWIFT3_OBJC_INFERENCE = Default; @@ -625,7 +625,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = "8.6.1-b1"; + MARKETING_VERSION = "8.6.1-gio"; PRODUCT_BUNDLE_IDENTIFIER = "com.jamf.jamf-migrator"; PRODUCT_NAME = Replicator; SWIFT_SWIFT3_OBJC_INFERENCE = Default; diff --git a/Replicator/CreateEndpoints.swift b/Replicator/CreateEndpoints.swift index 9b80fe9..0cf2817 100644 --- a/Replicator/CreateEndpoints.swift +++ b/Replicator/CreateEndpoints.swift @@ -977,4 +977,8 @@ class CreateEndpoints: NSObject, URLSessionDelegate { } // if !WipeData.state.on - end } // SendQueue - end } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/EndpointData.swift b/Replicator/EndpointData.swift index 85ffd70..508b854 100644 --- a/Replicator/EndpointData.swift +++ b/Replicator/EndpointData.swift @@ -368,5 +368,9 @@ class EndpointData: NSObject, URLSessionDelegate { } } } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/EndpointXml.swift b/Replicator/EndpointXml.swift index 24079f8..91bfa14 100644 --- a/Replicator/EndpointXml.swift +++ b/Replicator/EndpointXml.swift @@ -363,5 +363,9 @@ class EndpointXml: NSObject, URLSessionDelegate { } } } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/ExistingObjects.swift b/Replicator/ExistingObjects.swift index f6bc05c..5707f4c 100644 --- a/Replicator/ExistingObjects.swift +++ b/Replicator/ExistingObjects.swift @@ -424,4 +424,8 @@ class ExistingObjects: NSObject, URLSessionDelegate { completion(("Current endpoints - export.saveOnly, not needed.","\(theDestEndpoint)")) } } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/IconDelegate.swift b/Replicator/IconDelegate.swift index 5f71771..bfb44e0 100644 --- a/Replicator/IconDelegate.swift +++ b/Replicator/IconDelegate.swift @@ -617,5 +617,8 @@ class IconDelegate: NSObject, URLSessionDelegate { } // while - end } // DispatchQueue.main.async - end } - + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/Info.plist b/Replicator/Info.plist index a2a71e8..db78a05 100644 --- a/Replicator/Info.plist +++ b/Replicator/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 20260510-5A4 + 20260909-8BF LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/Replicator/Json.swift b/Replicator/Json.swift index b620753..39cb5fe 100644 --- a/Replicator/Json.swift +++ b/Replicator/Json.swift @@ -131,5 +131,9 @@ class Json: NSObject, URLSessionDelegate { } return cleanPolicies as AnyObject } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/ObjectDelegate.swift b/Replicator/ObjectDelegate.swift index dcb3ae6..2aa175e 100644 --- a/Replicator/ObjectDelegate.swift +++ b/Replicator/ObjectDelegate.swift @@ -47,5 +47,9 @@ class ObjectDelegate: NSObject, URLSessionDelegate { } } } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/PackagesDelegate.swift b/Replicator/PackagesDelegate.swift index 973c890..b23b2f1 100644 --- a/Replicator/PackagesDelegate.swift +++ b/Replicator/PackagesDelegate.swift @@ -399,4 +399,8 @@ class PackagesDelegate: NSObject, URLSessionDelegate { // WriteToLog.shared.message("[PackageDelegate.filenameIdDict] Duplicate references to the same package were found on \(theServer)\n\(message)") } } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } diff --git a/Replicator/RemoveObjects.swift b/Replicator/RemoveObjects.swift index 41b8368..95cbbe2 100644 --- a/Replicator/RemoveObjects.swift +++ b/Replicator/RemoveObjects.swift @@ -355,4 +355,8 @@ class RemoveObjects: NSObject, URLSessionDelegate { semaphore.wait() } } + + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + } } From 60fa60aa8da1b072a8beb0a32eae78c8cc1856a2 Mon Sep 17 00:00:00 2001 From: Leslie Helou Date: Tue, 15 Sep 2026 07:49:44 -0400 Subject: [PATCH 5/5] Update Info.plist allow unsecure connections --- Replicator/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Replicator/Info.plist b/Replicator/Info.plist index db78a05..c099900 100644 --- a/Replicator/Info.plist +++ b/Replicator/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 20260909-8BF + 20260909-8C6 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion