Add BDK to an Extension App for Circle of Trust
Prerequisites
Complete the previous guide on building an extension app with app views
Build an Extension App with App ViewsComplete the first part of this guide with the assistance of your pod administrator, ensuring that your app has the Primary User Identity and Trust application permissions.
Add an Extension App to a Symphony PodUser Identity
In order to obtain identity information of the current user, an extension app needs to perform an authentication call and validation loop as part of the Circle of Trust process. This requires a backend service to call Symphony Messaging REST APIs so as to secure the required private key. You can choose to manually create your own REST API client and link the endpoint contracts to the ADK configuration, but this guide will demonstrate how to use BDK to ease the process.
Create BDK Project
$ yo @finos/symphony
__ __ ___ _
\ \ / /__ / __|_ _ _ __ _ __| |_ ___ _ _ _ _
\ V / _ \ \__ \ || | ' \| '_ \ ' \/ _ \ ' \ || |
|_|\___/ |___/\_, |_|_|_| .__/_||_\___/_||_\_, |
|__/ |_| |__/
Welcome to Symphony Generator v2.8.0
Project files will be generated in folder: /home/user/code/bdk-ext-app
______________________________________________________________________________________________________
? Enter your pod host develop2.symphony.com
? Enter your bot username my-bot
? Select your project type Extension App (BDK)
? Select your programing language Java
? Enter your app id localhost-4000
? Select your build system Maven
? Enter your project artifactId bot-application
? Enter your base package com.mycompany.bot
Configuration
As we won't be using the bot components, we can remove configuration relating to bots. We will also remove the TLS configuration as we will use ADK to host the frontend app instead. We also need to expand the CORS configuration as our frontend will make a cross-origin call to this backend in development mode (modify as appropriately for production).
bdk:
host: develop2.symphony.com
app:
appId: localhost-4000
privateKey:
path: rsa/privatekey.pem
bdk-app:
auth:
enabled: true
cors:
"[/**]":
allowed-origins: "*"
allowed-headers: "*"
allowed-credentials: false
allowed-methods: [ "POST", "GET" ]
If you are using your own extension app id and key, change the values as appropriate. If you are using the developer sandbox, download this key into rsa/privatekey.pem
.
Start Backend
Either launch the BDK project from your IDE or use the respective maven or gradle command:
# Maven
./mvnw spring-boot:run
# Gradle
./gradlew bootRun
Build ADK App
Modify the index.js
or index.ts
file from the earlier ADK project to be as follows:
import * as ADK from '@symphony-ui/adk';
const backendUri = 'http://localhost:8080/bdk/v1/app';
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
const getAppToken = () => fetch(`${backendUri}/auth`, { method: 'POST' })
.then(r => r.json())
.then(r => r.appToken);
const validateAppToken = (appToken: string, symphonyToken: string) =>
fetch(`${backendUri}/tokens`, { method: 'POST', body: JSON.stringify({ appToken, symphonyToken }), headers })
.then(r => null);
const validateJwt = (jwt: string) =>
fetch(`${backendUri}/jwt`, { method: 'POST', body: JSON.stringify({ jwt }), headers })
.then(r => r.json());
const config : ADK.SymphonyAppDescriptor = {
id: 'localhost-4000',
circleOfTrust: { getAppToken, validateAppToken, validateJwt },
};
ADK.start(config).then(() => {
ADK.navigation.add('My App', () => ADK.modules.open('view-a', { title: 'Hello' }));
});
Note that we previously only supplied id
to the ADK.start
call but we now supply an additioinal circleOfTrust
object in that configuration. This object has 3 properties that each return a promise.
getAppToken
: calls the backend to perform app authentication and retrieve the tokenvalidateAppToken
: calls the backend to perform token validationvalidateJwt
: calls the backend to perform JWT validation
ADK takes care of adherence to the Circle of Trust process so you only need to define these contracts to allow ADK to perform the required backend calls.
Now that the app is authenticated, we can fetch user identity from either the controller or views. Let's edit the existing view to be as follows:
import * as React from 'react';
import * as ADKReact from '@symphony-ui/adk-react';
import * as ADK from '@symphony-ui/adk';
import { useEffect, useState } from 'react';
import './view-a.css';
const ViewA = () => {
const [ user, setUser ] = useState<ADK.UserJwt>();
useEffect(() => {
ADK.user.getUserInfo().then(response => setUser(response));
}, []);
return (
<div className="main-view">
<main>
{ user && (
<div>
<strong>User</strong>: {user.displayName} ({user.emailAddress})
</div>
)}
</main>
</div>
);
};
ADKReact.createView(<ViewA />, { id: 'localhost-4000' });
Start the App
We can now start the app using:
npm start
Load the App in Symphony Messaging
Instead of performing bundle injection as before, load Symphony Messaging normally now. Once Symphony Messaging is loaded, open the Marketplace using the left rail. Locate your App and install it. If you are using the developer sandbox, the app's name is Localhost 4000.
Test the App
Once the app is installed, you should notice a new app appears in the Apps section labelled as My App. If you launch the app, it opens a module showing the view, which contains your display name and email.
Last updated
Was this helpful?