From c1262d740edba076a28643ba1948c7b65dc47a19 Mon Sep 17 00:00:00 2001 From: Federico Maccaroni Date: Tue, 17 Sep 2024 17:31:25 -0300 Subject: [PATCH] [PM-12242] Updated default US and EU region URLs (#939) Co-authored-by: holow29 <67209066+holow29@users.noreply.github.com> --- .../Models/Domain/EnvironmentUrlData.swift | 37 ++++++++++- .../Domain/EnvironmentUrlDataTests.swift | 64 +++++++++++++++++++ .../Models/Domain/EnvironmentUrls.swift | 2 +- .../Models/Domain/EnvironmentUrlsTests.swift | 47 +++++++++++++- .../Services/EnvironmentServiceTests.swift | 38 +++++------ .../Tools/Repositories/SendRepository.swift | 8 ++- .../Repositories/SendRepositoryTests.swift | 10 ++- 7 files changed, 179 insertions(+), 27 deletions(-) diff --git a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlData.swift b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlData.swift index 59bf3c68c..c49363e5f 100644 --- a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlData.swift +++ b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlData.swift @@ -82,9 +82,24 @@ extension EnvironmentUrlData { subpageUrl(additionalPath: "recover-2fa") } + /// Gets the region depending on the base url. + var region: RegionType { + switch base { + case EnvironmentUrlData.defaultUS.base: + .unitedStates + case EnvironmentUrlData.defaultEU.base: + .europe + default: + .selfHosted + } + } + /// The base url for send sharing. var sendShareURL: URL? { - subpageUrl(additionalPath: "send") + guard region != .unitedStates else { + return URL(string: "https://send.bitwarden.com/#")! + } + return subpageUrl(additionalPath: "send") } /// The base url for the settings screen. @@ -118,8 +133,24 @@ extension EnvironmentUrlData { extension EnvironmentUrlData { /// The default URLs for the US region. - static let defaultUS = EnvironmentUrlData(base: URL(string: "https://vault.bitwarden.com")!) + static let defaultUS = EnvironmentUrlData( + api: URL(string: "https://api.bitwarden.com")!, + base: URL(string: "https://vault.bitwarden.com")!, + events: URL(string: "https://events.bitwarden.com")!, + icons: URL(string: "https://icons.bitwarden.net")!, + identity: URL(string: "https://identity.bitwarden.com")!, + notifications: URL(string: "https://notifications.bitwarden.com")!, + webVault: URL(string: "https://vault.bitwarden.com")! + ) /// The default URLs for the EU region. - static let defaultEU = EnvironmentUrlData(base: URL(string: "https://vault.bitwarden.eu")!) + static let defaultEU = EnvironmentUrlData( + api: URL(string: "https://api.bitwarden.eu")!, + base: URL(string: "https://vault.bitwarden.eu")!, + events: URL(string: "https://events.bitwarden.eu")!, + icons: URL(string: "https://icons.bitwarden.eu")!, + identity: URL(string: "https://identity.bitwarden.eu")!, + notifications: URL(string: "https://notifications.bitwarden.eu")!, + webVault: URL(string: "https://vault.bitwarden.eu")! + ) } diff --git a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlDataTests.swift b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlDataTests.swift index 67a19a816..b3e0c78e9 100644 --- a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlDataTests.swift +++ b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlDataTests.swift @@ -5,6 +5,40 @@ import XCTest class EnvironmentUrlDataTests: XCTestCase { // MARK: Tests + /// `defaultUS` returns the properly configured `EnvironmentUrlData` + /// with the deafult Urls for united states region. + func test_defaultUS() { + XCTAssertEqual( + EnvironmentUrlData.defaultUS, + EnvironmentUrlData( + api: URL(string: "https://api.bitwarden.com")!, + base: URL(string: "https://vault.bitwarden.com")!, + events: URL(string: "https://events.bitwarden.com")!, + icons: URL(string: "https://icons.bitwarden.net")!, + identity: URL(string: "https://identity.bitwarden.com")!, + notifications: URL(string: "https://notifications.bitwarden.com")!, + webVault: URL(string: "https://vault.bitwarden.com")! + ) + ) + } + + /// `defaultEU` returns the properly configured `EnvironmentUrlData` + /// with the deafult Urls for europe region. + func test_defaultEU() { + XCTAssertEqual( + EnvironmentUrlData.defaultEU, + EnvironmentUrlData( + api: URL(string: "https://api.bitwarden.eu")!, + base: URL(string: "https://vault.bitwarden.eu")!, + events: URL(string: "https://events.bitwarden.eu")!, + icons: URL(string: "https://icons.bitwarden.eu")!, + identity: URL(string: "https://identity.bitwarden.eu")!, + notifications: URL(string: "https://notifications.bitwarden.eu")!, + webVault: URL(string: "https://vault.bitwarden.eu")! + ) + ) + } + /// `importItemsURL` returns the import items url for the base url. func test_importItemsURL_baseURL() { let subject = EnvironmentUrlData(base: URL(string: "https://vault.example.com")) @@ -42,6 +76,36 @@ class EnvironmentUrlDataTests: XCTestCase { XCTAssertFalse(EnvironmentUrlData(webVault: .example).isEmpty) } + /// `region` returns `.unitedStates` if base url is the same as the default for US. + func test_region_unitedStates() { + let subject = EnvironmentUrlData(base: URL(string: "https://vault.bitwarden.com")!) + XCTAssertTrue(subject.region == .unitedStates) + } + + /// `region` returns `.europe` if base url is the same as the default for EU. + func test_region_europe() { + let subject = EnvironmentUrlData(base: URL(string: "https://vault.bitwarden.eu")!) + XCTAssertTrue(subject.region == .europe) + } + + /// `region` returns `.selfHosted` if base url is neither the default for US nor for EU. + func test_region_selfHost() { + let subject = EnvironmentUrlData(base: URL(string: "https://example.com")!) + XCTAssertTrue(subject.region == .selfHosted) + } + + /// `sendShareURL` returns the send url for the united states region. + func test_sendShareURL_unitedStates() { + let subject = EnvironmentUrlData.defaultUS + XCTAssertEqual(subject.sendShareURL?.absoluteString, "https://send.bitwarden.com/#") + } + + /// `sendShareURL` returns the send url for the europe region. + func test_sendShareURL_europe() { + let subject = EnvironmentUrlData.defaultEU + XCTAssertEqual(subject.sendShareURL?.absoluteString, "https://vault.bitwarden.eu/#/send") + } + /// `sendShareURL` returns the send url for the base url. func test_sendShareURL_baseURL() { let subject = EnvironmentUrlData(base: URL(string: "https://vault.example.com")) diff --git a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrls.swift b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrls.swift index aa53069e8..eb6c42a77 100644 --- a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrls.swift +++ b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrls.swift @@ -42,7 +42,7 @@ extension EnvironmentUrls { /// - Parameter environmentUrlData: The environment URLs used to initialize `EnvironmentUrls`. /// init(environmentUrlData: EnvironmentUrlData) { - if let base = environmentUrlData.base { + if environmentUrlData.region == .selfHosted, let base = environmentUrlData.base { apiURL = base.appendingPathComponent("api") baseURL = base eventsURL = base.appendingPathComponent("events") diff --git a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlsTests.swift b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlsTests.swift index 0682d1c1b..60df7b966 100644 --- a/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlsTests.swift +++ b/BitwardenShared/Core/Platform/Models/Domain/EnvironmentUrlsTests.swift @@ -5,7 +5,52 @@ import XCTest class EnvironmentUrlsTests: BitwardenTestCase { // MARK: Tests - /// `init(environmentUrlData:)` sets the URLs from the base URL if one is set. + /// `init(environmentUrlData:)` sets the URLs from the passed data when such data is the default US. + func test_init_environmentUrlData_defaultUS() { + let subject = EnvironmentUrls( + environmentUrlData: EnvironmentUrlData.defaultUS + ) + XCTAssertEqual( + subject, + EnvironmentUrls( + apiURL: URL(string: "https://api.bitwarden.com")!, + baseURL: URL(string: "https://vault.bitwarden.com")!, + eventsURL: URL(string: "https://events.bitwarden.com")!, + iconsURL: URL(string: "https://icons.bitwarden.net")!, + identityURL: URL(string: "https://identity.bitwarden.com")!, + importItemsURL: URL(string: "https://vault.bitwarden.com/#/tools/import")!, + recoveryCodeURL: URL(string: "https://vault.bitwarden.com/#/recover-2fa")!, + sendShareURL: URL(string: "https://send.bitwarden.com/#")!, + settingsURL: URL(string: "https://vault.bitwarden.com/#/settings")!, + webVaultURL: URL(string: "https://vault.bitwarden.com")! + ) + ) + } + + /// `init(environmentUrlData:)` sets the URLs from the passed data when such data is the default EU. + func test_init_environmentUrlData_defaultEU() { + let subject = EnvironmentUrls( + environmentUrlData: EnvironmentUrlData.defaultEU + ) + XCTAssertEqual( + subject, + EnvironmentUrls( + apiURL: URL(string: "https://api.bitwarden.eu")!, + baseURL: URL(string: "https://vault.bitwarden.eu")!, + eventsURL: URL(string: "https://events.bitwarden.eu")!, + iconsURL: URL(string: "https://icons.bitwarden.eu")!, + identityURL: URL(string: "https://identity.bitwarden.eu")!, + importItemsURL: URL(string: "https://vault.bitwarden.eu/#/tools/import")!, + recoveryCodeURL: URL(string: "https://vault.bitwarden.eu/#/recover-2fa")!, + sendShareURL: URL(string: "https://vault.bitwarden.eu/#/send")!, + settingsURL: URL(string: "https://vault.bitwarden.eu/#/settings")!, + webVaultURL: URL(string: "https://vault.bitwarden.eu")! + ) + ) + } + + /// `init(environmentUrlData:)` sets the URLs from the base URL if one is set and is not + /// `.unitedStates` nor `.europe` region type. func test_init_environmentUrlData_baseUrl() { let subject = EnvironmentUrls( environmentUrlData: EnvironmentUrlData(base: URL(string: "https://example.com")!) diff --git a/BitwardenShared/Core/Platform/Services/EnvironmentServiceTests.swift b/BitwardenShared/Core/Platform/Services/EnvironmentServiceTests.swift index cb2ae457b..1b23b1f59 100644 --- a/BitwardenShared/Core/Platform/Services/EnvironmentServiceTests.swift +++ b/BitwardenShared/Core/Platform/Services/EnvironmentServiceTests.swift @@ -36,13 +36,13 @@ class EnvironmentServiceTests: XCTestCase { /// The default US URLs are returned if the URLs haven't been loaded. func test_defaultUrls() { - XCTAssertEqual(subject.apiURL, URL(string: "https://vault.bitwarden.com/api")) - XCTAssertEqual(subject.eventsURL, URL(string: "https://vault.bitwarden.com/events")) - XCTAssertEqual(subject.iconsURL, URL(string: "https://vault.bitwarden.com/icons")) - XCTAssertEqual(subject.identityURL, URL(string: "https://vault.bitwarden.com/identity")) + XCTAssertEqual(subject.apiURL, URL(string: "https://api.bitwarden.com")) + XCTAssertEqual(subject.eventsURL, URL(string: "https://events.bitwarden.com")) + XCTAssertEqual(subject.iconsURL, URL(string: "https://icons.bitwarden.net")) + XCTAssertEqual(subject.identityURL, URL(string: "https://identity.bitwarden.com")) XCTAssertEqual(subject.importItemsURL, URL(string: "https://vault.bitwarden.com/#/tools/import")) XCTAssertEqual(subject.region, .unitedStates) - XCTAssertEqual(subject.sendShareURL, URL(string: "https://vault.bitwarden.com/#/send")) + XCTAssertEqual(subject.sendShareURL, URL(string: "https://send.bitwarden.com/#")) XCTAssertEqual(subject.settingsURL, URL(string: "https://vault.bitwarden.com/#/settings")) XCTAssertEqual(subject.webVaultURL, URL(string: "https://vault.bitwarden.com")) } @@ -77,10 +77,10 @@ class EnvironmentServiceTests: XCTestCase { await subject.loadURLsForActiveAccount() - XCTAssertEqual(subject.apiURL, URL(string: "https://vault.bitwarden.eu/api")) - XCTAssertEqual(subject.eventsURL, URL(string: "https://vault.bitwarden.eu/events")) - XCTAssertEqual(subject.iconsURL, URL(string: "https://vault.bitwarden.eu/icons")) - XCTAssertEqual(subject.identityURL, URL(string: "https://vault.bitwarden.eu/identity")) + XCTAssertEqual(subject.apiURL, URL(string: "https://api.bitwarden.eu")) + XCTAssertEqual(subject.eventsURL, URL(string: "https://events.bitwarden.eu")) + XCTAssertEqual(subject.iconsURL, URL(string: "https://icons.bitwarden.eu")) + XCTAssertEqual(subject.identityURL, URL(string: "https://identity.bitwarden.eu")) XCTAssertEqual(subject.importItemsURL, URL(string: "https://vault.bitwarden.eu/#/tools/import")) XCTAssertEqual(subject.region, .europe) XCTAssertEqual(subject.sendShareURL, URL(string: "https://vault.bitwarden.eu/#/send")) @@ -124,13 +124,13 @@ class EnvironmentServiceTests: XCTestCase { await subject.loadURLsForActiveAccount() - XCTAssertEqual(subject.apiURL, URL(string: "https://vault.bitwarden.com/api")) - XCTAssertEqual(subject.eventsURL, URL(string: "https://vault.bitwarden.com/events")) - XCTAssertEqual(subject.iconsURL, URL(string: "https://vault.bitwarden.com/icons")) - XCTAssertEqual(subject.identityURL, URL(string: "https://vault.bitwarden.com/identity")) + XCTAssertEqual(subject.apiURL, URL(string: "https://api.bitwarden.com")) + XCTAssertEqual(subject.eventsURL, URL(string: "https://events.bitwarden.com")) + XCTAssertEqual(subject.iconsURL, URL(string: "https://icons.bitwarden.net")) + XCTAssertEqual(subject.identityURL, URL(string: "https://identity.bitwarden.com")) XCTAssertEqual(subject.importItemsURL, URL(string: "https://vault.bitwarden.com/#/tools/import")) XCTAssertEqual(subject.region, .unitedStates) - XCTAssertEqual(subject.sendShareURL, URL(string: "https://vault.bitwarden.com/#/send")) + XCTAssertEqual(subject.sendShareURL, URL(string: "https://send.bitwarden.com/#")) XCTAssertEqual(subject.settingsURL, URL(string: "https://vault.bitwarden.com/#/settings")) XCTAssertEqual(subject.webVaultURL, URL(string: "https://vault.bitwarden.com")) @@ -143,13 +143,13 @@ class EnvironmentServiceTests: XCTestCase { func test_loadURLsForActiveAccount_noAccount() async { await subject.loadURLsForActiveAccount() - XCTAssertEqual(subject.apiURL, URL(string: "https://vault.bitwarden.com/api")) - XCTAssertEqual(subject.eventsURL, URL(string: "https://vault.bitwarden.com/events")) - XCTAssertEqual(subject.iconsURL, URL(string: "https://vault.bitwarden.com/icons")) - XCTAssertEqual(subject.identityURL, URL(string: "https://vault.bitwarden.com/identity")) + XCTAssertEqual(subject.apiURL, URL(string: "https://api.bitwarden.com")) + XCTAssertEqual(subject.eventsURL, URL(string: "https://events.bitwarden.com")) + XCTAssertEqual(subject.iconsURL, URL(string: "https://icons.bitwarden.net")) + XCTAssertEqual(subject.identityURL, URL(string: "https://identity.bitwarden.com")) XCTAssertEqual(subject.importItemsURL, URL(string: "https://vault.bitwarden.com/#/tools/import")) XCTAssertEqual(subject.region, .unitedStates) - XCTAssertEqual(subject.sendShareURL, URL(string: "https://vault.bitwarden.com/#/send")) + XCTAssertEqual(subject.sendShareURL, URL(string: "https://send.bitwarden.com/#")) XCTAssertEqual(subject.settingsURL, URL(string: "https://vault.bitwarden.com/#/settings")) XCTAssertEqual(subject.webVaultURL, URL(string: "https://vault.bitwarden.com")) XCTAssertEqual(stateService.preAuthEnvironmentUrls, .defaultUS) diff --git a/BitwardenShared/Core/Tools/Repositories/SendRepository.swift b/BitwardenShared/Core/Tools/Repositories/SendRepository.swift index 3f22be95c..336aab130 100644 --- a/BitwardenShared/Core/Tools/Repositories/SendRepository.swift +++ b/BitwardenShared/Core/Tools/Repositories/SendRepository.swift @@ -199,8 +199,12 @@ class DefaultSendRepository: SendRepository { func shareURL(for sendView: SendView) async throws -> URL? { guard let accessId = sendView.accessId, let key = sendView.key else { return nil } - let sharePath = "/\(accessId)/\(key)" - let url = URL(string: environmentService.sendShareURL.absoluteString.appending(sharePath)) + let sharePath = "\(accessId)/\(key)" + var sendShareUrlString = environmentService.sendShareURL.absoluteString + if !sendShareUrlString.hasSuffix("#") { + sendShareUrlString = sendShareUrlString.appending("/") + } + let url = URL(string: sendShareUrlString.appending(sharePath)) return url } diff --git a/BitwardenShared/Core/Tools/Repositories/SendRepositoryTests.swift b/BitwardenShared/Core/Tools/Repositories/SendRepositoryTests.swift index a6b86e73b..e1d949416 100644 --- a/BitwardenShared/Core/Tools/Repositories/SendRepositoryTests.swift +++ b/BitwardenShared/Core/Tools/Repositories/SendRepositoryTests.swift @@ -344,12 +344,20 @@ class SendRepositoryTests: BitwardenTestCase { // swiftlint:disable:this type_bo /// `shareURL()` successfully generates a share url for the send view. func test_shareURL() async throws { let sendView = SendView.fixture(accessId: "ACCESS_ID", key: "KEY") - environmentService.webVaultURL = .example let url = try await subject.shareURL(for: sendView) XCTAssertEqual(url?.absoluteString, "https://example.com/#/send/ACCESS_ID/KEY") } + /// `shareURL()` successfully generates a share url for the send view when the `sendShareURL` ends with a "#". + func test_shareURL_poundSignSuffix() async throws { + let sendView = SendView.fixture(accessId: "ACCESS_ID", key: "KEY") + environmentService.sendShareURL = URL(string: "https://send.bitwarden.com/#")! + let url = try await subject.shareURL(for: sendView) + + XCTAssertEqual(url?.absoluteString, "https://send.bitwarden.com/#ACCESS_ID/KEY") + } + /// `updateSend()` successfully encrypts the send view and uses the send service to update it. func test_updateSend() async throws { let sendResult = Send.fixture(id: "SEND_ID")