# accountsSDK

`accountsSDK` is a small library that installs the "Sign in with LiveChat" button on any website or app. It also wraps OAuth flow in an easy-to-use API.

## Installation

```
npm install --save @livechat/accounts-sdk
```

## Button

Example sign in with LiveChat button designs. Assets are available [here](https://livechat.design/).

![Button](assets/button.svg)
![Small button](assets/button-small.svg)

## Example popup

```
import AccountsSDK from '@livechat/accounts-sdk';

// create new SDK instance with it's options
const sdk = new AccountsSDK({
  client_id: '<your_app_client_id>'
});

document.getElementById('login-button').onclick = (e) => {
  if (e && e.preventDefault) {
    e.preventDefault();
  }

  sdk.popup().authorize().then((authorizeData)=>{
    const transaction = sdk.verify(authorizeData);
    if (transaction != null) {
      // authorization success
      // authorizeData contains `accessToken` or `code`
      // transation contains state and optional code_verifier (code + PKCE)
    }
  }).catch((e)=>{

  })
};
```

## Flows

Authorize using a popup. It's possible to pass options to override constructor options.

```
const sdk = new AccountsSDK(options)
const promise = sdk.popup(options).authorize()
```

Authorize using iframe. It's possible to pass options to override constructor options. Works when a browser doesn't check for ITP, and user authentication is set.

```
const sdk = new AccountsSDK(options)
const promise = sdk.iframe(options).authorize()
```

Authorize using a full redirect. Authorize function performs full browser redirect to an authorization server. `authorizeData` function checks if authorization is set in URL.

```
const sdk = new AccountsSDK(options)

sdk.redirect().authorizeData().then((authorizeData)=>{
  // authorize data found in URL
  const transaction = sdk.verify(authorizeData);

}).catch((e)=>{
  // authorize data missing, redirect to authorization server
  sdk.redirect().authorize()
})
```

## Options

- `client_id` **string** **required** registered client ID
- `organization_id` **string** organization ID
- `prompt` **string** use `consent` to force consent prompt in a popup and redirect flows
- `response_type='token'` **string** OAuth response type, use `token` or `code`
- `popup_flow='auto'` **string** `auto` - don't show popup when credentials are not required, `manual` - always show popup
- `state` **string** OAuth state param, auto generated by SDK when empty
- `verify_state=true` **bool** a function that returns transaction should verify if the state matches
- `scope` **string** - custom scope list, must be a subset of preconfigured client ID scopes
- `redirect_uri` **string** OAuth redirect URI - current location by default
- `email_hint` **string** fill in an email hint in forms
- `server_url='https://accounts.livechat.com'` **string** authorization server url
- `path=''` **string** option to provide a path when loading accounts, for example `/signup`
- `tracking` **object** tracking querystring params
- `transaction.namespace='com.livechat.accounts'` **string** transaction keys prefix
- `transaction.key_length=32` **number** transaction random state length
- `transaction.force_local_storage=false` **bool** try to use local storage instead of cookies
- `pkce.enabled=true` **bool** Oauth 2.1 PKCE extension enabled for `code` grant
- `pkce.code_verifier` **string** override auto generated code verifier
- `pkce.code_verifier_length=128` **number** code verifier length, between 43 and 128 characters https://tools.ietf.org/html/rfc7636#section-4.1
- `pkce.code_challange_method='S256'` **string** code challange method, use `S256` or `plain`

## SJCL

One of components uses crypto library called SJCL. We include a custom build in `src/vendor/sjcl.js` that only includes the pieces we need and avoids bundler errors caused by Node requires in standard version.

To do this build yourself and verify code integrity, do the following:

1. Clone [the SJCL repo](https://github.com/bitwiseshiftleft/sjcl).
2. Check out a `1.0.8` version.
3. Run `./configure --without-all --with-sha256 --compress=none` to configure our build.
4. Run `make sjcl.js` to build the file.
5. Compare newly created `sjcl.js` with the one included in `src/vendor`.


## Release

To release a new version of the package to npm:

1. **Make sure you're logged in**:
   ```bash
   npm login
   ```

   This will prompt you for your npm username, password, and 2FA code (if enabled).
   You can confirm you're logged in with:

   ```bash
   npm whoami
   ```

2. **Verify you have publish permissions**:
   ```bash
   npm publish --dry-run
   ```
   This will simulate publishing without actually publishing. If you don't have permission, you'll see:
   ```
   403 Forbidden - You do not have permission to publish to this organization
   ```
   
   You can also check your permissions with:
   ```bash
   npm access list collaborators @livechat/accounts-sdk | grep "$(npm whoami)"
   ```
   
   Or list all collaborators with write permission:
   ```bash
   npm access list collaborators @livechat/accounts-sdk | grep write
   ```

3. **Create a new branch** for the release:
   ```bash
   git checkout -b release-v2.0.11  # use the appropriate version number
   ```

4. **Update the version** in `package.json` following [semantic versioning](https://semver.org/):
   ```bash
   npm version patch --no-git-tag-version  # for bug fixes (2.0.10 -> 2.0.11)
   npm version minor --no-git-tag-version  # for new features (2.0.10 -> 2.1.0)
   npm version major --no-git-tag-version  # for breaking changes (2.0.10 -> 3.0.0)
   ```

5. **Update the CHANGELOG.md**:
   - Move all items from the `[Unreleased]` section to a new version section with the release version number and date
   - Ensure the changes are categorized properly (Added, Changed, Fixed, Security, Documentation)
   - Add a new empty `[Unreleased]` section at the top
   - Update the version comparison links at the bottom of the file

   Example:
   ```markdown
   ## [Unreleased]


   ## [2.0.11] - 2026-02-09

   ### Fixed
   - Fix issue with authentication flow
   ```

   Then commit both changes:
   ```bash
   git add package.json package-lock.json CHANGELOG.md
   git commit -m "Bump version to 2.0.11"
   ```

6. **Build the package**:
   ```bash
   npm run build
   ```

7. **Run tests** to ensure everything works:
   ```bash
   npm test
   ```

8. **Push the branch**:
   ```bash
   git push origin release-v2.0.11
   ```

9. **Create a pull request** with the version update and get it reviewed and merged.

10. **After the PR is merged**, checkout the default branch and pull the latest changes:
    ```bash
    git checkout master
    git pull
    ```

11. **Create and push the git tag on the merged commit**:
    ```bash
    git tag v2.0.11
    git push origin v2.0.11
    ```

12. **Publish to npm**:
    ```bash
    npm publish
    ```

**Note**: Tagging *after* the PR is merged keeps the tag on the commit that actually landed on the default branch (important when using squash/rebase merges). The `prepare` script will automatically run the build before publishing.

## Beta Release Process

To release a beta version of the package for testing purposes:

1. **Make sure you're logged in to npm**:
   ```bash
   npm login
   npm whoami  # confirm you're logged in
   ```

2. **Create a beta version** (without committing):
   ```bash
   npm version prerelease --preid=beta --no-git-tag-version
   ```

   This will bump the version to something like `2.1.4-beta.0`. For subsequent beta iterations:
   ```bash
   npm version prerelease --no-git-tag-version  # increments to beta.1, beta.2, etc.
   ```

3. **Build the package**:
   ```bash
   npm run build
   ```

4. **Run tests** to ensure everything works:
   ```bash
   npm test
   ```

5. **Publish to npm with the beta tag**:
   ```bash
   npm publish --tag beta
   ```

**Note**: The `--tag beta` flag ensures that this version is not installed by default. Users must explicitly install it with `npm install @livechat/accounts-sdk@beta`. You can view all published beta versions with `npm view @livechat/accounts-sdk versions`.
