Rename OIDC to OAuth. (#5525)
* Rename OIDC to OAuth. * Update the enterprise submodule.
This commit is contained in:
@@ -21,22 +21,22 @@ struct AppRouteURLParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func oidcCallbackRoute() {
|
||||
// Given an OIDC callback for this app.
|
||||
let callbackURL = appSettings.oidcRedirectURL.appending(queryItems: [URLQueryItem(name: "state", value: "12345"),
|
||||
URLQueryItem(name: "code", value: "67890")])
|
||||
func oAuthCallbackRoute() {
|
||||
// Given an OAuth callback for this app.
|
||||
let callbackURL = appSettings.oAuthRedirectURL.appending(queryItems: [URLQueryItem(name: "state", value: "12345"),
|
||||
URLQueryItem(name: "code", value: "67890")])
|
||||
|
||||
// When parsing that route.
|
||||
let route = appRouteURLParser.route(from: callbackURL)
|
||||
|
||||
// Then it should be considered a valid OIDC callback.
|
||||
#expect(route == .oidcCallback(url: callbackURL))
|
||||
// Then it should be considered a valid OAuth callback.
|
||||
#expect(route == .oAuthCallback(url: callbackURL))
|
||||
}
|
||||
|
||||
@Test
|
||||
func oidcCallbackAppVariantRoute() {
|
||||
// Given an OIDC callback for a different app variant.
|
||||
let callbackURL = appSettings.oidcRedirectURL
|
||||
func oAuthCallbackAppVariantRoute() {
|
||||
// Given an OAuth callback for a different app variant.
|
||||
let callbackURL = appSettings.oAuthRedirectURL
|
||||
.deletingLastPathComponent()
|
||||
.appending(component: "io.element.elementz")
|
||||
.appending(queryItems: [URLQueryItem(name: "state", value: "12345"),
|
||||
|
||||
@@ -45,7 +45,7 @@ struct AuthenticationServiceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func configureLoginWithOIDC() async throws {
|
||||
mutating func configureLoginWithOAuth() async throws {
|
||||
try await setup()
|
||||
|
||||
try await service.configure(for: "matrix.org", flow: .login).get()
|
||||
@@ -55,7 +55,7 @@ struct AuthenticationServiceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func configureRegisterWithOIDC() async throws {
|
||||
mutating func configureRegisterWithOAuth() async throws {
|
||||
try await setup()
|
||||
|
||||
try await service.configure(for: "matrix.org", flow: .register).get()
|
||||
|
||||
@@ -64,15 +64,15 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func provisionedOIDCState() async throws {
|
||||
// Given a view model that has been provisioned with a server that supports OIDC.
|
||||
func provisionedOAuthState() async throws {
|
||||
// Given a view model that has been provisioned with a server that supports OAuth.
|
||||
await setupViewModel(provisioningParameters: .init(accountProvider: "company.com", loginHint: "user@company.com"))
|
||||
#expect(authenticationService.homeserver.value.loginMode == .unknown)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
// When tapping the login button the authentication service should be used and the screen
|
||||
// should request to continue the flow without any server selection needed.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
|
||||
context.send(viewAction: .login)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -80,13 +80,13 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "user@company.com")
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
|
||||
}
|
||||
|
||||
@Test
|
||||
func provisionedPasswordState() async throws {
|
||||
// Given a view model that has been provisioned with a server that does not support OIDC.
|
||||
await setupViewModel(provisioningParameters: .init(accountProvider: "company.com", loginHint: "user@company.com"), supportsOIDC: false)
|
||||
// Given a view model that has been provisioned with a server that does not support OAuth.
|
||||
await setupViewModel(provisioningParameters: .init(accountProvider: "company.com", loginHint: "user@company.com"), supportsOAuth: false)
|
||||
#expect(authenticationService.homeserver.value.loginMode == .unknown)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
@@ -102,8 +102,8 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func singleProviderOIDCState() async throws {
|
||||
// Given a view model that for an app that only allows the use of a single provider that supports OIDC.
|
||||
func singleProviderOAuthState() async throws {
|
||||
// Given a view model that for an app that only allows the use of a single provider that supports OAuth.
|
||||
setAllowedAccountProviders(["company.com"])
|
||||
await setupViewModel()
|
||||
#expect(authenticationService.homeserver.value.loginMode == .unknown)
|
||||
@@ -111,7 +111,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
|
||||
// When tapping the login button the authentication service should be used and the screen
|
||||
// should request to continue the flow without any server selection needed.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
|
||||
context.send(viewAction: .login)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -119,14 +119,14 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == nil)
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
|
||||
}
|
||||
|
||||
@Test
|
||||
func singleProviderPasswordState() async throws {
|
||||
// Given a view model that for an app that only allows the use of a single provider that does not support OIDC.
|
||||
// Given a view model that for an app that only allows the use of a single provider that does not support OAuth.
|
||||
setAllowedAccountProviders(["company.com"])
|
||||
await setupViewModel(supportsOIDC: false)
|
||||
await setupViewModel(supportsOAuth: false)
|
||||
#expect(authenticationService.homeserver.value.loginMode == .unknown)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
@@ -156,13 +156,13 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
|
||||
// When continuing with the Classic app account the authentication service should be used and the screen
|
||||
// should request to continue the flow without any server selection needed.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
|
||||
context.send(viewAction: .continueWithClassic(classicAppAccount))
|
||||
try await deferred.fulfill()
|
||||
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.homeserverAddress == "company.com")
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "mxid:\(classicAppAccount.userID)")
|
||||
}
|
||||
|
||||
@@ -180,21 +180,21 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
|
||||
// When continuing with the Classic app account the authentication service should be used with the direct homeserver URL
|
||||
// and the screen should request to continue the flow without any server selection needed.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
|
||||
context.send(viewAction: .continueWithClassic(classicAppAccount))
|
||||
try await deferred.fulfill()
|
||||
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 2)
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments?.homeserverAddress == "https://matrix.company.com")
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oidc(supportsCreatePrompt: false))
|
||||
#expect(authenticationService.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: false))
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.loginHint == "mxid:\(classicAppAccount.userID)")
|
||||
}
|
||||
|
||||
@Test
|
||||
func classicAppAccountOnUnsupportedServer() async {
|
||||
// Given a view model with a Classic app account whose server supports neither OIDC nor password login.
|
||||
// Given a view model with a Classic app account whose server supports neither OAuth nor password login.
|
||||
let classicAppAccount = makeClassicAppAccount()
|
||||
await setupViewModel(classicAppAccount: classicAppAccount, supportsOIDC: false, supportsPasswordLogin: false)
|
||||
await setupViewModel(classicAppAccount: classicAppAccount, supportsOAuth: false, supportsPasswordLogin: false)
|
||||
guard case .welcomeBack(let account) = context.viewState.classicAppMode else {
|
||||
Issue.record("Expected classicAppMode to be .welcomeBack")
|
||||
return
|
||||
@@ -271,7 +271,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
try await deferred.fulfill()
|
||||
|
||||
// When the user continues with the Classic account again.
|
||||
let deferredAction = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
|
||||
let deferredAction = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOAuth }
|
||||
context.send(viewAction: .continueWithClassic(classicAppAccount))
|
||||
|
||||
// Then the flow should continue the login process.
|
||||
@@ -282,12 +282,12 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
|
||||
private func setupViewModel(classicAppAccount: ClassicAppAccount? = nil,
|
||||
provisioningParameters: AccountProvisioningParameters? = nil,
|
||||
supportsOIDC: Bool = true,
|
||||
supportsOAuth: Bool = true,
|
||||
supportsPasswordLogin: Bool = true,
|
||||
availableSecrets: ClassicAppAccount.AvailableSecrets = .complete) async {
|
||||
// Manually create a configuration as the default homeserver address setting is immutable.
|
||||
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.company.com/authorize" : nil,
|
||||
supportsOIDCCreatePrompt: false,
|
||||
client = ClientSDKMock(configuration: .init(oAuthLoginURL: supportsOAuth ? "https://account.company.com/authorize" : nil,
|
||||
supportsOAuthCreatePrompt: false,
|
||||
supportsPasswordLogin: supportsPasswordLogin))
|
||||
// Map both the server name and the homeserver URL so fallback lookups work.
|
||||
let homeserverClients: [String: ClientSDKMock] = ["company.com": client,
|
||||
@@ -321,7 +321,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
notificationCenter: notificationCenter,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
// Add a fake window in order for the OIDC flow to continue
|
||||
// Add a fake window in order for the OAuth flow to continue
|
||||
viewModel.context.send(viewAction: .updateWindow(UIWindow()))
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
allowOtherAccountProviders: false,
|
||||
hideBrandChrome: false,
|
||||
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
|
||||
oidcRedirectURL: appSettings.oidcRedirectURL,
|
||||
oAuthRedirectURL: appSettings.oAuthRedirectURL,
|
||||
websiteURL: appSettings.websiteURL,
|
||||
logoURL: appSettings.logoURL,
|
||||
copyrightURL: appSettings.copyrightURL,
|
||||
@@ -362,9 +362,9 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
}
|
||||
|
||||
extension AuthenticationStartScreenViewModelAction {
|
||||
var isLoginDirectlyWithOIDC: Bool {
|
||||
var isLoginDirectlyWithOAuth: Bool {
|
||||
switch self {
|
||||
case .loginDirectlyWithOIDC: true
|
||||
case .loginDirectlyWithOAuth: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,21 +155,21 @@ struct LoginScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func oidcServer() async throws {
|
||||
mutating func oAuthServer() async throws {
|
||||
// Given the screen configured for matrix.org
|
||||
await setupViewModel()
|
||||
|
||||
// When entering a username for a user on a homeserver with OIDC.
|
||||
// When entering a username for a user on a homeserver with OAuth.
|
||||
let deferred = deferFulfillment(viewModel.actions) {
|
||||
$0.isConfiguredForOIDC
|
||||
$0.isConfiguredForOAuth
|
||||
}
|
||||
context.username = "@bob:company.com"
|
||||
context.send(viewAction: .parseUsername)
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then the view state should be updated with the homeserver and show the OIDC button.
|
||||
#expect(context.viewState.loginMode.supportsOIDCFlow,
|
||||
"The OIDC button should be shown.")
|
||||
// Then the view state should be updated with the homeserver and show the OAuth button.
|
||||
#expect(context.viewState.loginMode.supportsOAuthFlow,
|
||||
"The OAuth button should be shown.")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -147,7 +147,7 @@ struct QRCodeLoginScreenViewModelTests {
|
||||
try await deferred.fulfill()
|
||||
|
||||
var deferredAction = deferFulfillment(viewModel.actionsPublisher) { action in
|
||||
guard case .requestOIDCAuthorisation = action else { return false }
|
||||
guard case .requestOAuthAuthorisation = action else { return false }
|
||||
return true
|
||||
}
|
||||
linkDesktopProgressSubject.send(.waitingForAuthorisation(verificationURL: .homeDirectory))
|
||||
@@ -183,7 +183,7 @@ struct QRCodeLoginScreenViewModelTests {
|
||||
try await deferredState.fulfill()
|
||||
|
||||
var deferredAction = deferFulfillment(viewModel.actionsPublisher) { action in
|
||||
guard case .requestOIDCAuthorisation = action else { return false }
|
||||
guard case .requestOAuthAuthorisation = action else { return false }
|
||||
return true
|
||||
}
|
||||
linkMobileProgressSubject.send(.waitingForAuthorisation(verificationURL: .homeDirectory))
|
||||
|
||||
@@ -21,7 +21,7 @@ struct ServerConfirmationScreenViewStateTests {
|
||||
authenticationFlow: .login)
|
||||
#expect(elementDotIoLogin.message == L10n.screenServerConfirmationMessageLoginElementDotIo, "element.io should have a custom message.")
|
||||
|
||||
let otherLogin = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOIDC.address),
|
||||
let otherLogin = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOAuth.address),
|
||||
authenticationFlow: .login)
|
||||
#expect(otherLogin.message == "", "Other servers should not show a message.")
|
||||
|
||||
@@ -36,8 +36,8 @@ struct ServerConfirmationScreenViewStateTests {
|
||||
authenticationFlow: .register)
|
||||
#expect(matrixDotOrgRegister.message == L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
|
||||
|
||||
let oidcRegister = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOIDC.address),
|
||||
authenticationFlow: .register)
|
||||
#expect(oidcRegister.message == L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
|
||||
let oAuthRegister = ServerConfirmationScreenViewState(mode: .confirmation(LoginHomeserver.mockOAuth.address),
|
||||
authenticationFlow: .register)
|
||||
#expect(oAuthRegister.message == L10n.screenServerConfirmationMessageRegister, "The registration message should always be the same.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
// When continuing from the confirmation screen.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -54,7 +54,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
|
||||
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
|
||||
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -65,13 +65,13 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
Issue.record("The configuration should succeed.")
|
||||
return
|
||||
}
|
||||
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
|
||||
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
|
||||
#expect(context.viewState.mode == .confirmation(service.homeserver.value.address))
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
// When continuing from the confirmation screen.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -91,7 +91,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
// When continuing from the confirmation screen.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -100,7 +100,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
|
||||
// The create prompt is broken: https://github.com/element-hq/matrix-authentication-service/issues/3429
|
||||
// #expect(client.urlForOauthOauthConfigurationPromptReceivedArguments?.prompt == .create)
|
||||
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
|
||||
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,13 +111,13 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
Issue.record("The configuration should succeed.")
|
||||
return
|
||||
}
|
||||
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
|
||||
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
|
||||
#expect(context.viewState.mode == .confirmation(service.homeserver.value.address))
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
// When continuing from the confirmation screen.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -130,8 +130,8 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
|
||||
@Test
|
||||
func confirmPasswordLoginWithoutConfiguration() async throws {
|
||||
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OIDC).
|
||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false)
|
||||
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OAuth).
|
||||
setupViewModel(authenticationFlow: .login, supportsOAuth: false)
|
||||
#expect(service.homeserver.value.loginMode == .unknown)
|
||||
#expect(context.viewState.mode == .confirmation(service.homeserver.value.address))
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
|
||||
@@ -142,7 +142,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then a call to configure service should be made, but not for the OIDC URL.
|
||||
// Then a call to configure service should be made, but not for the OAuth URL.
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
#expect(service.homeserver.value.loginMode == .password)
|
||||
@@ -151,7 +151,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
@Test
|
||||
func confirmPasswordLoginAfterConfiguration() async throws {
|
||||
// Given a view model for login using a service that has already been configured (via the server selection screen).
|
||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false)
|
||||
setupViewModel(authenticationFlow: .login, supportsOAuth: false)
|
||||
guard case .success = await service.configure(for: viewModel.state.homeserverAddress, flow: .login) else {
|
||||
Issue.record("The configuration should succeed.")
|
||||
return
|
||||
@@ -166,7 +166,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
|
||||
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OAuth URL.
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
}
|
||||
@@ -175,7 +175,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
func registrationNotSupportedAlert() async throws {
|
||||
// Given a view model for registration using a service that hasn't been configured and the default server doesn't support registration.
|
||||
// Note: We don't currently take the create prompt into account when determining registration support.
|
||||
setupViewModel(authenticationFlow: .register, supportsOIDC: false, supportsOIDCCreatePrompt: false)
|
||||
setupViewModel(authenticationFlow: .register, supportsOAuth: false, supportsOAuthCreatePrompt: false)
|
||||
#expect(service.homeserver.value.loginMode == .unknown)
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
|
||||
#expect(context.alertInfo == nil)
|
||||
@@ -193,7 +193,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
@Test
|
||||
func loginNotSupportedAlert() async throws {
|
||||
// Given a view model for login using a service that hasn't been configured and the default server doesn't support login.
|
||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false, supportsOIDCCreatePrompt: false, supportsPasswordLogin: false)
|
||||
setupViewModel(authenticationFlow: .login, supportsOAuth: false, supportsOAuthCreatePrompt: false, supportsPasswordLogin: false)
|
||||
#expect(service.homeserver.value.loginMode == .unknown)
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
|
||||
#expect(context.alertInfo == nil)
|
||||
@@ -211,7 +211,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
@Test
|
||||
func elementProRequired() async throws {
|
||||
// Given a view model for login using a service that hasn't been configured and the default server requires Element Pro.
|
||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false, supportsOIDCCreatePrompt: false, supportsPasswordLogin: false, requiresElementPro: true)
|
||||
setupViewModel(authenticationFlow: .login, supportsOAuth: false, supportsOAuthCreatePrompt: false, supportsPasswordLogin: false, requiresElementPro: true)
|
||||
#expect(service.homeserver.value.loginMode == .unknown)
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
|
||||
#expect(context.alertInfo == nil)
|
||||
@@ -238,7 +238,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
// When continuing from the confirmation screen.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -246,7 +246,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesReceivedArguments?.prompt == .consent)
|
||||
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
|
||||
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -257,13 +257,13 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
Issue.record("The configuration should succeed.")
|
||||
return
|
||||
}
|
||||
#expect(service.homeserver.value.loginMode == .oidc(supportsCreatePrompt: true))
|
||||
#expect(service.homeserver.value.loginMode == .oAuth(supportsCreatePrompt: true))
|
||||
#expect(context.viewState.mode == .picker(appSettings.accountProviders))
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
|
||||
// When continuing from the confirmation screen.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOIDC }
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isContinueWithOAuth }
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -275,8 +275,8 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
|
||||
@Test
|
||||
func pickerForPasswordLoginWithoutConfiguration() async throws {
|
||||
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OIDC).
|
||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false, restrictedFlow: true)
|
||||
// Given a view model for login using a service that hasn't been configured (against a server that doesn't support OAuth).
|
||||
setupViewModel(authenticationFlow: .login, supportsOAuth: false, restrictedFlow: true)
|
||||
#expect(service.homeserver.value.loginMode == .unknown)
|
||||
#expect(context.viewState.mode == .picker(appSettings.accountProviders))
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 0)
|
||||
@@ -287,7 +287,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then a call to configure service should be made, but not for the OIDC URL.
|
||||
// Then a call to configure service should be made, but not for the OAuth URL.
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
#expect(service.homeserver.value.loginMode == .password)
|
||||
@@ -296,7 +296,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
@Test
|
||||
func pickerForPasswordLoginAfterConfiguration() async throws {
|
||||
// Given a view model for login using a service that has already been configured (via the server selection screen).
|
||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false, restrictedFlow: true)
|
||||
setupViewModel(authenticationFlow: .login, supportsOAuth: false, restrictedFlow: true)
|
||||
guard case .success = await service.configure(for: appSettings.accountProviders[0], flow: .login) else {
|
||||
Issue.record("The configuration should succeed.")
|
||||
return
|
||||
@@ -311,7 +311,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
context.send(viewAction: .confirm)
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
|
||||
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OAuth URL.
|
||||
#expect(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount == 1)
|
||||
#expect(client.urlForOauthOauthConfigurationPromptLoginHintDeviceIdAdditionalScopesCallsCount == 0)
|
||||
}
|
||||
@@ -319,8 +319,8 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
// MARK: - Helpers
|
||||
|
||||
private func setupViewModel(authenticationFlow: AuthenticationFlow,
|
||||
supportsOIDC: Bool = true,
|
||||
supportsOIDCCreatePrompt: Bool = true,
|
||||
supportsOAuth: Bool = true,
|
||||
supportsOAuthCreatePrompt: Bool = true,
|
||||
supportsPasswordLogin: Bool = true,
|
||||
restrictedFlow: Bool = false,
|
||||
requiresElementPro: Bool = false) {
|
||||
@@ -330,7 +330,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
allowOtherAccountProviders: false,
|
||||
hideBrandChrome: false,
|
||||
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
|
||||
oidcRedirectURL: appSettings.oidcRedirectURL,
|
||||
oAuthRedirectURL: appSettings.oAuthRedirectURL,
|
||||
websiteURL: appSettings.websiteURL,
|
||||
logoURL: appSettings.logoURL,
|
||||
copyrightURL: appSettings.copyrightURL,
|
||||
@@ -350,8 +350,8 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
}
|
||||
|
||||
// Manually create a configuration as the default homeserver address setting is immutable.
|
||||
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.matrix.org/authorize" : nil,
|
||||
supportsOIDCCreatePrompt: supportsOIDCCreatePrompt,
|
||||
client = ClientSDKMock(configuration: .init(oAuthLoginURL: supportsOAuth ? "https://account.matrix.org/authorize" : nil,
|
||||
supportsOAuthCreatePrompt: supportsOAuthCreatePrompt,
|
||||
supportsPasswordLogin: supportsPasswordLogin,
|
||||
elementWellKnown: requiresElementPro ? "{\"version\":1,\"enforce_element_pro\":true}" : nil))
|
||||
let configuration = AuthenticationClientFactoryMock.Configuration(homeserverClients: ["matrix.org": client])
|
||||
@@ -370,7 +370,7 @@ final class ServerConfirmationScreenViewModelTests {
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
// Add a fake window in order for the OIDC flow to continue
|
||||
// Add a fake window in order for the OAuth flow to continue
|
||||
viewModel.context.send(viewAction: .updateWindow(UIWindow()))
|
||||
}
|
||||
}
|
||||
@@ -387,9 +387,9 @@ private extension ServerConfirmationScreenViewState {
|
||||
}
|
||||
|
||||
private extension ServerConfirmationScreenViewModelAction {
|
||||
var isContinueWithOIDC: Bool {
|
||||
var isContinueWithOAuth: Bool {
|
||||
switch self {
|
||||
case .continueWithOIDC: true
|
||||
case .continueWithOAuth: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ struct SoftLogoutScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func initialStateForOIDC() {
|
||||
func initialStateForOAuth() {
|
||||
let viewModel = SoftLogoutScreenViewModel(credentials: credentials,
|
||||
homeserver: .mockMatrixDotOrg,
|
||||
keyBackupNeeded: false)
|
||||
@@ -54,7 +54,7 @@ struct SoftLogoutScreenViewModelTests {
|
||||
// Given a view model where the user hasn't yet sent the verification email.
|
||||
#expect(context.password.isEmpty, "The view model should start with an empty password.")
|
||||
#expect(!context.viewState.canSubmit, "The view model should start with an invalid password.")
|
||||
#expect(context.viewState.loginMode.supportsOIDCFlow, "The view model should show OIDC button for the given homeserver.")
|
||||
#expect(context.viewState.loginMode.supportsOAuthFlow, "The view model should show OAuth button for the given homeserver.")
|
||||
#expect(!context.viewState.showRecoverEncryptionKeysMessage, "The view model should not show recover encryption keys message.")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user