# Extensions

Extensions allow to extend the system's behaviour with custom logic. Quasr allows you to run your own custom code to **respond to platform events** (such as account creation, OTP, data capture, ...) or **add custom claims to ID and/or access tokens.** Both use case differ in their integration pattern, responding to platform events is async, while adding custom claims to tokens is synchronous.

Quasr currently only supports the following programming languages/frameworks for extensions:

* Node.js 22 in JavaScript on AWS Lambda

## Synchronous vs Asynchronous

| Synchronous                                                                                                                                    | Asynchronous                                                                                                                                                                                                                                                                                                                                                            |
| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Run as part of request; time-sensitive                                                                                                         | Run outside of requests; not time-sensitive                                                                                                                                                                                                                                                                                                                             |
| <p>Current use cases:<br>- add custom claims to ID token<br>- add custom claims to access token<br>- modify granted scopes in access token</p> | <p>Current use cases:<br>- respond to API calls<br>- respond to resource creation<br>- respond to resource updates<br>- respond to resource deletion<br>- respond to input capture (username / OTP)<br>- respond to claims capture (federation)<br>- respond to communication (send OTP)<br>- respond to authentication events<br>- respond to authorization events</p> |
| <p>Configured as part of resource:<br>- client configuration</p>                                                                               | <p>Configured as part of extension:<br>- rule configuration</p>                                                                                                                                                                                                                                                                                                         |

## Tenant Administration UI

A **code extension** can be created and configured through the **Tenant Admin UI > Extensions > Code Extensions**.

<figure><img src="https://3830835165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mjx2ZPygyh2w8fuHh9P%2Fuploads%2Fbank0fa6mn2L65oPFdHJ%2FScreenshot%202023-07-24%20at%2017.51.17.png?alt=media&#x26;token=341e41f4-c78d-4207-8ce0-4cc6eac677b0" alt=""><figcaption><p>Extension in the Quasr Tenant Admin UI</p></figcaption></figure>

<figure><img src="https://3830835165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mjx2ZPygyh2w8fuHh9P%2Fuploads%2FE88w5XMmGIG8yPNlPGXG%2FScreenshot%202023-07-24%20at%2018.03.20.png?alt=media&#x26;token=35f236b0-ab03-4eef-85a9-1d9fe500c9d0" alt=""><figcaption><p>Extension example to add custom claims to tokens in the Quasr Tenant Admin UI</p></figcaption></figure>

{% hint style="danger" %}
It is currently **not possible to update extensions** (besides their label and status). The Tenant Admin UI may give the impression but it does not update the extension. If you want to change the code and/or rule of an extension you hence have to create a new one with the desired code and/or rule.
{% endhint %}

## API

Code Extensions can also be created and configured through the [Admin API](https://docs.quasr.io/quasr/tenant-administration/apis/management-api-graphql), see [Postman Collection](https://documenter.getpostman.com/view/18129777/UVXgMHEv#0da6e9fb-bae3-437d-ade5-2348d326a9df) and [GraphQL Voyager](https://quasr-io.github.io/graphql/).

{% hint style="danger" %}
The code must be provided in Base64 encoded format.
{% endhint %}

### GraphQL Example

```graphql
// GraphQL Query (Sample)
mutation createExtension ($input: CreateExtensionInput!) {
    createExtension (input: $input) {
        id
    }
}

// GraphQL Variables (Sample)
{
  "input": {
    "label": "My Code Extension",
    "code": "ZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoKSB7IHJldHVybiB7IG1hZ2ljOiAndGVzdCcgfX0="
  }
}

// Response (Sample)
{
    "data": {
        "createExtension": {
            "id": "8bde5565-7027-4232-8db8-3f3ca1acaeac"
        }
    }
}
```

### NodeJs - Axios Example

```javascript
var axios = require('axios');
var data = JSON.stringify({
  query: `mutation createExtension ($input: CreateExtensionInput!) {
    createExtension (input: $input) {
        id
    }
}`,
  variables: {
    "input": {
      "label": "My Code Extension",
      "code": "ZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoKSB7IHJldHVybiB7IG1hZ2ljOiAndGVzdCcgfX0="
    }
  }
});

var config = {
  method: 'post',
  url: 'https://{tenant_id}.api.quasr.io/graphql',
  headers: { 
    'Authorization': 'Bearer ACCESS_TOKEN_WITH_ADMIN_SCOPE', 
    'Content-Type': 'application/json'
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});
```

## Build

You can query the status by using `getExtension` and looking for the build status. Once the build has started it will say `STARTED` and once finished it will be either `SUCCEEDED` or `FAILED`. In case your extension build succeeded your extension status will change to `ENABLED`, else it will become `DISABLED`.

{% hint style="info" %}
Currently little information is provided when a build fails but as we share the build details customers can run this locally to debug.
{% endhint %}

{% hint style="danger" %}
You are limited to **5 enabled code extensions per tenant**. When your extension is initially deployed it will be valid for 1 day, in which time you must successfully run the extension or it will expire. Afterwards it will expire after an inactivity window of 30 days.
{% endhint %}

You provide code for a **Nodejs 22 AWS Lambda function in JavaScript**. The main function must be called `handler` (for more information please study AWS Lambda documentation [here](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html)).

Below the `package.json` we use during build hence no imports are allowed.

```json
{} // no imports
```

## Management API for Extensions

see [Postman Collection](https://documenter.getpostman.com/view/18129777/UVXgMHEv#0da6e9fb-bae3-437d-ade5-2348d326a9df)

see [GraphQL Voyager](https://quasr-io.github.io/graphql/)
