Skip to content

Commit

Permalink
Merge branch 'main' into matt/BIT-1212-refactor-vault-group
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-livefront committed Mar 19, 2024
2 parents 94d09f2 + ea85e6c commit c733caa
Show file tree
Hide file tree
Showing 57 changed files with 675 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class MockClientAuth: ClientAuthProtocol {
return satisfiesPolicyResult
}

func t() async throws -> BitwardenSdk.TrustDeviceResponse {
func trustDevice() async throws -> BitwardenSdk.TrustDeviceResponse {
// Nothing yet.
throw BitwardenTestError.example
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ class MockClientPlatform: ClientPlatformProtocol {
try fingerprintResult.get()
}

func loadFlags(flags: [String: Bool]) async throws {
// Nothing yet.
throw BitwardenTestError.example
}

func userFingerprint(fingerprintMaterial: String) async throws -> String {
fingerprintMaterialString = fingerprintMaterial
userFingerprintCalled = true
Expand Down
2 changes: 1 addition & 1 deletion BitwardenShared/Core/Platform/Models/Domain/Account.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ extension Account {
let orgIdentifier: String?

/// The account's security stamp.
let stamp: String?
var stamp: String?

/// User decryption options for the account.
let userDecryptionOptions: UserDecryptionOptions?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ struct EnvironmentUrlData: Codable, Equatable, Hashable {
}

extension EnvironmentUrlData {
// MARK: Properties

/// The base url for importing items.
var importItemsURL: URL? {
subpageUrl(additionalPath: "tools/import")
}

/// Whether all of the environment URLs are not set.
var isEmpty: Bool {
api == nil
Expand All @@ -72,18 +79,36 @@ extension EnvironmentUrlData {

/// The base url for send sharing.
var sendShareURL: URL? {
if let sendBase = webVault ?? base,
let url = URL(string: sendBase.absoluteString.appending("/#/send")) {
return url
}
return nil
subpageUrl(additionalPath: "send")
}

/// The base url for the settings screen.
var settingsURL: URL? {
subpageUrl(additionalPath: "settings")
}

/// The host of URL to the user's web vault.
var webVaultHost: String? {
let url = webVault ?? base
return url?.host
}

// MARK: Methods

/// The URL for a given subpage of the vault webpage.
///
/// - Parameters:
/// - additionalPath: The additional path string to append to the vault's base URL
private func subpageUrl(additionalPath: String) -> URL? {
// Foundation's URL appending methods percent encode the path component that is passed into the method,
// which includes the `#` symbol. Since the `#` character is a critical portion of these urls, we use String
// concatenation to get around this limitation.
if let baseUrl = webVault ?? base,
let url = URL(string: baseUrl.absoluteString.appending("/#/\(additionalPath)")) {
return url
}
return nil
}
}

extension EnvironmentUrlData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ import XCTest
class EnvironmentUrlDataTests: XCTestCase {
// MARK: Tests

/// `importItemsURL` returns the import items url for the base url.
func test_importItemsURL_baseURL() {
let subject = EnvironmentUrlData(base: URL(string: "https://vault.example.com"))
XCTAssertEqual(subject.importItemsURL?.absoluteString, "https://vault.example.com/#/tools/import")
}

/// `importItemsURL` returns the default import items base url.
func test_importItemsURL_noURLs() {
let subject = EnvironmentUrlData(base: nil, webVault: nil)
XCTAssertNil(subject.importItemsURL?.absoluteString)
}

/// `importItemsURL` returns the import items url for the web vault url.
func test_importItemsURL_webVaultURL() {
let subject = EnvironmentUrlData(
base: URL(string: "https://vault.example.com"),
webVault: URL(string: "https://web.vault.example.com")
)
XCTAssertEqual(subject.importItemsURL?.absoluteString, "https://web.vault.example.com/#/tools/import")
}

/// `isEmpty` is true if none of the URLs are set.
func test_isEmpty_empty() {
XCTAssertTrue(EnvironmentUrlData().isEmpty)
Expand Down Expand Up @@ -42,6 +63,27 @@ class EnvironmentUrlDataTests: XCTestCase {
XCTAssertEqual(subject.sendShareURL?.absoluteString, "https://web.vault.example.com/#/send")
}

/// `settingsURL` returns the settings url for the base url.
func test_settingsURL_baseURL() {
let subject = EnvironmentUrlData(base: URL(string: "https://vault.example.com"))
XCTAssertEqual(subject.settingsURL?.absoluteString, "https://vault.example.com/#/settings")
}

/// `settingsURL` returns the default settings base url.
func test_settingsURL_noURLs() {
let subject = EnvironmentUrlData(base: nil, webVault: nil)
XCTAssertNil(subject.settingsURL?.absoluteString)
}

/// `settingsURL` returns the settings url for the web vault url.
func test_settingsURL_webVaultURL() {
let subject = EnvironmentUrlData(
base: URL(string: "https://vault.example.com"),
webVault: URL(string: "https://web.vault.example.com")
)
XCTAssertEqual(subject.settingsURL?.absoluteString, "https://web.vault.example.com/#/settings")
}

/// `webVaultHost` returns the host for the base URL if no web vault URL is set.
func test_webVaultHost_baseURL() {
let subject = EnvironmentUrlData(base: URL(string: "https://vault.example.com"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ struct EnvironmentUrls: Equatable {
/// The URL for the identity API.
let identityURL: URL

/// The URL for importing items.
let importItemsURL: URL

/// The URL for sharing a send.
let sendShareURL: URL

/// The URL for vault settings.
let settingsURL: URL

/// The URL for the web vault.
let webVaultURL: URL
}
Expand All @@ -48,6 +54,8 @@ extension EnvironmentUrls {
identityURL = environmentUrlData.identity ?? URL(string: "https://identity.bitwarden.com")!
webVaultURL = environmentUrlData.webVault ?? URL(string: "https://vault.bitwarden.com")!
}
importItemsURL = environmentUrlData.importItemsURL ?? URL(string: "https://vault.bitwarden.com/#/tools/import")!
sendShareURL = environmentUrlData.sendShareURL ?? URL(string: "https://send.bitwarden.com/#")!
settingsURL = environmentUrlData.settingsURL ?? webVaultURL
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class EnvironmentUrlsTests: BitwardenTestCase {
eventsURL: URL(string: "https://example.com/events")!,
iconsURL: URL(string: "https://example.com/icons")!,
identityURL: URL(string: "https://example.com/identity")!,
importItemsURL: URL(string: "https://example.com/#/tools/import")!,
sendShareURL: URL(string: "https://example.com/#/send")!,
settingsURL: URL(string: "https://example.com/#/settings")!,
webVaultURL: URL(string: "https://example.com")!
)
)
Expand All @@ -43,7 +45,9 @@ class EnvironmentUrlsTests: BitwardenTestCase {
eventsURL: URL(string: "https://events.example.com")!,
iconsURL: URL(string: "https://icons.example.com")!,
identityURL: URL(string: "https://identity.example.com")!,
importItemsURL: URL(string: "https://example.com/#/tools/import")!,
sendShareURL: URL(string: "https://example.com/#/send")!,
settingsURL: URL(string: "https://example.com/#/settings")!,
webVaultURL: URL(string: "https://example.com")!
)
)
Expand All @@ -60,7 +64,9 @@ class EnvironmentUrlsTests: BitwardenTestCase {
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")!,
sendShareURL: URL(string: "https://send.bitwarden.com/#")!,
settingsURL: URL(string: "https://vault.bitwarden.com")!,
webVaultURL: URL(string: "https://vault.bitwarden.com")!
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ extension Account.AccountProfile {
kdfType: KdfType? = .pbkdf2sha256,
name: String? = nil,
orgIdentifier: String? = nil,
stamp: String? = "STAMP",
stamp: String? = "stamp",
userDecryptionOptions: UserDecryptionOptions? = nil,
userId: String = "1"
) -> Account.AccountProfile {
Expand Down
18 changes: 16 additions & 2 deletions BitwardenShared/Core/Platform/Services/EnvironmentService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ protocol EnvironmentService {
/// The URL for the identity API.
var identityURL: URL { get }

/// The URL for importing items.
var importItemsURL: URL { get }

/// The URL for sharing a send.
var sendShareURL: URL { get }

/// The URL for vault settings.
var settingsURL: URL { get }

/// The URL for the web vault.
var webVaultURL: URL { get }

Expand Down Expand Up @@ -89,6 +95,10 @@ extension DefaultEnvironmentService {
environmentUrls.apiURL
}

var eventsURL: URL {
environmentUrls.eventsURL
}

var iconsURL: URL {
environmentUrls.iconsURL
}
Expand All @@ -97,14 +107,18 @@ extension DefaultEnvironmentService {
environmentUrls.identityURL
}

var eventsURL: URL {
environmentUrls.eventsURL
var importItemsURL: URL {
environmentUrls.importItemsURL
}

var sendShareURL: URL {
environmentUrls.sendShareURL
}

var settingsURL: URL {
environmentUrls.settingsURL
}

var webVaultURL: URL {
environmentUrls.webVaultURL
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ class EnvironmentServiceTests: XCTestCase {
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.importItemsURL, URL(string: "https://vault.bitwarden.com/#/tools/import"))
XCTAssertEqual(subject.sendShareURL, URL(string: "https://vault.bitwarden.com/#/send"))
XCTAssertEqual(subject.settingsURL, URL(string: "https://vault.bitwarden.com/#/settings"))
XCTAssertEqual(subject.webVaultURL, URL(string: "https://vault.bitwarden.com"))
}

Expand All @@ -46,7 +50,11 @@ class EnvironmentServiceTests: XCTestCase {

XCTAssertEqual(subject.apiURL, URL(string: "https://example.com/api"))
XCTAssertEqual(subject.eventsURL, URL(string: "https://example.com/events"))
XCTAssertEqual(subject.iconsURL, URL(string: "https://example.com/icons"))
XCTAssertEqual(subject.identityURL, URL(string: "https://example.com/identity"))
XCTAssertEqual(subject.importItemsURL, URL(string: "https://example.com/#/tools/import"))
XCTAssertEqual(subject.sendShareURL, URL(string: "https://example.com/#/send"))
XCTAssertEqual(subject.settingsURL, URL(string: "https://example.com/#/settings"))
XCTAssertEqual(subject.webVaultURL, URL(string: "https://example.com"))
}

Expand All @@ -56,7 +64,11 @@ class EnvironmentServiceTests: XCTestCase {

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.importItemsURL, URL(string: "https://vault.bitwarden.com/#/tools/import"))
XCTAssertEqual(subject.sendShareURL, URL(string: "https://vault.bitwarden.com/#/send"))
XCTAssertEqual(subject.settingsURL, URL(string: "https://vault.bitwarden.com/#/settings"))
XCTAssertEqual(subject.webVaultURL, URL(string: "https://vault.bitwarden.com"))
}

Expand All @@ -68,7 +80,11 @@ class EnvironmentServiceTests: XCTestCase {

XCTAssertEqual(subject.apiURL, URL(string: "https://example.com/api"))
XCTAssertEqual(subject.eventsURL, URL(string: "https://example.com/events"))
XCTAssertEqual(subject.iconsURL, URL(string: "https://example.com/icons"))
XCTAssertEqual(subject.identityURL, URL(string: "https://example.com/identity"))
XCTAssertEqual(subject.importItemsURL, URL(string: "https://example.com/#/tools/import"))
XCTAssertEqual(subject.sendShareURL, URL(string: "https://example.com/#/send"))
XCTAssertEqual(subject.settingsURL, URL(string: "https://example.com/#/settings"))
XCTAssertEqual(subject.webVaultURL, URL(string: "https://example.com"))
XCTAssertEqual(stateService.preAuthEnvironmentUrls, urls)
}
Expand Down
1 change: 1 addition & 0 deletions BitwardenShared/Core/Platform/Services/StateService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,7 @@ actor DefaultStateService: StateService { // swiftlint:disable:this type_body_le
profile.email = response.email ?? profile.email
profile.emailVerified = response.emailVerified
profile.name = response.name
profile.stamp = response.securityStamp

state.accounts[userId]?.profile = profile
}
Expand Down
45 changes: 45 additions & 0 deletions BitwardenShared/Core/Platform/Services/StateServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1224,4 +1224,49 @@ class StateServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body

XCTAssertEqual(publishedValues, [true, false])
}

/// `updateProfile(from:userId:)` updates the user's profile from the profile response.
func test_updateProfile() async throws {
await subject.addAccount(
.fixture(
profile: .fixture(
avatarColor: nil,
email: "[email protected]",
emailVerified: false,
hasPremiumPersonally: false,
name: "User",
stamp: "stamp",
userId: "1"
)
)
)

await subject.updateProfile(
from: .fixture(
avatarColor: "175DDC",
email: "[email protected]",
emailVerified: true,
name: "Other",
premium: true,
securityStamp: "new stamp"
),
userId: "1"
)

let updatedAccount = try await subject.getActiveAccount()
XCTAssertEqual(
updatedAccount,
.fixture(
profile: .fixture(
avatarColor: "175DDC",
email: "[email protected]",
emailVerified: true,
hasPremiumPersonally: true,
name: "Other",
stamp: "new stamp",
userId: "1"
)
)
)
}
} // swiftlint:disable:this file_length
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ class MockEnvironmentService: EnvironmentService {
var eventsURL = URL(string: "https://example.com/events")!
var iconsURL = URL(string: "https://example.com/icons")!
var identityURL = URL(string: "https://example.com/identity")!
var importItemsURL = URL(string: "https://example.com/#/tools/import")!
var sendShareURL = URL(string: "https://example.com/#/send")!
var settingsURL = URL(string: "https://example.com/#/settings")!
var webVaultURL = URL(string: "https://example.com")!

func loadURLsForActiveAccount() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ class DefaultTwoStepLoginService: TwoStepLoginService {
// MARK: Methods

func twoStepLoginUrl() -> URL {
// Foundation's URL appending methods percent encode the path component that is passed into the method,
// which includes the `#` symbol. Since the `#` character is a critical portion of this url, we use String
// concatenation to get around this limitation. If for some reason this URL creation fails, we pass back the
// base url for this user. This should take them to the web app regardless,
// and they can navigate to the settings page from there.
URL(string: environmentService.webVaultURL.absoluteString + "/#/settings") ?? environmentService.webVaultURL
environmentService.settingsURL
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ struct UsernameGenerationOptions: Codable, Equatable {
/// The Firefox Relay API access token used to generate a forwarded email alias.
var firefoxRelayApiAccessToken: String?

/// The ForwardEmail API token used to generate a forwarded email alias.
var forwardEmailApiToken: String?

/// The ForwardEmail domain name used to generate a forwarded email alias.
var forwardEmailDomainName: String?

/// Whether the random word should include numbers.
var includeNumberRandomWordUsername: Bool?

Expand Down
Loading

0 comments on commit c733caa

Please sign in to comment.