## passkeys-prf-client

This package provides a JavaScript client for interacting with a Passwordless authentication service that utilizes Passkeys and Proof-of-Possession (PoP) based on a user's private key.

**Installation**

```
npm install passkeys-prf-client
```

### Prerequisites

Before you can use the passkeys-prf-client package, ensure you have completed the following steps:

1.  **Create an Account on Bitwarden Passwordless.dev:**

    - Sign up for an account on [Passwordless.dev](https://admin.passwordless.dev/signup).
    - After signing up, create a new application within your account.
    - Once the application is created, retrieve the Public API Key, which will be required when configuring this package.

2.  **Set Up a RESTful Backend API Server:**

    - You need a backend API server that handles passkey authentication, initiating sign-ups, and verifying sign-ins with the Passwordless.dev private API service.
    - To get started, read the following documentation:

      - [API Overview](https://docs.passwordless.dev/guide/api.html)
      - [Backend Integration Guide](https://docs.passwordless.dev/guide/backend)

    - In your backend API, you will need to create the following endpoints:

      1.  **POST /passkeys-auth/signup/begin** - Initiates the sign-up process.
      2.  **POST /passkeys-auth/signup/complete** - Completes the sign-up process, checks with the Passwordless.dev server to confirm user registration, and sets a flag in your database.
      3.  **POST /passkeys-auth/signin/verify** - Verifies the sign-in process.
      4.  **GET /passkeys-auth/credentials/list** - Retrieves a list of all passkey credentials associated with a user. (At least one of userId or authToken is required)
      5.  **DELETE /passkeys-auth/credentials/delete** - Deletes a specific passkey credential associated with a user. (credentialId must be provided in the request body)

Ensure your backend API server is configured with the Private API Key obtained from Passwordless.dev (as outlined in Step 1).

**Usage**

**Import the PasswordlessService class**

```
import { PasswordlessService } from 'passkeys-prf-client';
```

**Instantiate the PasswordlessService class**

```
const passwordlessService = new PasswordlessService('YOUR_PUBLIC_API_KEY', 'YOUR_BACKEND_API_ROOT_URL');
```

- Replace `YOUR_PUBLIC_API_KEY` with your public API key obtained from the Bitwarden Passwordless service provider.
- Replace `YOUR_BACKEND_API_ROOT_URL` with the root URL of your backend API that handles Passwordless authentication.

**Browser Support**

This client library requires the PublicKeyCredential API to be supported by the browser. This functionality is generally available in modern browsers. You can use the `isBrowserSupported` method to check for browser compatibility before proceeding.

```
passwordlessService.isBrowserSupported();
```

**Passwordless Sign-up**

1.  Initiate sign-up by providing the user's name and email address.

```
const signupResult = await passwordlessService.signup('John Doe', 'johndoe@example.com');

if (signupResult.error) {
  // Handle sign-up error
  console.error(signupResult.error);
} else {
  const { isPrfSupported, prfKey } = signupResult;
  // Use isPrfSupported to check if Proof-of-Possession is enabled and prfKey for the generated key (if available)
}
```

2.  The sign-up process typically involves user interaction with a browser window to create a new Passkey credential.

**Passwordless Sign-in**

There are two primary methods for signing in:

- Using an alias (username)

```
const signinResult = await passwordlessService.signinWithAlias('johndoe');

if (signinResult.error) {
  // Handle sign-in error
  console.error(signinResult.error);
} else {
  const { isPrfSupported, prfKey } = signinResult;
  // Use isPrfSupported to check if Proof-of-Possession is enabled and prfKey for the retrieved key (if available)
}
```

- Using browser autofill (if supported)

```
const signinResult = await passwordlessService.signinWithAutofill();

if (signinResult.error) {
  // Handle sign-in error
  console.error(signinResult.error);
} else {
  const { isPrfSupported, prfKey } = signinResult;
  // Use isPrfSupported to check if Proof-of-Possession is enabled and prfKey for the retrieved key (if available)
}
```

**Error Handling**

All methods that interact with the Passwordless service return a Promise that resolves to an object with an `error` property in case of errors or a result object containing details.

**API Reference**

The `PasswordlessService` class provides the following methods:

- `isBrowserSupported()`: Checks if the browser supports the PublicKeyCredential API.
- `signup(name: string, email: string)`: Initiates user sign-up.
- `signinWithAlias(alias: string)`: Signs in a user using an alias (username).
- `signinWithAutofill()`: Signs in a user using browser autofill (if supported).
- `signupOrSigninAbort()`: Aborts any ongoing SignIn or SignUp operation.
- `getUserPasskeyCredentials()`: Lists all passkey credentials associated with a user.
- `deleteUserPasskeyCredential()`: Deletes passskey credential of a user.

**Additional Notes**

- This client library interacts with a Passwordless service and the specific API behavior might differ depending on the service provider's implementation.
- Refer to the Passwordless service provider's documentation for detailed information on their API endpoints and functionalities.
