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
1 change: 1 addition & 0 deletions authenticator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
4 changes: 4 additions & 0 deletions authenticator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## [Release 1.0.0-dev-preview.0](https://github.com/aws-amplify/amplify-ui-android/releases/tag/release_authenticator_v1.0.0-dev-preview.0)

### Features
- **authenticator:** Initial Authenticator Dev Preview Release ([#10](https://github.com/aws-amplify/amplify-ui-android/issues/10))
3 changes: 3 additions & 0 deletions authenticator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Authenticator

Amplify Authenticator provides a complete drop-in implementation of an authentication flow for your application using [Amplify Authentication](https://docs.amplify.aws/lib/auth/getting-started/q/platform/android/).
33 changes: 33 additions & 0 deletions authenticator/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply from: rootProject.file("configuration/publishing.gradle")

group = POM_GROUP

android {
namespace 'com.amplifyframework.ui.authenticator'
defaultConfig {
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

publishing {
singleVariant("release") {
withSourcesJar()
}
}
}

dependencies {
api dependency.amplify.auth

implementation dependency.androidx.material
implementation dependency.androidx.uiTooling
implementation dependency.androidx.lifecycle_ktx
implementation dependency.androidx.compose.viewmodel

testImplementation dependency.test.androidx.espresso
testImplementation dependency.test.androidx.junit
testImplementation dependency.test.junit
testImplementation dependency.test.robolectric
testImplementation dependency.test.mockk
}
Empty file.
20 changes: 20 additions & 0 deletions authenticator/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/apache2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.
#

POM_ARTIFACT_ID=authenticator
POM_NAME=Amplify UI Framework for Android - Authenticator
POM_DESCRIPTION=Amplify UI Framework for Android - Authenticator Plugin
POM_PACKAGING=aar
VERSION_NAME=1.0.0-dev-preview.0
21 changes: 21 additions & 0 deletions authenticator/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
17 changes: 17 additions & 0 deletions authenticator/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License").
~ You may not use this file except in compliance with the License.
~ A copy of the License is located at
~
~ http://aws.amazon.com/apache2.0
~
~ or in the "license" file accompanying this file. This file is distributed
~ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
~ express or implied. See the License for the specific language governing
~ permissions and limitations under the License.
-->

<manifest />
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amplifyframework.ui.authenticator

import com.amplifyframework.ui.authenticator.enums.AuthenticatorInitialStep
import com.amplifyframework.ui.authenticator.forms.SignUpFormBuilder

internal data class AuthenticatorConfiguration(
val initialStep: AuthenticatorInitialStep,
val signUpForm: SignUpFormBuilder.() -> Unit
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amplifyframework.ui.authenticator

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import com.amplifyframework.auth.AuthCodeDeliveryDetails
import com.amplifyframework.auth.AuthException
import com.amplifyframework.auth.AuthUser
import com.amplifyframework.auth.AuthUserAttribute
import com.amplifyframework.auth.result.AuthSignOutResult
import com.amplifyframework.ui.authenticator.enums.AuthenticatorInitialStep
import com.amplifyframework.ui.authenticator.enums.AuthenticatorStep
import com.amplifyframework.ui.authenticator.forms.MutableFormState

/**
* A Screen State is a state holder for the UI for a specific [AuthenticatorStep].
*/
@Stable
interface AuthenticatorScreenState {
val step: AuthenticatorStep
}

/**
* The Authenticator is loading the current state of the user's Auth session.
*/
@Immutable
object LoadingState : AuthenticatorScreenState {
override val step = AuthenticatorStep.Loading
}

/**
* The Authenticator has encountered an unrecoverable error.
* @param error The error that occurred.
*/
@Immutable
data class ErrorState(val error: AuthException) : AuthenticatorScreenState {
override val step = AuthenticatorStep.Error
}

/**
* The user has completed the sign in process.
*/
@Immutable
interface SignedInState : AuthenticatorScreenState {
/**
* The [AuthUser] instance for the signed in user.
*/
val user: AuthUser

/**
* Sign out the current user. This does a local sign out and returns the [AuthSignOutResult] that
* may be inspected to determine if any parts of the sign out were unsuccessful.
*/
suspend fun signOut(): AuthSignOutResult
}

/**
* An [AuthenticatorScreenState] for a part of UI that contains an input form.
*/
@Stable
interface FormHolderState : AuthenticatorScreenState {
val form: MutableFormState
}

/**
* The user is on the Sign In step. They can enter their Sign In information to authenticate with Amplify.
*/
@Stable
interface SignInState : FormHolderState {
fun moveTo(step: AuthenticatorInitialStep)
suspend fun signIn()
}

/**
* The user has completed the initial Sign In step, and needs to enter the confirmation code from an MFA
* message to complete the sign in process.
*/
@Stable
interface SignInConfirmMfaState : FormHolderState {
val deliveryDetails: AuthCodeDeliveryDetails?
fun moveTo(step: AuthenticatorInitialStep)
suspend fun confirmSignIn()
}

/**
* The user has completed the initial Sign In step, and needs to enter the confirmation code from a custom
* challenge to complete the sign in process.
*/
@Stable
interface SignInConfirmCustomState : FormHolderState {
val additionalInfo: Map<String, String>
val deliveryDetails: AuthCodeDeliveryDetails?
fun moveTo(step: AuthenticatorInitialStep)
suspend fun confirmSignIn()
}

/**
* The user has completed the initial Sign In step, and is required to change their password in order to complete
* the sign in process.
*/
@Stable
interface SignInConfirmNewPasswordState : FormHolderState {
fun moveTo(step: AuthenticatorInitialStep)
suspend fun confirmSignIn()
}

/**
* The user is on the Sign Up step, and can fill out the account creation form to Sign Up.
*/
@Stable
interface SignUpState : FormHolderState {
fun moveTo(step: AuthenticatorInitialStep)
suspend fun signUp()
}

/**
* The user has signed up, but needs to enter a confirmation code sent to them.
*/
@Stable
interface SignUpConfirmState : FormHolderState {
val deliveryDetails: AuthCodeDeliveryDetails?
fun moveTo(step: AuthenticatorInitialStep)
suspend fun confirmSignUp()
suspend fun resendCode()
}

/**
* The user is on the Password Reset step. They can enter their username to begin the password reset.
*/
@Stable
interface PasswordResetState : FormHolderState {
fun moveTo(step: AuthenticatorInitialStep)
suspend fun submitPasswordReset()
}

/**
* The user has entered their username and been sent a confirmation code. The need to enter the code and their new
* password to complete the password reset.
*/
@Stable
interface PasswordResetConfirmState : FormHolderState {
val deliveryDetails: AuthCodeDeliveryDetails?
fun moveTo(step: AuthenticatorInitialStep)
suspend fun submitPasswordResetConfirm()
}

/**
* The user has successfully signed in and their account is confirmed, however they do not have any means of account recovery (email, phone) that is confirmed.
*/
@Stable
interface VerifyUserState : FormHolderState {
/**
* The list of unverified attributes.
*/
val attributes: List<AuthUserAttribute>

/**
* Submit the selected attribute to initiate the attribute verification.
*/
suspend fun verifyUser()

/**
* Skip verification and move to the Signed In state
*/
fun skip()
}

/**
* The user has initiated verification of an account recovery mechanism (email, phone) and needs to provide a confirmation code.
*/
@Stable
interface VerifyUserConfirmState : FormHolderState {
/**
* The details of where the verification code was sent.
*/
val deliveryDetails: AuthCodeDeliveryDetails?

/**
* Submit the entered confirmation code to confirm the verification.
*/
suspend fun confirmVerifyUser()

/**
* Re-send the verification code.
*/
suspend fun resendCode()

/**
* Skip verification and move to the Signed In state
*/
fun skip()
}
Loading