> ## Documentation Index
> Fetch the complete documentation index at: https://sidedish.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# End Users Authentication

> Safe sessions are used as a secure way to authenticate users and sign data you want to pass to SideDish

## Introduction

<Note>
  Embedding a store or product pages inside your app doesn't require authentication using private safe sessions. You can serve public stores that are open to anonymous visitors.
  This method is used as an easy way for you to securely transfer information between your app and SideDish on the client. The decision on authentication is totally yours. If you don't need to ensure validity of properties, you could pass all parameters unsafely. Both methods are easy to implement. We recommend authenticating usres, but if you don't rely on any input from the user, and you manage purchases on your own, you can avoid authentication altogether.
</Note>

Safe sessions allow you to achieve two main things:

1. Authenticate users on SideDish.
   SideDish doesn't create users on its own, but instead relies on the authentication of your app. This means that users don't need to go through another login flow.
2. Pass parameters from your app to SideDish safely.

In order to do this, you can call a REST api request or use the prebuilt `@sidedish/core` package with its `createSession` function.

## Creating a session

<Warning>
  Creatign safe sessions should be done on the server side, and never on the client side.
  Make sure you never pass your secret API key or personal tokens to the client!
</Warning>

<ParamField path="storeId" type="string">
  Store you want to use.
</ParamField>

<ParamField path="userId" type="string" required>
  Any unique identifier of a user. We suggest you use your existing userId (may it be a uuid or an email). It is required because there is no point in creating a session without passing a user.
</ParamField>

<ParamField path="data" type="AcceptableParameters" optional>
  Object with any extra parameters you want to pass to SideDish.
</ParamField>

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.sidedish.dev/v1/sessions" \
      -H  "Accept: application/json" \
      -H  "X-API-Token: API_KEY" \
      -H 'Content-Type: application/json' \
      -d '{BODY_OF_REQUEST}'
  ```

  ```js Typescript
  import { createSession, AcceptableParameters } from "@sidedish/core"

  export function createSafeSessionWithParams(data: AcceptableParameters): Promise<{
  	sessionId: string;
  	expiresAt: string;
  }> {
    const apiKey = process.env.SIDEDISH_API_KEY!;
    const domain = process.env.SIDEDISH_STORE!;
    return createSession({apiKey, domain, data});
  }
  ```
</CodeGroup>

### Response

<ResponseField name="sessionId" type="string">
  The `id` of the safe session
</ResponseField>

<ResponseField name="expiresAt" type="string">
  The `expiresAt` of the session in ISO string
</ResponseField>

## Acceptable parameters

### User data and user's account

All but `userId` are optional.

<ParamField path="userId" type="string" required>
  Pass this as your user id to be act upon.
</ParamField>

<ParamField path="userName" type="string">
  Pass this to see user's name in the dashboard, logs and analytics.
</ParamField>

<ParamField path="user" type="json">
  Anything you want to send for the user's properties.

  Please note that if you pass `internal` property in the user object, it will disable tracking and analytics for the user.
</ParamField>

<ParamField path="accountId" type="string">
  `id` for the logged in user's account. This is especially useful if your app is a B2B and you want to support account level features.
</ParamField>

<ParamField path="accountName" type="string">
  Pass this to see account's name in the dashboard, logs and analytics.
</ParamField>

<ParamField path="account" type="json">
  Anything you want to send for the account's properties.
</ParamField>

### Purchases

If you are managing the purchases of products yourself, you can pass what are the products the user / account has installed.

<ParamField path="purchases" type="string[] | Purchase[]">
  Array of `id` strings or Objects that include `id` and `data` for the installation

  `Purchase` Type:

  <Expandable title="Purchase">
    <ParamField path="productId" type="string">
      the `id` of the product
    </ParamField>

    <ParamField path="data" type="any">
      any extra payload you want to use in your templatae
    </ParamField>
  </Expandable>
</ParamField>

## Updating a session with new data

If you are managing the installation state and you want to update a session you could send new data with:

<ParamField path="sessionId" type="string" required>
  The id of the session
</ParamField>

<ParamField path="data" type="AcceptableParameters" required>
  Updated data
</ParamField>

Updating a `userId` isn't possible and you should just create a new session.

<CodeGroup>
  ```bash cURL
  curl -X PATCH "https://api.sidedish.com/v1/sessions/$SESSION_ID" \
      -H  "Accept: application/json" \
      -H  "X-API-Token: API_KEY" \
      -H 'Content-Type: application/json' \
      -d '{BODY_OF_REQUEST}'
  ```

  ```js Typescript
  import { updateSession, AcceptableParameters } from "@sidedish/core"

  export function updateSafeSessionWithParams(sessionId: string; data: AcceptableParameters): Promise<string> {
    const apiKey = process.env.SIDEDISH_API_KEY!;
    return updateSession({apiKey, sessionId, data});
  }
  ```
</CodeGroup>

## Revoking a session

Even though sessions are relatively short lived, you can still choose to revoke a session. This is useful if you want to log out a user.

<ParamField path="sessionId" type="string" required>
  The id of the session
</ParamField>

<CodeGroup>
  ```bash cURL
  curl -X DELETE "https://api.sidedish.com/v1/sessions/$SESSION_ID" \
      -H  "X-API-Token: API_KEY"
  ```

  ```js Typescript
  import { revokeSession } from "@sidedish/core"

  export function revokeSession(sessionId: string){
    const apiKey = process.env.SIDEDISH_API_KEY!;
    return revokeSafeSession({apiKey, sessionId});
  }
  ```
</CodeGroup>
