Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/detekt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Detekt

on:
merge_group:
workflow_dispatch:
push:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
detekt:
name: Detekt
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup build environment
uses: ./.github/actions/setup

- name: Run Detekt
run: ./gradlew detekt --continue --console=plain --no-daemon
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ configure(project(':universal_components')) {
detekt {
buildUponDefaultConfig = true
parallel = true
config.setFrom(files("$rootDir/config/detekt/detekt.yml"))
source.setFrom(files('src/main/java', 'src/main/kotlin', 'src/test/java', 'src/test/kotlin'))
}

Expand Down
9 changes: 9 additions & 0 deletions config/detekt/detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ formatting:
active: true
NoWildcardImports:
active: true
# authenticator_methods package is public API; renaming would break consumers.
PackageName:
active: true
excludes: [ '**/mfa/authenticator_methods/**' ]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmathew92 this will be removed in upcoming PR where i am solving the component visibility issue


complexity:
active: true
Expand Down Expand Up @@ -65,6 +69,11 @@ naming:
TopLevelPropertyNaming:
active: true
constantPattern: '[A-Z][_A-Z0-9]*'
# The authenticator_methods package is part of the published public API.
# Renaming it to drop the underscore would be a breaking change for consumers.
PackageNaming:
active: true
excludes: [ '**/mfa/authenticator_methods/**' ]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmathew92 this will be removed in upcoming PR where i am solving the component visibility issue


style:
active: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import java.util.concurrent.atomic.AtomicBoolean
/**
* Configuration for managing passkey authentication.
*
* @param credentialManager User application's existing [CredentialManager] instance. Pass the same instance you use elsewhere in the app to handle passkey operations consistently.
* @param credentialManager User application's existing [CredentialManager] instance. Pass the
* same instance you use elsewhere in the app to handle passkey operations consistently.
* @param connection The Auth0 DB connection name to use for passkey enrollment and authentication.
* @param userIdentity Unique identifier of the current user's identity. Needed if the user logged in with a [linked account](https://auth0.com/docs/manage-users/user-accounts/user-account-linking)
* @param userIdentity Unique identifier of the current user's identity. Needed if the user
* logged in with a [linked account](https://auth0.com/docs/manage-users/user-accounts/user-account-linking)
*/
data class PasskeyConfiguration(
val credentialManager: CredentialManager? = null,
Expand Down Expand Up @@ -80,7 +82,7 @@ public object Auth0UniversalComponents {

private fun assertInitialized() {
if (!initialized.get()) {
throw IllegalStateException("Auth0UniversalComponents must be initialized first.")
error("Auth0UniversalComponents must be initialized first.")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.auth0.universalcomponents.BuildConfig
/**
* Provider class that creates and provides instances of MyAccount from the Auth0 Android SDK.
*/
class MyAccountProvider() {
class MyAccountProvider {

/**
* Creates and returns a MyAccountAPIClient instance configured with the current access token.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import com.auth0.universalcomponents.domain.error.Auth0Error

internal object ErrorMapper {

private const val HTTP_STATUS_SERVER_ERROR = 500

/**
* Maps any exception to an Auth0Error
* Handles AuthenticationException, MyAccountException, and other exceptions
Expand Down Expand Up @@ -150,7 +152,7 @@ internal object ErrorMapper {
)
}

exception.statusCode >= 500 -> Auth0Error.ServerError(
exception.statusCode >= HTTP_STATUS_SERVER_ERROR -> Auth0Error.ServerError(
message = "Server error, please try again later",
statusCode = exception.statusCode,
cause = exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import kotlin.coroutines.cancellation.CancellationException
* @throws [CancellationException] if the coroutine is cancelled
* @throws [com.auth0.universalcomponents.domain.error.Auth0Error]
*/
// Intentionally catches all throwables to map them to Auth0Error; CancellationException is rethrown first.
@Suppress("TooGenericExceptionCaught")
internal suspend inline fun <reified T> withErrorMapping(
scope: String? = null,
execute: suspend () -> T
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.auth0.universalcomponents.presentation.navigation

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
Expand All @@ -15,10 +16,12 @@ import com.auth0.universalcomponents.presentation.ui.passkeys.PasskeyEnableScree
@Composable
internal fun AuthenticatorSettingsNavigationHost(
navController: NavHostController,
modifier: Modifier = Modifier,
) {
NavHost(
navController = navController,
startDestination = AuthenticatorRoute.AuthenticatorMethodList
startDestination = AuthenticatorRoute.AuthenticatorMethodList,
modifier = modifier
) {
composable<AuthenticatorRoute.AuthenticatorMethodList> {
AuthenticatorMethodsScreen(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public fun SnackBar(

SnackbarHost(
hostState = snackbarHostState,
modifier = Modifier
modifier = modifier
.padding(sizes.padding)
)

LaunchedEffect(Unit) {
snackbarHostState.showSnackbar("Copied to clipboard")
LaunchedEffect(message) {
snackbarHostState.showSnackbar(message)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.auth0.universalcomponents.presentation.ui.menu

// TODO: Move this to the correct package based on usage

sealed interface MenuAction {
object Remove : MenuAction
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public fun AuthenticatorSettingsComponent(

Auth0Theme(configuration = themeConfiguration) {
AuthenticatorSettingsNavigationHost(
navController
navController = navController,
modifier = modifier
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.auth0.universalcomponents.presentation.ui.mfa

import android.graphics.Bitmap
import android.util.Log
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
Expand Down Expand Up @@ -70,6 +71,7 @@ import com.auth0.universalcomponents.presentation.viewmodel.EnrollmentUiState
import com.auth0.universalcomponents.presentation.viewmodel.EnrollmentViewModel
import com.auth0.universalcomponents.theme.Auth0Theme
import com.google.zxing.BarcodeFormat
import com.google.zxing.WriterException
import com.google.zxing.qrcode.QRCodeWriter

@Composable
Expand Down Expand Up @@ -529,22 +531,33 @@ private fun generateQRCode(
return try {
val writer = QRCodeWriter()
val bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, size, size)
val width = bitMatrix.width
val height = bitMatrix.height
val bitmap = createBitmap(width, height)

for (x in 0 until width) {
for (y in 0 until height) {
bitmap[x, y] = if (bitMatrix[x, y]) {
qrCodeColor.toArgb()
} else {
qrBackgroundColor.toArgb()
}
createQRBitmap(bitMatrix, qrCodeColor, qrBackgroundColor)
} catch (e: WriterException) {
Log.e("TAG", "Failed to generate QR code", e)
null
}
}

/**
* Creates a bitmap from a QR code bit matrix with specified colors.
*/
private fun createQRBitmap(
bitMatrix: com.google.zxing.common.BitMatrix,
qrCodeColor: Color,
qrBackgroundColor: Color
): Bitmap {
val width = bitMatrix.width
val height = bitMatrix.height
val bitmap = createBitmap(width, height)

for (x in 0 until width) {
for (y in 0 until height) {
bitmap[x, y] = if (bitMatrix[x, y]) {
qrCodeColor.toArgb()
} else {
qrBackgroundColor.toArgb()
}
}
bitmap
} catch (e: Exception) {
e.printStackTrace()
null
}
return bitmap
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class PasskeyViewModel(
_uiState.update {
PasskeyUiState.EnrollingPasskey
}
val result = myAccountRepository.verifyPasskey(
myAccountRepository.verifyPasskey(
publicKeyCredentials,
challenge,
SCOPE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ data class Auth0Typography(

// Other styles

/** Helper text for hints, validation messages, and supplementary information. Inter Regular 13sp / 18sp line height / 0.2sp tracking. */
/** Helper text for hints, validation messages, and supplementary information.
* Inter Regular 13sp / 18sp line height / 0.2sp tracking. */
val helper: TextStyle,
/** Overline text for tags, categories, and small annotations. Inter Regular 11sp / 16sp line height / 0.77sp tracking. */
/** Overline text for tags, categories, and small annotations.
* Inter Regular 11sp / 16sp line height / 0.77sp tracking. */
val overline: TextStyle,
) {
companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ suspend fun createCredential(
val request = CreatePublicKeyCredentialRequest(authParamsJson)
val response = credentialsManager.createCredential(context, request)
val publicKeyResponse = response as? CreatePublicKeyCredentialResponse
?: throw IllegalStateException("Unexpected credential response type: ${response::class.java.name}")
?: error("Unexpected credential response type: ${response::class.java.name}")
return publicKeyResponse.registrationResponseJson
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ package com.auth0.universalcomponents.utils

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException

object DateUtil {

private const val ISO_DATE_PREFIX_LENGTH = 10

/**
* Formats ISO8601 date string to M/dd/yy format
*/
fun formatIsoDate(isoDate: String): String {
return try {
val dateTime = LocalDateTime.parse(isoDate, DateTimeFormatter.ISO_DATE_TIME)
dateTime.format(DateTimeFormatter.ofPattern("M/dd/yy"))
} catch (e: Exception) {
isoDate.take(10)
} catch (e: DateTimeParseException) {
isoDate.take(ISO_DATE_PREFIX_LENGTH)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import android.util.Patterns
*/
object ValidationUtil {

private const val MIN_PHONE_NUMBER_LENGTH = 6

/**
* Validates if an email address is in a valid format
* Uses Android's built-in email pattern matcher
Expand All @@ -27,7 +29,7 @@ object ValidationUtil {
*/
fun isValidPhoneNumber(phoneNumber: String): Boolean {
val digitsOnly = phoneNumber.replace(Regex("[^0-9]"), "")
return digitsOnly.length >= 6
return digitsOnly.length >= MIN_PHONE_NUMBER_LENGTH
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.auth0.universalcomponents

import org.junit.Assert.*
import org.junit.Assert.assertEquals
import org.junit.Test

/**
Expand Down
Loading