Skip to content

Commit 4b2fb16

Browse files
import npm package instead of script
1 parent f1ca4b6 commit 4b2fb16

File tree

5 files changed

+59
-38
lines changed

5 files changed

+59
-38
lines changed

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ services:
2323
javascript-sdk-server-side:
2424
build:
2525
context: .
26-
dockerfile: web-integrations/javascript-sdk/server-side/Dockerfile
26+
dockerfile: web-integrations/javascript-sdk/server-side-node/Dockerfile
2727
ports:
2828
- "3034:3034"
2929
container_name: javascript-sdk-server-side

web-integrations/javascript-sdk/server-side-node/Dockerfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ FROM node:20.11.0-alpine3.18
33
WORKDIR /usr/src/app
44

55
# Copy package files first for better caching
6-
COPY web-integrations/javascript-sdk/server-side/package*.json ./
6+
COPY web-integrations/javascript-sdk/server-side-node/package*.json ./
77
RUN npm install
88

99
# Copy application files
10-
COPY web-integrations/javascript-sdk/server-side/server.js ./
11-
COPY web-integrations/javascript-sdk/server-side/public ./public/
12-
COPY web-integrations/javascript-sdk/server-side/views ./views/
10+
COPY web-integrations/javascript-sdk/server-side-node/server.js ./
11+
COPY web-integrations/javascript-sdk/server-side-node/public ./public/
12+
COPY web-integrations/javascript-sdk/server-side-node/views ./views/
1313

1414
ENV PORT=3034
1515
EXPOSE 3034

