From 709037bce5248589f6b7ab3f87ffc37e022e3b8e Mon Sep 17 00:00:00 2001 From: Jamil Date: Sat, 4 Jan 2025 23:52:32 -0800 Subject: [PATCH] chore(apple): Make update download URL compatible with upcoming standalone macOS release (#7666) - Updates Apple download URL to point to app store or website depending on package type - Refactors `AppInfoPlistConstants` to `BundleHelper` to better name what it does --- .../{AppInfoPlistConstants.swift => Bundle.swift} | 13 +++++++++++-- .../Sources/FirezoneKit/Helpers/SharedAccess.swift | 2 +- .../Sources/FirezoneKit/Helpers/Telemetry.swift | 3 +-- .../Sources/FirezoneKit/Models/FirezoneId.swift | 2 +- .../Sources/FirezoneKit/Models/Token.swift | 2 +- .../Sources/FirezoneKit/Views/MenuBar.swift | 2 +- .../Sources/FirezoneKit/Views/SettingsView.swift | 4 ++-- .../FirezoneKit/Views/UpdateNotification.swift | 12 +++++++++--- website/redirects.js | 12 ++++++++++++ website/src/middleware.ts | 5 +++++ 10 files changed, 44 insertions(+), 13 deletions(-) rename swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/{AppInfoPlistConstants.swift => Bundle.swift} (69%) diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/AppInfoPlistConstants.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Bundle.swift similarity index 69% rename from swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/AppInfoPlistConstants.swift rename to swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Bundle.swift index 012603fd9..f80deb120 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/AppInfoPlistConstants.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Bundle.swift @@ -1,12 +1,21 @@ // -// AppInfoPlistConstants.swift +// Bundle.swift // (c) 2024 Firezone, Inc. // LICENSE: Apache-2.0 // import Foundation -struct AppInfoPlistConstants { +enum BundleHelper { + static func isAppStore() -> Bool { + if let receiptURL = Bundle.main.appStoreReceiptURL, + FileManager.default.fileExists(atPath: receiptURL.path) { + return true + } + + return false + } + static var gitSha: String { guard let gitSha = Bundle.main.object(forInfoDictionaryKey: "GitSha") as? String, !gitSha.isEmpty diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/SharedAccess.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/SharedAccess.swift index 90d3a8e4f..6a193de40 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/SharedAccess.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/SharedAccess.swift @@ -21,7 +21,7 @@ public struct SharedAccess { public static var baseFolderURL: URL { guard let url = FileManager.default.containerURL( - forSecurityApplicationGroupIdentifier: AppInfoPlistConstants.appGroupId) + forSecurityApplicationGroupIdentifier: BundleHelper.appGroupId) else { fatalError("Shared folder unavailable") } diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift index 02ba33bcc..1ae96961b 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift @@ -95,8 +95,7 @@ public enum Telemetry { return "ios-appstore-\(version)" #else // Apps from the app store have a receipt file - if let receiptURL = Bundle.main.appStoreReceiptURL, - FileManager.default.fileExists(atPath: receiptURL.path) { + if BundleHelper.isAppStore() { return "macos-appstore-\(version)" } diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/FirezoneId.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/FirezoneId.swift index 5de8ba22e..9d713a859 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/FirezoneId.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/FirezoneId.swift @@ -11,7 +11,7 @@ public struct FirezoneId { private static let query: [CFString: Any] = [ kSecAttrLabel: "Firezone id", kSecAttrAccount: "2", - kSecAttrService: AppInfoPlistConstants.appGroupId, + kSecAttrService: BundleHelper.appGroupId, kSecAttrDescription: "Firezone device id", ] diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Token.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Token.swift index e7fe2b78c..79a91ea0f 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Token.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Models/Token.swift @@ -11,7 +11,7 @@ public struct Token: CustomStringConvertible { private static let query: [CFString: Any] = [ kSecAttrLabel: "Firezone token", kSecAttrAccount: "1", - kSecAttrService: AppInfoPlistConstants.appGroupId, + kSecAttrService: BundleHelper.appGroupId, kSecAttrDescription: "Firezone access token", ] diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift index a2d8190ce..93f68750a 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/MenuBar.swift @@ -308,7 +308,7 @@ public final class MenuBar: NSObject, ObservableObject { } @objc private func updateAvailableButtonTapped() { - NSWorkspace.shared.open(appStoreLink) + NSWorkspace.shared.open(UpdateChecker.downloadURL()) } @objc private func documentationButtonTapped() { diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/SettingsView.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/SettingsView.swift index 2ea4a9307..1e1a97789 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/SettingsView.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/SettingsView.swift @@ -373,7 +373,7 @@ public struct SettingsView: View { } Spacer() HStack { - Text("Build: \(AppInfoPlistConstants.gitSha)") + Text("Build: \(BundleHelper.gitSha)") .textSelection(.enabled) .foregroundColor(.gray) Spacer() @@ -447,7 +447,7 @@ public struct SettingsView: View { } Spacer() HStack { - Text("Build: \(AppInfoPlistConstants.gitSha)") + Text("Build: \(BundleHelper.gitSha)") .textSelection(.enabled) .foregroundColor(.gray) Spacer() diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/UpdateNotification.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/UpdateNotification.swift index 05d5d49ca..3fb2e22fa 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/UpdateNotification.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Views/UpdateNotification.swift @@ -73,9 +73,15 @@ class UpdateChecker { task.resume() } -} -public let appStoreLink = URL(string: "https://apps.apple.com/app/firezone/id6443661826")! + static func downloadURL() -> URL { + if BundleHelper.isAppStore() { + return URL(string: "https://apps.apple.com/app/firezone/id6443661826")! + } + + return URL(string: "https://www.firezone.dev/dl/firezone-client-macos/latest")! + } +} private class NotificationAdapter: NSObject, UNUserNotificationCenterDelegate { private var lastNotifiedVersion: SemVerString? @@ -140,7 +146,7 @@ private class NotificationAdapter: NSObject, UNUserNotificationCenterDelegate { return } - NSWorkspace.shared.open(appStoreLink) + NSWorkspace.shared.open(UpdateChecker.downloadURL()) completionHandler() } diff --git a/website/redirects.js b/website/redirects.js index 6dc37ee9f..1b7acb973 100644 --- a/website/redirects.js +++ b/website/redirects.js @@ -1,6 +1,18 @@ // Add all server-side redirects here. Will be loaded by next.config.mjs. module.exports = [ + /* + * + * macOS Client + * + */ + { + source: "/dl/firezone-client-macos/latest", + destination: + // mark:current-apple-version + "https://www.github.com/firezone/firezone/releases/download/macos-client-1.3.9/firezone-macos-client-1.3.9.dmg", + permanent: false, + }, /* * * Android Client diff --git a/website/src/middleware.ts b/website/src/middleware.ts index 7711d09f7..295f0fd3c 100644 --- a/website/src/middleware.ts +++ b/website/src/middleware.ts @@ -3,6 +3,11 @@ import { NextResponse, NextRequest } from "next/server"; // This middleware is needed because NextJS doesn't populate params in the destination // more than once. See https://github.com/vercel/next.js/issues/66891 const versionedRedirects = [ + { + source: /^\/dl\/firezone-client-macos\/(\d+\.\d+\.\d+)$/, + destination: + "https://www.github.com/firezone/firezone/releases/download/macos-client-:version/firezone-macos-client-:version.dmg", + }, { source: /^\/dl\/firezone-client-android\/(\d+\.\d+\.\d+)$/, destination: