> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Guide on implementing Passwordless authentication with Lock.Android

# Lock.Android: Passwordless

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

Lock <Tooltip tip="Passwordless: Form of authentication that does not rely on a password as the first factor." cta="View Glossary" href="/docs/glossary?term=Passwordless">Passwordless</Tooltip> authenticates users by sending them an Email or SMS with a one-time password that the user must enter and confirm to be able to log in, similar to how WhatsApp authenticates. This article will explain how to send a CODE using the `Lock.Android` library.

You can achieve a similar result by [sending a link that the user can click](/docs/libraries/lock-android/lock-android-passwordless-with-magic-link) to finish the passwordless authentication automatically, but a few more configuration steps are involved.

In order to be able to authenticate the user, your application must have the Email/SMS connection enabled and configured in your [Auth0 Dashboard](https://manage.auth0.com/#/connections/passwordless).

## Implementing Code Passwordless

### Configuring the SDK

In your `app/build.gradle` file add the [Manifest Placeholders](https://developer.android.com/studio/build/manifest-build-variables.html) for the Auth0 Domain and the Auth0 Scheme properties, which are going to be used internally by the library to register an intent-filter that captures the authentication result.

```kotlin lines theme={null}
plugins {
    id "com.android.application"
    id "kotlin-android"
}

android {
    compileSdkVersion 30
    defaultConfig {
        applicationId "com.auth0.samples"
        minSdkVersion 21
        targetSdkVersion 30
        // ...

        // ---> Add the next line
        manifestPlaceholders = [auth0Domain: "@string/com_auth0_domain", auth0Scheme: "https"]
        // <---
    }
}
```

It is good practice to add these values to the `strings.xml` file as string resources that can be referenced later from the code.

export const codeExample = `<resources>
    <string name="com_auth0_client_id">{yourClientId}</string>
    <string name="com_auth0_domain">{yourDomain}</string>
</resources>`;

<AuthCodeBlock children={codeExample} language="xml" />

### SDK usage

In the activity where you plan to invoke Lock, create an instance of `Auth0` with your application's information. The easiest way to create it is by passing an Android Context. This will use the values previously defined in the `strings.xml` file. For this to work, the string resources must be defined using the same keys as the ones listed above.

```kotlin lines theme={null}
val account = Auth0(context)
```

Declare an `AuthenticationCallback` implementation that will handle user authentication events. The `Credentials` object returned in successful authentication scenarios will contain the tokens that your application or API will end up consuming. See [Tokens](/docs/secure/tokens) for more specifics.

```kotlin lines theme={null}
private val callback = object : AuthenticationCallback() {
    override fun onAuthentication(credentials: Credentials) {
        // Authenticated
    }

    override fun onError(error: AuthenticationException) {
        // Exception occurred
    }
}
```

Prepare a new Lock instance by using the Builder class to configure it. Provide the account details and the callback implementation declared above. Values like <Tooltip tip="Audience: Unique identifier of the audience for an issued token. Named aud in a token, its value contains the ID of either an application (Client ID) for an ID Token or an API (API Identifier) for an Access Token." cta="View Glossary" href="/docs/glossary?term=audience">audience</Tooltip>, scope, and available connections, among others, can be configured here. When done, build the Lock instance. This instance is meant to be reused and must be disposed of when it is no longer needed. A good place to do this is in your activity's `onDestroy` method.

The sample below calls the `useCode()` method to make Lock send a **CODE** to the user's email or phone number.

```kotlin lines expandable theme={null}
// This activity will show Passwordless Lock
class MyActivity : AppCompatActivity() {

    private lateinit var lock: PasswordlessLock

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val account = Auth0(this)
        // Instantiate Lock once
        lock = PasswordlessLock.newBuilder(account, callback)
            .useCode()
            // Customize Lock
            .build(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        // Important! Release Lock and its resources
        lock.onDestroy(this)
    }

    private val callback = object : AuthenticationCallback() {
        override fun onAuthentication(credentials: Credentials) {
            // Authenticated
        }

        override fun onError(error: AuthenticationException) {
            // An exception occurred
        }
    }
}
```

Finally, launch the `PasswordlessLock` widget from inside your activity.

```kotlin lines theme={null}
startActivity(lock.newIntent(this))
```

Depending on which passwordless connections are enabled, Lock will send the **CODE** in an Email or SMS. The 'email' connection is selected first if available. Then the user must input the CODE in the confirmation step. If the value equals the one the server is expecting, the authentication will be successful.