web-integrations/javascript-sdk/server-side-node/README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ For more information on the JavaScript SDK, refer to the [UID2 SDK for JavaScrip
1010

1111
Unlike the browser where the SDK runs natively in the DOM, this example uses **jsdom** to simulate a browser environment within Node.js:
1212

13-
1. **Creates a virtual DOM**: Uses jsdom to provide `window`, `document`, and `navigator` objects that the SDK expects
14-
2. **Polyfills browser APIs**: Adds Node.js equivalents for Web Crypto API (`crypto.subtle`) and text encoding APIs (`TextEncoder`/`TextDecoder`)
15-
3. **Loads the SDK**: Fetches and executes the browser-based SDK code within the simulated environment
16-
4. **Runs SDK methods**: Calls `setIdentityFromEmail` just like in a browser, with the same public credentials
13+
1. **Imports the SDK**: Uses npm packages `@uid2/uid2-sdk` or `@unified-id/euid-sdk` (selected dynamically based on `IDENTITY_NAME`)
14+
2. **Creates a virtual DOM**: Uses jsdom to provide `window`, `document`, and `navigator` objects that the SDK expects
15+
3. **Polyfills browser APIs**: Adds Node.js equivalents for Web Crypto API (`crypto.subtle`) and text encoding APIs (`TextEncoder`/`TextDecoder`)
16+
4. **Instantiates the SDK**: Creates a new instance of `UID2` or `EUID` class
17+
5. **Runs SDK methods**: Calls `setIdentityFromEmail` just like in a browser, with the same public credentials
1718

1819
This demonstrates that the client-side SDK can be compatible with server-side Node.js environments when given the proper browser-like context.
1920

@@ -61,10 +62,10 @@ The following table lists the environment variables that you must specify to sta
6162
| `UID_SERVER_BASE_URL` | The base URL of the UID2/EUID service. For details, see [Environments](https://unifiedid.com/docs/getting-started/gs-environments) (UID2) or [Environments](https://euid.eu/docs/getting-started/gs-environments) (EUID). | UID2: `https://operator-integ.uidapi.com`<br/>EUID: `https://integ.euid.eu/v2` |
6263
| `UID_CSTG_SUBSCRIPTION_ID` | Your UID2/EUID subscription ID for Client-Side Token Generation. **These are public credentials.** | Your assigned subscription ID (e.g., `DMr7uHxqLU`) |
6364
| `UID_CSTG_SERVER_PUBLIC_KEY` | Your UID2/EUID server public key for Client-Side Token Generation. **These are public credentials.** | Your assigned public key |
64-
| `UID_JS_SDK_URL` | URL to the UID2/EUID JavaScript SDK | UID2: `https://cdn.integ.uidapi.com/uid2-sdk-4.0.1.js`<br/>EUID: `https://cdn.integ.euid.eu/euid-sdk-4.0.1.js` |
65-
| `UID_JS_SDK_NAME` | Global variable name for the SDK | UID2: `__uid2`<br/>EUID: `__euid` |
6665
| `SESSION_KEY` | Used by the cookie-session middleware to encrypt the session data stored in cookies. | Any secure random string |
6766

67+
> **⚠️ Important**: Your CSTG subscription must be configured with `http://localhost:3034` as an allowed origin. Contact your UID2/EUID representative to add this origin to your subscription's allowed origins list.
68+
6869
### Display/UI Configuration
6970

7071
| Variable | Description | Example Values |

web-integrations/javascript-sdk/server-side-node/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
"author": "",
1717
"license": "Apache-2.0",
1818
"dependencies": {
19-
"axios": "^1.6.0",
19+
"@uid2/uid2-sdk": "^4.0.1",
20+
"@unified-id/euid-sdk": "^4.0.1",
2021
"cookie-session": "^2.0.0",
2122
"dotenv": "^16.0.3",
2223
"ejs": "^3.1.9",
2324
"express": "^4.18.2",
2425
"jsdom": "^23.0.0",
25-
"nocache": "^4.0.0"
26+
"nocache": "^4.0.0",
27+
"xhr2": "^0.2.1"
2628
},
2729
"devDependencies": {
2830
"nodemon": "^3.0.1"

web-integrations/javascript-sdk/server-side-node/server.js

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,76 +8,94 @@ const ejs = require('ejs');
88
const express = require('express');
99
const nocache = require('nocache');
1010
const { JSDOM } = require('jsdom');
11-
const axios = require('axios');
1211
const crypto = require('crypto');
1312
const util = require('util');
13+
const XMLHttpRequest = require('xhr2');
1414

1515
const app = express();
1616
const port = process.env.PORT || 3034;
1717

1818
let uidBaseUrl = process.env.UID_SERVER_BASE_URL;
1919
const subscriptionId = process.env.UID_CSTG_SUBSCRIPTION_ID;
2020
const serverPublicKey = process.env.UID_CSTG_SERVER_PUBLIC_KEY;
21-
const uidJsSdkUrl = process.env.UID_JS_SDK_URL;
22-
const uidJsSdkName = process.env.UID_JS_SDK_NAME;
2321

2422
// UI/Display configuration
2523
const identityName = process.env.IDENTITY_NAME;
2624
const docsBaseUrl = process.env.DOCS_BASE_URL;
2725

26+
// SDK will be loaded dynamically (it's an ES module)
27+
let SdkClass = null;
28+
2829
// Initialize UID JavaScript SDK in a simulated browser environment using jsdom
2930
// This demonstrates that the client-side SDK works in Node.js with jsdom
3031
let uidSdk = null;
3132
let dom = null;
3233

3334
async function initializeSDK() {
34-
// Create a virtual DOM environment
35+
// Create a virtual DOM environment for the SDK to run in
36+
// NOTE: The origin 'http://localhost:3034' must be added to your CSTG subscription's
37+
// allowed origins list by your UID2/EUID representative
3538
dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
36-
url: 'http://localhost',
39+
url: 'http://localhost:3034',
3740
runScripts: 'dangerously',
3841
resources: 'usable',
3942
pretendToBeVisual: true,
4043
});
4144

42-
// Set global variables for the SDK
45+
// Set global variables for the SDK (SDK expects browser globals)
4346
global.window = dom.window;
4447
global.document = dom.window.document;
4548
global.navigator = dom.window.navigator;
4649
global.localStorage = dom.window.localStorage;
4750

48-
// Polyfill Web Crypto API for jsdom
49-
// The SDK needs window.crypto.subtle for encryption
51+
// Polyfill Web Crypto API for jsdom (SDK uses crypto.subtle for encryption)
5052
Object.defineProperty(dom.window, 'crypto', {
5153
value: crypto.webcrypto,
5254
writable: false,
5355
configurable: true
5456
});
5557

56-
// Polyfill TextEncoder and TextDecoder (required by the SDK)
58+
// Polyfill TextEncoder and TextDecoder (required by SDK for string/byte conversion)
5759
global.TextEncoder = util.TextEncoder;
5860
global.TextDecoder = util.TextDecoder;
5961
dom.window.TextEncoder = util.TextEncoder;
6062
dom.window.TextDecoder = util.TextDecoder;
6163

62-
// Load the UID SDK script from CDN
63-
try {
64-
const response = await axios.get(uidJsSdkUrl);
65-
66-
// Execute the SDK code in the jsdom context
67-
const scriptEl = dom.window.document.createElement('script');
68-
scriptEl.textContent = response.data;
69-
dom.window.document.body.appendChild(scriptEl);
70-
71-
// Wait for the SDK to initialize
72-
await new Promise(resolve => setTimeout(resolve, 100));
64+
// Polyfill XMLHttpRequest with Origin header support
65+
// The SDK needs the Origin header to be set for CSTG validation
66+
const OriginalXHR = XMLHttpRequest;
67+
class XMLHttpRequestWithOrigin extends OriginalXHR {
68+
constructor() {
69+
super();
70+
this._origin = 'http://localhost:3034';
71+
}
7372

74-
// Get reference to the SDK
75-
uidSdk = dom.window[uidJsSdkName];
76-
if (!uidSdk) {
77-
throw new Error(`SDK not found at window.${uidJsSdkName}`);
73+
open(method, url, async) {
74+
const result = super.open(method, url, async);
75+
// Set Origin header immediately after open (required for CSTG)
76+
super.setRequestHeader('Origin', this._origin);
77+
return result;
7878
}
79+
}
80+
81+
global.XMLHttpRequest = XMLHttpRequestWithOrigin;
82+
dom.window.XMLHttpRequest = XMLHttpRequestWithOrigin;
83+
84+
try {
85+
// Dynamically import the SDK (it's an ES module)
86+
const isEUID = identityName && identityName.toUpperCase() === 'EUID';
87+
if (isEUID) {
88+
const { EUID } = await import('@unified-id/euid-sdk');
89+
SdkClass = EUID;
90+
} else {
91+
const { UID2 } = await import('@uid2/uid2-sdk');
92+
SdkClass = UID2;
93+
}
94+
95+
// Instantiate the SDK (UID2 or EUID based on config)
96+
uidSdk = new SdkClass();
7997

80-
// Initialize the SDK
98+
// Initialize the SDK with base URL
8199
uidSdk.init({ baseUrl: uidBaseUrl });
82100

83101
return uidSdk;

0 commit comments

Comments
 (0)