# Initialize Trust1Connector

## Introduction

For initialisation of the T1C you need to prepare your application first by [adding the SDK JS files to your project](setting-up-the-sdk) and importing them in such a way that you can call for the Javascript functions when you need them. When you've succesfully [downloaded](downloading-latest-trust1connector) and installed the Trust1Connector you can initialize and use the Trust1Connector

## Creating the configuration object

We will prepare the SDK's configuration Object, this object is used to pass information about which default port the Trust1Connector is running on, JWT key, API url, ... which is needed to properly contact and use the Trust1Connector.

When the Trust1Connector is configured with a Distribution Service in mind you **can** provide a valid JWT token in the configuration object. [You can retrieve such token via the Distribution Service based on the API key you received](#retrieve-jwt-token).

{% hint style="warning" %}
Retrieving JWT tokens should be handled in your own backend to maximize security
{% endhint %}

Now we can create a complete Configuration Options object to be passed to the Trust1Connector.

### T1CConfigOptions

The T1C config options is a class that can be used to create a valid configuration object to initialize the Trust1Connector. Below you can find a class definition.

```javascript
class T1CConfigOptions {
  constructor(
    public t1cApiUrl?: string,
    public t1cApiPort?: string,
    public t1cProxyUrl?: string, // deprecated
    public t1cProxyPort?: string, // deprecated
    public jwt?: string,
    public applicationDomain?: string, // "rmc.t1t.be"
  ) {}
}
```

{% hint style="info" %}
`t1cProxyUrl` and `t1cProxyPort` are deprecated since 3.5.x and only used in 3.4.x versions.
{% endhint %}

#### Parameters

**`t1cApiUrl: string`**\
&#xNAN;_&#x4F;ptional_\
The URL that connects to the local Trust1Connector instances. This can be either localhost or a domain that directs towards localhost. By default this will be `https://t1c.t1t.io`

**`t1cApiPort: string`**\
&#xNAN;_&#x4F;ptional_\
The port defined to be used for the Trust1Connector. By default this is `51983`

**`t1cProxyUrl: string`**\
&#xNAN;_&#x4F;ptional - Deprecated_\
The URL that connects to the local Trust1Connector Proxy instances. This can be either localhost or a domain that directs towards localhost. By default this will be `https://t1c.t1t.io`

**`t1cProxyPort: string`**\
&#xNAN;_&#x4F;ptional - Deprecated_\
The port defined to be used for the Trust1Connector Proxy. By default this is `51983`

**`jwt: string`**\
&#xNAN;_&#x4F;ptional_\
The JWT token that is used to authenticate towards the Trust1Connector. This should be retrieved from the DS and is only needed when the Trust1Connector is configured to work with a DS and requires JWT validation

**`applicationDomain: string`**\
&#xNAN;_&#x4F;ptional_\
The domain of the application that is using the Trust1Connector. This is used to make sure the consent is only available for a specific web-application. This prevents various clients to interfere with eachother.\
This domain also `tags` the Distribution service transactions being sent to the Distribution service. This makes it easy to distinguish between applications/tags for the transactions

```javascript
// ...

let environment = {
    t1cApiUrl: 'https://t1c.t1t.io',
    t1cApiPort: '51983',
    t1cProxyUrl: 'https://t1c.t1t.io',
    t1cProxyPort: '51983',
    jwt: 'eyJraWQiOiJ0MWNkcyIsImFsZyI6IlJTMjU2In0..._Mg2PfdhCMQ',
    applicationDomain: 'test-app'
};

const configoptions = new T1CSdk.T1CConfigOptions(
        environment.t1cApiUrl,
        environment.t1cApiPort,
        environment.t1cProxyUrl,
        environment.t1cProxyPort,
        environment.jwt,
        environment.applicationDomain
    );
config = new T1CSdk.T1CConfig(configoptions);

// ...
```

When a remote DS is used you can set the following field with the correct DS url, this will in turn use the DS's capabilities of acting as a Trust1Connector proxy for enchanced security.

```javascript
// When remote DS is used set the following parameter
config.dsUrl = "https://acc-ds.t1t.io";
```

Now we can continue to use the `config` variable to [initialize](#initializing-the-trust-1-connector-sdk) and retrieve a `T1CClient`

### Authenticated client

If you need to set up the Trust1Connector with a valid JWT token you can follow the documentation on the [Authenticated Client page](authenticated-client) to [retrieve a valid token](../authenticated-client#retrieving-a-jwt-token) from the DS.

When you have a valid token you can provide this in the Configuration. This will make sure the Trust1Connector is usable until the token becomes unvalid. At which point you can [refresh](../authenticated-client#refresh-jwt-token) your token to continue to use the Trust1Connector. More information on how to retrieve,use and refresh a token can be found on the [Authenticated Client page](authenticated-client).

## Initializing the Trust1Connector SDK

Initialization of the Trust1Connector in many cases requires a user consent, the exception being when no registry is configured (either local or central). More information can be found [here](consent). The registry allowed us to create a Trust1Connector that works in any environment, without the need for Administrative rights from the users, wether it be Standalone, Multi session, RDP, Citrix, ...

To Initialize the Trust1Connector a [Consent](consent) is required(when a central or local registry is present). When no consent can be found the error codes `814500` or `814501` will be thrown. This means that either the previous consent is not valid anymore or no consent was given yet. More information regarding the consent can be found on the [Consent page](consent) which explains it in more detail

```javascript
// ...

T1CSdk.T1CClient.initialize(config).then(res => {
    client = res;
    console.log("Client config: ", client.localConfig);
    core = client.core();
    core.version().then(versionResult => console.log("T1C running on core "+ versionResult));
}, err => {
    if (err.code == 814500 || err.code == 814501) {
        client = err.client;
        // (new) Consent is required
    }
    else if(err.code == 112999) {
        // Could not connect with the Trust1Connector
    } else {
        // an uncatched error occured
        console.error("T1C error:", err)
    }
});

// ...
```

When either no consent is present or its invalid you will receive a **invalid** `client` object (line 8 in example above) that can be used to trigger the `getImplicitConsent` function in the Core serivce.

The Consent requires a user action to [copy some data to its clipboard](#clipboard). This data is used by the T1C registry to make sure you're targetting the correct instance of the Trust1Connector. More information about this can be found here.

The signature of the `getImplicitConsent` function is as follows;

```javascript
public getImplicitConsent(codeWord: string, durationInDays?: number, 
    callback?: (error?: T1CLibException, data?: T1CClient) => void
): Promise<T1CClient>
```

This function expects:

**`codeword: string`**\
The string value that is saved to the user's clipboard needs to be sent to the Consent function.

**`durationInDays: number`**\
&#xNAN;_&#x4F;ptional_\
Amount of days that the consent is valid.

**`callback: (error?: T1CLibException, data?: T1CClient)`**\
&#xNAN;_&#x4F;ptional_\
Callback when you're not using ES

Below is a small javascript example of how you can trigger the `getImplicitConsent` function

```javascript
client.core().getImplicitConsent(document.querySelector(".clipboard-data").innerHTML).then(res => {
    console.log("Consent Executed")
    client = res;        
    // Use the client for your use-cases
}, err => {
    // Failed, use the error client to retry the consent
    this.client = err.client;
    console.error(err.description ? err.description : err)
})
```

After this you will have a `client` that can be used to execute the rest of the functionality that the Trust1Connector has to offer.

#### Full example

```javascript
// Global client to be used over the entire application
const client = null

// Prepare the configuration
let environment = {
    t1cApiUrl: 'https://t1c.t1t.io',
    t1cApiPort: '51983',
    t1cProxyUrl: 'https://t1c.t1t.io',
    t1cProxyPort: '51983',
    jwt: 'eyJraWQiOiJ0MWNkcyIsImFsZyI6IlJTMjU2In0..._Mg2PfdhCMQ',
    applicationDomain: 'test-app'
};

const configoptions = new T1CSdk.T1CConfigOptions(
        environment.t1cApiUrl,
        environment.t1cApiPort,
        environment.t1cProxyUrl,
        environment.t1cProxyPort,
        environment.jwt,
        environment.applicationDomain
    );
config = new T1CSdk.T1CConfig(configoptions);

// Initialize the Trust1Connector with the previously created configuration object
T1CSdk.T1CClient.initialize(config).then(res => {
    client = res;
    console.log("Client config: ", client.localConfig);
    core = client.core();
    core.version().then(versionResult => console.log("T1C running on core "+ versionResult));
}, err => {
    if (err.code == 814500 || err.code == 814501) {
        // (new) Consent is required
    }
    else if(err.code == 112999) {
        // Could not connect with the Trust1Connector
    } else {
        // an uncatched error occured
        console.error("T1C error:", err)
    }
});
    
    

// when the user has clicked on the clipboard/consent button we execute the getImplicitConsent function
document.querySelector(".clipboard").addEventListener("click", (ev) => {
    if (client != null) {
        client.core().getImplicitConsent(document.querySelector(".clipboard-data").innerHTML).then(res => {
            console.log("Consent Executed")
            client = res;        
            // Use the client for your use-cases
        }, err => {
            this.client = err.client;
            console.error(err.description ? err.description : err)
        })
    }

})
```

## Clipboard

To provide a consent, we suggest you use the clipboard functionality available in browsers. The most supported way is via `document.exeCommand` and below you can find an example of this.

There is also a [clipboard API ](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)but this is not fully supported yet

{% hint style="info" %}
The code below is an example of how you can integrate a copy command in the webbrowser
{% endhint %}

```javascript
const tokenNode = document.querySelector('.consent-token');
var range = document.createRange();
range.selectNode(tokenNode);
window.getSelection().addRange(range);
try {
    // Now that we've selected the anchor text, execute the copy command
    document.execCommand('copy');
} catch(err) {
    console.log('Oops, unable to copy');
}

// Remove the selections - NOTE: Should use
// removeRange(range) when it is supported
window.getSelection().removeRange(range);
const clipboardData = tokenNode.textContent;
```

## Retrieve JWT token

<mark style="color:blue;">`GET`</mark> `https://ds.t1t.io/v3/tokens/application`

This endpoint will return a valid JWT token to use for a certain period based on the API-key you provide in the \`apikey\` header

#### Headers

| Name   | Type   | Description                      |
| ------ | ------ | -------------------------------- |
| apikey | string | API-key received from Trust1Team |

{% tabs %}
{% tab title="200 Will return an success boolean and data object. The data object is the JWT token" %}
```javascript
{
    "success": true,
    "data": "eyJraWQiOiJ0MWNkcyIsImFsZyI6IlJTMjU2In0...v8_Mg2PfdhCMQ"
}
```
{% endtab %}

{% tab title="401 When the apikey header is not sent" %}
```javascript
{
    "message": "No API key found in request"
}
```
{% endtab %}

{% tab title="403 When trying to retrieve a JWT token for an invalid/unknown API key" %}
```javascript
{
    "success": false,
    "description": "Invalid API key",
    "code": 1005,
}
```
{% endtab %}
{% endtabs %}

