Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import HideSignupSwift from './hidesignup.swift.mdx';
import HideSignupWeb from './hidesignup.web.mdx';
import TotpSwift from './totpIssuer.swift.mdx';
import TotpAndroid from './totpIssuer.android.mdx';
import PasswordlessSwift from './passwordless.swift.mdx';
import PasswordlessAndroid from './passwordless.android.mdx';

export async function getStaticPaths() {
return getCustomStaticPath(frontmatter.supportedFrameworks);
Expand Down Expand Up @@ -72,6 +74,8 @@ By default, unauthenticated users are redirected to the Sign In flow. You can ex
</InlineFilter>
<InlineFilter filters={['android']}>
<LoginAndroid />

<PasswordlessAndroid />
</InlineFilter>
<InlineFilter filters={['flutter']}>
<LoginFlutter />
Expand All @@ -81,6 +85,8 @@ By default, unauthenticated users are redirected to the Sign In flow. You can ex
</InlineFilter>
<InlineFilter filters={['swift']}>
<LoginSwift />

<PasswordlessSwift />
</InlineFilter>

## Sign Up Attributes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Alert } from '@aws-amplify/ui-react';

### Passwordless Authentication

<Alert role="none" variation="info" heading="Platform Requirements">
Passkey support requires Android API level 28+ with Google Play Services.
</Alert>

#### Backend Configuration

For backend setup including Email OTP, SMS OTP, and WebAuthn (Passkey) configuration, see the [Passwordless documentation](https://docs.amplify.aws/android/build-a-backend/auth/concepts/passwordless/).

#### Authentication Flows

The Authenticator supports two authentication flows:

**Password Flow (Default)**

Traditional password-based authentication:

```kotlin
Authenticator(
authenticationFlow = AuthenticationFlow.Password
) { state ->
Text("Welcome!")
}
```

**User Choice Flow**

Allows users to choose from available authentication methods:

```kotlin
Authenticator(
authenticationFlow = AuthenticationFlow.UserChoice()
) { state ->
Text("Welcome!")
}
```

#### Available Authentication Factors

| Factor | Description | Code |
|--------|-------------|------|
| Password | Traditional password with SRP | `AuthFactor.Password(srp = true)` |
| Password (no SRP) | Password without SRP | `AuthFactor.Password(srp = false)` |
| Email OTP | One-time code via email | `AuthFactor.EmailOtp` |
| SMS OTP | One-time code via SMS | `AuthFactor.SmsOtp` |
| WebAuthn (Passkey) | Biometric/security key authentication | `AuthFactor.WebAuthn` |

#### Preferred Auth Factor

Skip the factor selection step by specifying a preferred factor:

```kotlin
Authenticator(
authenticationFlow = AuthenticationFlow.UserChoice(
preferredAuthFactor = AuthFactor.WebAuthn
)
) { state ->
Text("Welcome!")
}
```

When a preferred factor is set:
- If the user has that factor available, they'll use it directly
- If not available, they'll see the factor selection screen

#### Passkey Prompts

Control when users are prompted to create a passkey:

```kotlin
Authenticator(
authenticationFlow = AuthenticationFlow.UserChoice(
passkeyPrompts = PasskeyPrompts(
afterSignUp = PasskeyPrompt.Always, // Prompt after sign-up
afterSignIn = PasskeyPrompt.Never // Don't prompt after sign-in
)
)
) { state ->
Text("Welcome!")
}
```

**PasskeyPrompt Options:**
- `PasskeyPrompt.Always` - Always prompt to create a passkey (if user doesn't have one)
- `PasskeyPrompt.Never` - Never prompt to create a passkey

#### Authentication Flow Steps

When using `UserChoice` flow, users may encounter these additional steps:

1. **SignInSelectAuthFactor** - User selects their preferred authentication method
2. **SignInConfirmPassword** - User enters password (if password factor selected)
3. **PromptToCreatePasskey** - User is prompted to create a passkey
4. **PasskeyCreated** - Confirmation after successful passkey creation

#### Complete Example

```kotlin
Authenticator(
authenticationFlow = AuthenticationFlow.UserChoice(
preferredAuthFactor = AuthFactor.WebAuthn,
passkeyPrompts = PasskeyPrompts(
afterSignUp = PasskeyPrompt.Always,
afterSignIn = PasskeyPrompt.Always
)
)
) { state ->
Text("Welcome ${state.user.username}!")
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Alert } from '@aws-amplify/ui-react';

### Passwordless Authentication

<Alert role="none" variation="info" heading="Platform Requirements">
Passkey support requires iOS 17.4+, macOS 13.5+, or visionOS 1.0+.
</Alert>

#### Backend Configuration

For backend setup including Email OTP, SMS OTP, and WebAuthn (Passkey) configuration, see the [Passwordless documentation](https://docs.amplify.aws/swift/build-a-backend/auth/concepts/passwordless/).

#### Authentication Flows

The Authenticator supports two authentication flows:

**Password Flow (Default)**

Traditional password-based authentication:

```swift
Authenticator(authenticationFlow: .password) { signedInState in
Text("Welcome!")
}
```

**User Choice Flow**

Allows users to choose from available authentication methods:

```swift
Authenticator(authenticationFlow: .userChoice()) { signedInState in
Text("Welcome!")
}
```

#### Available Authentication Factors

| Factor | Description | Code |
|--------|-------------|------|
| Password | Traditional password with SRP | `.password(srp: true)` |
| Password (no SRP) | Password without SRP | `.password(srp: false)` |
| Email OTP | One-time code via email | `.emailOtp` |
| SMS OTP | One-time code via SMS | `.smsOtp` |
| WebAuthn (Passkey) | Biometric/security key authentication | `.webAuthn` |

#### Preferred Auth Factor

Skip the factor selection step by specifying a preferred factor:

```swift
Authenticator(
authenticationFlow: .userChoice(
preferredAuthFactor: .webAuthn
)
) { signedInState in
Text("Welcome!")
}
```

When a preferred factor is set:
- If the user has that factor available, they'll use it directly
- If not available, they'll see the factor selection screen

#### Passkey Prompts

Control when users are prompted to create a passkey:

```swift
Authenticator(
authenticationFlow: .userChoice(
passkeyPrompts: PasskeyPrompts(
afterSignUp: .always, // Prompt after sign-up
afterSignIn: .never // Don't prompt after sign-in
)
)
) { signedInState in
Text("Welcome!")
}
```

**PasskeyPrompt Options:**
- `.always` - Always prompt to create a passkey (if user doesn't have one)
- `.never` - Never prompt to create a passkey

#### Authentication Flow Steps

When using `.userChoice` flow, users may encounter these additional steps:

1. **signInSelectAuthFactor** - User selects their preferred authentication method
2. **signInConfirmPassword** - User enters password (if password factor selected)
3. **promptToCreatePasskey** - User is prompted to create a passkey
4. **passkeyCreated** - Confirmation after successful passkey creation

#### Complete Example

```swift
Authenticator(
authenticationFlow: .userChoice(
preferredAuthFactor: .webAuthn,
passkeyPrompts: PasskeyPrompts(
afterSignUp: .always,
afterSignIn: .always
)
)
) { signedInState in
Text("Welcome \(signedInState.user.username)!")
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Alert } from '@aws-amplify/ui-react';

### Customizing Passwordless Views

When using `AuthenticationFlow.UserChoice`, you can customize the additional views that appear during the authentication flow. Below is an example of customizing the Passkey views.

#### Prompt To Create Passkey View

Customize the passkey creation prompt that appears after sign-in or sign-up:

```kotlin
Authenticator(
authenticationFlow = AuthenticationFlow.UserChoice(),
promptToCreatePasskeyContent = { state ->
Column {
Text("Create a Passkey")
Text("Sign in faster with biometrics")

Button(onClick = {
scope.launch { state.createPasskey() }
}) {
Text("Create Passkey")
}

Button(onClick = {
scope.launch { state.skip() }
}) {
Text("Skip for now")
}
}
}
) { state ->
Text("Welcome!")
}
```

**PromptToCreatePasskeyState Actions:**
- `createPasskey()` - Initiates passkey creation using the device's biometric/security key authentication
- `skip()` - Skips passkey creation and continues to the signed-in state

#### Passkey Created View

Customize the confirmation screen shown after successful passkey creation:

```kotlin
Authenticator(
authenticationFlow = AuthenticationFlow.UserChoice(),
passkeyCreatedContent = { state ->
Column {
Text("Passkey Created Successfully!")
Text("You have ${state.passkeys.size} passkey(s)")

state.passkeys.forEach { passkey ->
Card {
Text(passkey.friendlyName ?: "Unknown Passkey")
}
}

Button(onClick = {
scope.launch { state.continueSignIn() }
}) {
Text("Continue")
}
}
}
) { state ->
Text("Welcome!")
}
```

**PasskeyCreatedState Properties:**
- `passkeys: List<AuthWebAuthnCredential>` - List of user's passkey credentials

**PasskeyCreatedState Actions:**
- `continueSignIn()` - Continues to the signed-in state
Loading
Loading