This example demonstrates how to integrate the JavaScript API library into an existing project. The open source project Mailtrain was chosen as an example, in which you can see below how it has been integrated with the JavaScript API library.
Example of JavaScript integration: MailTrain#
Overview#
Mailtrain is a self hosted newsletter web based application built on Node.js (v14+) and MySQL (v8+) or MariaDB (v10+).
- Subscriber lists management
- List segmentation
- Custom fields
- Email templates (including MJML-based templates)
- Custom reports
- Automation (triggered and RSS campaigns)
- Multiple users with granular user permissions and flexible sharing
- Hierarchical namespaces for enterprise-level situations
- Builtin Zone-MTA for close-to-zero setup of mail delivery
- Encrypt emails of subscribers before saving in DB
- Decryption of email when they are rendered in the frontend
- Encrypt/decrypt email templates
- Decryption of email when backend send campaign email to the targeted recipients
Installation#
Using npm:
npm i rps-engine-client-js
Configure the transformation#
The example illustrated in this pages is based on the following transformation configuration which can be created by following this tutorial and using this JSON configuration file.
Details of the transformation configuration:
- One rights context is defined: Can TRANSFORM.
- Two processing contexts are defined: Protect and Deprotect.
-
The
Subscriber.Email
data instance can be protected/deprotected using the "AES deterministic decryption sequence"/"AES deterministic encryption sequence" transformer sequences which are based on "AES deterministic encryption" transformers -
The
CampaignSettings.ReplyEmail
data instance can be protected/deprotected using the "AES deterministic decryption sequence"/"AES deterministic encryption sequence" transformer sequences which are based on "AES deterministic encryption" transformers -
The
CampaignSettings.FromEmail
data instance can be protected/deprotected using the "AES deterministic decryption sequence"/"AES deterministic encryption sequence" transformer sequences which are based on "AES deterministic encryption" transformers -
The
Template.Text
data instance can be protected/deprotected using the "AES deterministic decryption sequence"/"AES deterministic encryption sequence" transformer sequences which are based on "AES deterministic encryption" transformers -
The
Template.Name
data instance can be protected/deprotected using the "AES deterministic decryption sequence"/"AES deterministic encryption sequence" transformer sequences which are based on "AES deterministic encryption" transformers -
The
Template.Description
data instance can be protected/deprotected using the "AES deterministic decryption sequence"/"AES deterministic encryption sequence" transformer sequences which are based on "AES deterministic encryption" transformers
Configuration of the API library#
The API library is installed and configured in the shared
directory
because it is used on the client
and on the server
.
Configuration files#
In this section we see how to configure the RPS API Library in order to use the transformation configuration
you just created. You have to replace following parameters with the you retrieved when you created the
transformation configuration in RPS CoreConfiguration
:
- {API_KEY_OF_CONFIGURATION} = It is the
API Key
of the transformation configuration - {SECRET_KEY_OF_CONFIGURATION} = It is the
Secret Key
of the transformation configuration - {ENGINE_HOST_NAME} = It is the
RPS transformation services hostname
- {AUTH_HOST_NAME} = It is the
RPS OAuth2 authentication services hostname
Configuration file in the server directory:#
const {TokenProvider, EngineProvider, Criteria} = require('../../shared/engine');
const ENGINE_AUTH_HOST_NAME = '{AUTH_HOST_NAME}' // Example: 'https://identity.rpsprod.ch'
// configuration secrets
const CLIENT_ID = '{API_KEY_OF_CONFIGURATION}'; // Example: '518155d0-4774-467c-b891-6ebd3ea07f08'
const CLIENT_SECRET = '{SECRET_KEY_OF_CONFIGURATION}'; // Example: '75582a544bda425d956390844755f60369b9866026d8485aa49f7edcfe986bb1'
const secrets = {
clientId: CLIENT_ID,
clientSecret: CLIENT_SECRET
};
// creating an instance of the class TokenProvider using 'secrets' and 'ENGINE_AUTH_HOST_NAME'
const tokenProvider = new TokenProvider({
identityServerHostName: ENGINE_AUTH_HOST_NAME,
...secrets
})
const engineProvider = new EngineProvider(tokenProvider)
module.exports = {
engineProvider,
tokenProvider,
Criteria,
};
Configuration file in the client directory:#
import {TokenProvider, EngineProvider, Criteria} from '../../../shared/engine'
import {getUrl} from './urls'
// ClientTokenProvider - Proxy token provider from backend
class ClientTokenProvider extends TokenProvider {
constructor () {
super({
identityServerHostName: getUrl(),
authEndpoint: 'rest/connect/token'
})
}
// allows validation with empty secrets (clientId = undefined, clientSecret = undefined)
_validateGenerateToken (secrets) {
return true
}
}
const clientTokenProvider = new ClientTokenProvider()
const engineProvider = new EngineProvider(clientTokenProvider)
export {
clientTokenProvider,
engineProvider,
Criteria
}
Examples of usages#
Here you can see how data is encrypted in the client and how data is decrypted in the server by calling the RPS Engine transform endpoint via the RPS API library.
Client:#
import {engineProvider, Criteria} from '../../lib/engine';
...
const encryptMethod = instance => engineProvider.encryptInstance(instance, Criteria.SUBSCRIBER); // encrypt subscriber instance
Server:#
const {engineProvider, Criteria} = require('../../lib/engine');
...
// getSubscriberById endpoint
router.getAsync('/subscriptions/:listId/:subscriptionId', passport.loggedIn, async (req, res) => {
const entity = await subscriptions.getById(req.context, castToInteger(req.params.listId), castToInteger(req.params.subscriptionId));
entity.hash = await subscriptions.hashByList(castToInteger(req.params.listId), entity);
const decryptedEntity = await engineProvider.decryptInstance(entity, Criteria.SUBSCRIBER);
return res.json(decryptedEntity);
});
Examples of encryption#
The following screen-shots shows you how data is rendered by the frontend of MailTrain frontend in two scenarii:
- RPS is not used, there is no integration with RPS API library. This is how the data is stored in the database of MailTrain, so data is fully protected.
- RPS is used via the integration of RPS API library in MailTrain. Data is rendered in clear to the final user allowing to him to use it.