Skip to content

Commit 2d6fa27

Browse files
committed
Merge branch 'feat/T3' of github.com:demolaf/FirebaseUI-Android into feat/P2
2 parents 5bd8c7c + 45b6a40 commit 2d6fa27

File tree

9 files changed

+518
-71
lines changed

9 files changed

+518
-71
lines changed

auth/build.gradle.kts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
id("com.android.library")
55
id("com.vanniktech.maven.publish")
66
id("org.jetbrains.kotlin.android")
7-
alias(libs.plugins.compose.compiler)
7+
id("org.jetbrains.kotlin.plugin.compose") version Config.kotlinVersion
88
}
99

1010
android {
@@ -74,24 +74,24 @@ android {
7474
}
7575

7676
dependencies {
77-
implementation(platform(libs.androidx.compose.bom))
78-
implementation(libs.androidx.compose.ui)
79-
implementation(libs.androidx.compose.ui.graphics)
80-
implementation(libs.androidx.compose.material3)
81-
implementation(libs.androidx.compose.foundation)
82-
implementation(libs.androidx.compose.ui.tooling)
83-
implementation(libs.androidx.compose.ui.tooling.preview)
84-
implementation(libs.androidx.activity.compose)
77+
implementation(platform(Config.Libs.Androidx.Compose.bom))
78+
implementation(Config.Libs.Androidx.Compose.ui)
79+
implementation(Config.Libs.Androidx.Compose.uiGraphics)
80+
implementation(Config.Libs.Androidx.Compose.material3)
81+
implementation(Config.Libs.Androidx.Compose.foundation)
82+
implementation(Config.Libs.Androidx.Compose.tooling)
83+
implementation(Config.Libs.Androidx.Compose.toolingPreview)
84+
implementation(Config.Libs.Androidx.Compose.activityCompose)
8585
implementation(Config.Libs.Androidx.materialDesign)
8686
implementation(Config.Libs.Androidx.activity)
87-
implementation(libs.androidx.compose.material.icons.extended)
88-
implementation(libs.androidx.datastore.preferences)
87+
implementation(Config.Libs.Androidx.Compose.materialIconsExtended)
88+
implementation(Config.Libs.Androidx.datastorePreferences)
8989
// The new activity result APIs force us to include Fragment 1.3.0
9090
// See https://issuetracker.google.com/issues/152554847
9191
implementation(Config.Libs.Androidx.fragment)
9292
implementation(Config.Libs.Androidx.customTabs)
9393
implementation(Config.Libs.Androidx.constraint)
94-
implementation(libs.androidx.credentials)
94+
implementation(Config.Libs.Androidx.credentials)
9595
implementation("androidx.credentials:credentials-play-services-auth:1.3.0")
9696

9797
implementation(Config.Libs.Androidx.lifecycleExtensions)
@@ -116,19 +116,19 @@ dependencies {
116116
testImplementation(Config.Libs.Test.robolectric)
117117
testImplementation(Config.Libs.Test.kotlinReflect)
118118
testImplementation(Config.Libs.Provider.facebook)
119-
testImplementation(libs.androidx.ui.test.junit4)
120-
testImplementation(libs.mockito)
121-
testImplementation(libs.mockito.inline)
122-
testImplementation(libs.mockito.kotlin)
123-
testImplementation(libs.androidx.credentials)
119+
testImplementation(Config.Libs.Test.composeUiTestJunit4)
120+
testImplementation(Config.Libs.Test.mockitoCore)
121+
testImplementation(Config.Libs.Test.mockitoInline)
122+
testImplementation(Config.Libs.Test.mockitoKotlin)
123+
testImplementation(Config.Libs.Androidx.credentials)
124124

125125
debugImplementation(project(":internal:lintchecks"))
126126
}
127127

128128
val mockitoAgent by configurations.creating
129129

130130
dependencies {
131-
mockitoAgent(libs.mockito) {
131+
mockitoAgent(Config.Libs.Test.mockitoCore) {
132132
isTransitive = false
133133
}
134134
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2025 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
15+
package com.firebase.ui.auth.compose.configuration
16+
17+
/**
18+
* Configuration class for Multi-Factor Authentication (MFA) enrollment and verification behavior.
19+
*
20+
* This class controls which MFA factors are available to users, whether enrollment is mandatory,
21+
* and whether recovery codes are generated.
22+
*
23+
* @property allowedFactors List of MFA factors that users are permitted to enroll in.
24+
* Defaults to [MfaFactor.Sms, MfaFactor.Totp].
25+
* @property requireEnrollment Whether MFA enrollment is mandatory for all users.
26+
* When true, users must enroll in at least one MFA factor.
27+
* Defaults to false.
28+
* @property enableRecoveryCodes Whether to generate and provide recovery codes to users
29+
* after successful MFA enrollment. These codes can be used
30+
* as a backup authentication method. Defaults to true.
31+
*/
32+
class MfaConfiguration(
33+
val allowedFactors: List<MfaFactor> = listOf(MfaFactor.Sms, MfaFactor.Totp),
34+
val requireEnrollment: Boolean = false,
35+
val enableRecoveryCodes: Boolean = true
36+
) {
37+
init {
38+
require(allowedFactors.isNotEmpty()) {
39+
"At least one MFA factor must be allowed"
40+
}
41+
}
42+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2025 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
15+
package com.firebase.ui.auth.compose.configuration
16+
17+
/**
18+
* Represents the different Multi-Factor Authentication (MFA) factors that can be used
19+
* for enrollment and verification.
20+
*/
21+
enum class MfaFactor {
22+
/**
23+
* SMS-based authentication factor.
24+
* Users receive a verification code via text message to their registered phone number.
25+
*/
26+
Sms,
27+
28+
/**
29+
* Time-based One-Time Password (TOTP) authentication factor.
30+
* Users generate verification codes using an authenticator app.
31+
*/
32+
Totp
33+
}
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
//package com.firebase.ui.auth.compose.ui.screens.sign_in
2+
//
3+
//import android.content.Intent
4+
//import androidx.compose.foundation.layout.Column
5+
//import androidx.compose.foundation.layout.PaddingValues
6+
//import androidx.compose.foundation.layout.Row
7+
//import androidx.compose.foundation.layout.Spacer
8+
//import androidx.compose.foundation.layout.height
9+
//import androidx.compose.foundation.layout.padding
10+
//import androidx.compose.foundation.layout.safeDrawingPadding
11+
//import androidx.compose.foundation.layout.size
12+
//import androidx.compose.foundation.layout.width
13+
//import androidx.compose.material.icons.Icons
14+
//import androidx.compose.material.icons.filled.Email
15+
//import androidx.compose.material.icons.filled.Lock
16+
//import androidx.compose.material3.Button
17+
//import androidx.compose.material3.CircularProgressIndicator
18+
//import androidx.compose.material3.ExperimentalMaterial3Api
19+
//import androidx.compose.material3.Icon
20+
//import androidx.compose.material3.MaterialTheme
21+
//import androidx.compose.material3.Scaffold
22+
//import androidx.compose.material3.Text
23+
//import androidx.compose.material3.TextButton
24+
//import androidx.compose.material3.TopAppBar
25+
//import androidx.compose.runtime.Composable
26+
//import androidx.compose.runtime.remember
27+
//import androidx.compose.ui.Alignment
28+
//import androidx.compose.ui.Modifier
29+
//import androidx.compose.ui.graphics.Color
30+
//import androidx.compose.ui.platform.LocalContext
31+
//import androidx.compose.ui.text.style.TextAlign
32+
//import androidx.compose.ui.text.style.TextDecoration
33+
//import androidx.compose.ui.tooling.preview.Preview
34+
//import androidx.compose.ui.unit.dp
35+
//import androidx.compose.ui.unit.sp
36+
//import androidx.core.net.toUri
37+
//import com.firebase.ui.auth.compose.configuration.AuthUIConfiguration
38+
//import com.firebase.ui.auth.compose.configuration.authUIConfiguration
39+
//import com.firebase.ui.auth.compose.configuration.auth_provider.AuthProvider
40+
//import com.firebase.ui.auth.compose.configuration.string_provider.DefaultAuthUIStringProvider
41+
//import com.firebase.ui.auth.compose.configuration.theme.AuthUITheme
42+
//import com.firebase.ui.auth.compose.configuration.validators.EmailValidator
43+
//import com.firebase.ui.auth.compose.configuration.validators.PasswordValidator
44+
//import com.firebase.ui.auth.compose.ui.components.AuthTextField
45+
//import com.firebase.ui.auth.compose.ui.screens.SignInUI
46+
//
47+
//@OptIn(ExperimentalMaterial3Api::class)
48+
//@Composable
49+
//fun SignInExistingUserUI(
50+
// modifier: Modifier = Modifier,
51+
// configuration: AuthUIConfiguration,
52+
// provider: AuthProvider.Email,
53+
// email: String,
54+
// password: String,
55+
// isLoading: Boolean,
56+
// onEmailChange: (String) -> Unit,
57+
// onPasswordChange: (String) -> Unit,
58+
// onSignInClick: () -> Unit,
59+
// onGoToSignUp: () -> Unit,
60+
// onGoToResetPassword: () -> Unit,
61+
//) {
62+
// val context = LocalContext.current
63+
// val passwordValidator = remember {
64+
// PasswordValidator(
65+
// stringProvider = DefaultAuthUIStringProvider(context),
66+
// rules = emptyList()
67+
// )
68+
// }
69+
//
70+
// Scaffold(
71+
// modifier = modifier,
72+
// topBar = {
73+
// TopAppBar(
74+
// title = {
75+
// Text("Sign In")
76+
// },
77+
// )
78+
// },
79+
// ) { innerPadding ->
80+
// Column(
81+
// modifier = Modifier
82+
// .padding(innerPadding)
83+
// .safeDrawingPadding()
84+
// .padding(horizontal = 16.dp),
85+
// ) {
86+
// Text(
87+
// "Welcome Back",
88+
// fontSize = 20.sp,
89+
// )
90+
// Text(
91+
// "You've already used $email to sign in. " +
92+
// "Enter the password for that account",
93+
// color = Color.Gray,
94+
// fontSize = 14.sp,
95+
// )
96+
// Spacer(modifier = Modifier.height(24.dp))
97+
// AuthTextField(
98+
// value = password,
99+
// validator = passwordValidator,
100+
// enabled = !isLoading,
101+
// label = {
102+
// Text("Password")
103+
// },
104+
// onValueChange = { text ->
105+
// onPasswordChange(password)
106+
// },
107+
// leadingIcon = {
108+
// Icon(
109+
// imageVector = Icons.Default.Lock,
110+
// contentDescription = ""
111+
// )
112+
// }
113+
// )
114+
// Spacer(modifier = Modifier.height(8.dp))
115+
// TextButton(
116+
// modifier = Modifier
117+
// .align(Alignment.Start),
118+
// onClick = {
119+
// onGoToResetPassword()
120+
// },
121+
// enabled = !isLoading,
122+
// contentPadding = PaddingValues.Zero
123+
// ) {
124+
// Text(
125+
// modifier = modifier,
126+
// text = "Trouble signing in?",
127+
// style = MaterialTheme.typography.bodyMedium,
128+
// textAlign = TextAlign.Center,
129+
// textDecoration = TextDecoration.Underline
130+
// )
131+
// }
132+
// Spacer(modifier = Modifier.height(8.dp))
133+
// Row(
134+
// modifier = Modifier
135+
// .align(Alignment.End),
136+
// ) {
137+
// Button(
138+
// onClick = {
139+
// onSignInClick()
140+
// },
141+
// enabled = !isLoading,
142+
// ) {
143+
// if (isLoading) {
144+
// CircularProgressIndicator(
145+
// modifier = Modifier
146+
// .size(16.dp)
147+
// )
148+
// } else {
149+
// Text("Sign In")
150+
// }
151+
// }
152+
// }
153+
// Spacer(modifier = Modifier.height(16.dp))
154+
// Row(
155+
// modifier = Modifier
156+
// .align(Alignment.End),
157+
// ) {
158+
// TextButton(
159+
// onClick = {
160+
// val intent = Intent(
161+
// Intent.ACTION_VIEW,
162+
// configuration.tosUrl?.toUri()
163+
// )
164+
// context.startActivity(intent)
165+
// },
166+
// contentPadding = PaddingValues.Zero,
167+
// enabled = !isLoading,
168+
// ) {
169+
// Text(
170+
// modifier = modifier,
171+
// text = "Terms of Service",
172+
// style = MaterialTheme.typography.bodyMedium,
173+
// textAlign = TextAlign.Center,
174+
// textDecoration = TextDecoration.Underline
175+
// )
176+
// }
177+
// Spacer(modifier = Modifier.width(24.dp))
178+
// TextButton(
179+
// onClick = {
180+
// val intent = Intent(
181+
// Intent.ACTION_VIEW,
182+
// configuration.privacyPolicyUrl?.toUri()
183+
// )
184+
// context.startActivity(intent)
185+
// },
186+
// contentPadding = PaddingValues.Zero,
187+
// enabled = !isLoading,
188+
// ) {
189+
// Text(
190+
// modifier = modifier,
191+
// text = "Privacy Policy",
192+
// style = MaterialTheme.typography.bodyMedium,
193+
// textAlign = TextAlign.Center,
194+
// textDecoration = TextDecoration.Underline
195+
// )
196+
// }
197+
// }
198+
// }
199+
// }
200+
//}
201+
//
202+
//@Preview
203+
//@Composable
204+
//fun PreviewSignInExistingUserUI() {
205+
// val applicationContext = LocalContext.current
206+
// val provider = AuthProvider.Email(
207+
// isDisplayNameRequired = true,
208+
// isEmailLinkSignInEnabled = false,
209+
// isEmailLinkForceSameDeviceEnabled = true,
210+
// actionCodeSettings = null,
211+
// isNewAccountsAllowed = true,
212+
// minimumPasswordLength = 8,
213+
// passwordValidationRules = listOf()
214+
// )
215+
//
216+
// AuthUITheme {
217+
// SignInExistingUserUI(
218+
// configuration = authUIConfiguration {
219+
// context = applicationContext
220+
// providers { provider(provider) }
221+
// tosUrl = ""
222+
// privacyPolicyUrl = ""
223+
// },
224+
// provider = provider,
225+
// email = "[email protected]",
226+
// password = "",
227+
// isLoading = false,
228+
// onEmailChange = { email -> },
229+
// onPasswordChange = { password -> },
230+
// onSignInClick = {},
231+
// onGoToSignUp = {},
232+
// onGoToResetPassword = {},
233+
// )
234+
// }
235+
//}

0 commit comments

Comments
 (0)