Skip to content
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