-
Notifications
You must be signed in to change notification settings - Fork 0
Create server-side app using javascript sdk #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
eiman-eltigani-ttd
wants to merge
19
commits into
main
Choose a base branch
from
eee-UID2-4799-create-server-side-node-app-with-js-sdk
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
027c048
Create new subfolder for server side javascript sdk
eiman-eltigani-ttd 9a877cc
create working example using js sdk on server
eiman-eltigani-ttd b4e4fe0
simplify ui
eiman-eltigani-ttd 8701ecb
simplify error ui to match previous server side example
eiman-eltigani-ttd 0611f7d
simplify logging and functionality in server.js
eiman-eltigani-ttd 6e330e0
improve ui langauage and description of page
eiman-eltigani-ttd 6b499a7
update readme to be consistent with other sdk readmes
eiman-eltigani-ttd 986f3be
update defintion of env variable in readme
eiman-eltigani-ttd 2208be0
fix optout bug by clearing session and clean up logs
eiman-eltigani-ttd 9f5f9bf
more comment clean up
eiman-eltigani-ttd 0ee4b54
replace uid2 references with generic naming
eiman-eltigani-ttd 1fbaa6f
simplify error page to reflect new sdk responses
eiman-eltigani-ttd 8c6e154
rename folder and reorganize readme
eiman-eltigani-ttd f1ca4b6
more readme clean up
eiman-eltigani-ttd 4b2fb16
import npm package instead of script
eiman-eltigani-ttd 152fad6
clean up comments
eiman-eltigani-ttd 0b5ec06
add new env variable to sample files
eiman-eltigani-ttd 189b3e5
add link to npm packages in readme
eiman-eltigani-ttd dc22b34
update title
eiman-eltigani-ttd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
web-integrations/javascript-sdk/server-side-node/.gitignore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Dependencies | ||
| node_modules/ | ||
| package-lock.json | ||
|
|
||
| # Logs | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
|
|
||
| # Environment variables | ||
| .env | ||
| .env.local | ||
| .env.*.local | ||
|
|
||
| # OS files | ||
| .DS_Store | ||
|
|
17 changes: 17 additions & 0 deletions
17
web-integrations/javascript-sdk/server-side-node/Dockerfile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| FROM node:20.11.0-alpine3.18 | ||
|
|
||
| WORKDIR /usr/src/app | ||
|
|
||
| # Copy package files first for better caching | ||
| COPY web-integrations/javascript-sdk/server-side-node/package*.json ./ | ||
| RUN npm install | ||
|
|
||
| # Copy application files | ||
| COPY web-integrations/javascript-sdk/server-side-node/server.js ./ | ||
| COPY web-integrations/javascript-sdk/server-side-node/public ./public/ | ||
| COPY web-integrations/javascript-sdk/server-side-node/views ./views/ | ||
|
|
||
| ENV PORT=3034 | ||
| EXPOSE 3034 | ||
| CMD ["npm", "start"] | ||
|
|
101 changes: 101 additions & 0 deletions
101
web-integrations/javascript-sdk/server-side-node/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # Server-Side UID2 or EUID Integration Example using JavaScript SDK via Node.js | ||
|
|
||
| This example showcases how the UID2/EUID **JavaScript SDK works in Node.js** server environments. It uses the same `setIdentityFromEmail` method that runs in browsers, but executes it on the server. This uses **public credentials** (Subscription ID + Server Public Key) which are the same credentials used for client-side integrations. | ||
|
|
||
| For more information on the JavaScript SDK, refer to the [UID2 SDK for JavaScript](https://unifiedid.com/docs/sdks/sdk-ref-javascript) or [EUID SDK for JavaScript](https://euid.eu/docs/sdks/sdk-ref-javascript) documentation. | ||
|
|
||
| > **Note:** This example can be configured for either UID2 or EUID — the behavior is determined by your environment variable configuration. You cannot use both simultaneously. | ||
|
|
||
| ## How This Implementation Works | ||
|
|
||
| Unlike the browser where the SDK runs natively in the DOM, this example uses **jsdom** to simulate a browser environment within Node.js: | ||
|
|
||
| 1. **Imports the SDK**: Uses npm packages [`@uid2/uid2-sdk`](https://www.npmjs.com/package/@uid2/uid2-sdk) or [`@unified-id/euid-sdk`](https://www.npmjs.com/package/@unified-id/euid-sdk) (selected dynamically based on the `IDENTITY_NAME` environment variable) | ||
| 2. **Creates a virtual DOM**: Uses jsdom to provide `window`, `document`, and `navigator` objects that the SDK expects | ||
| 3. **Polyfills browser APIs**: Adds Node.js equivalents for Web Crypto API (`crypto.subtle`) and text encoding APIs (`TextEncoder`/`TextDecoder`) | ||
| 4. **Instantiates the SDK**: Creates a new instance of `UID2` or `EUID` class | ||
| 5. **Runs SDK methods**: Calls `setIdentityFromEmail` just like in a browser, with the same public credentials | ||
|
|
||
| This demonstrates that the client-side SDK can be compatible with server-side Node.js environments when given the proper browser-like context. | ||
|
|
||
| ## Build and Run the Example Application | ||
|
|
||
| ### Using Docker Compose (Recommended) | ||
|
|
||
| From the repository root directory: | ||
|
|
||
| ```bash | ||
| # Start the service | ||
| docker compose up javascript-sdk-server-side | ||
| ``` | ||
|
|
||
| The application will be available at http://localhost:3034 | ||
|
|
||
| To view logs or stop the service: | ||
|
|
||
| ```bash | ||
| # View logs (in another terminal) | ||
| docker compose logs javascript-sdk-server-side | ||
|
|
||
| # Stop the service | ||
| docker compose stop javascript-sdk-server-side | ||
| ``` | ||
|
|
||
| ### Using Docker Build | ||
|
|
||
| ```bash | ||
| # Build the image | ||
| docker build -f web-integrations/javascript-sdk/server-side/Dockerfile -t javascript-sdk-server-side . | ||
|
|
||
| # Run the container | ||
| docker run -it --rm -p 3034:3034 --env-file .env javascript-sdk-server-side | ||
| ``` | ||
|
|
||
| ## Environment Variables | ||
|
|
||
| The following table lists the environment variables that you must specify to start the application. | ||
|
|
||
| ### Core Configuration | ||
|
|
||
| | Variable | Description | Example Values | | ||
| |:---------|:------------|:---------------| | ||
| | `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` | | ||
| | `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`) | | ||
| | `UID_CSTG_SERVER_PUBLIC_KEY` | Your UID2/EUID server public key for Client-Side Token Generation. **These are public credentials.** | Your assigned public key | | ||
| | `UID_CSTG_ORIGIN` | The public URL where this application is deployed. Must match your CSTG subscription's allowed origins. | `https://your-domain.com` (production)<br/>`http://localhost:3034` (local dev default) | | ||
| | `SESSION_KEY` | Used by the cookie-session middleware to encrypt the session data stored in cookies. | Any secure random string | | ||
|
|
||
| ### Display/UI Configuration | ||
|
|
||
| | Variable | Description | Example Values | | ||
| |:---------|:------------|:---------------| | ||
| | `IDENTITY_NAME` | Identity name for UI display | UID2: `UID2`<br/>EUID: `EUID` | | ||
| | `DOCS_BASE_URL` | Documentation base URL | UID2: `https://unifiedid.com/docs`<br/>EUID: `https://euid.eu/docs` | | ||
|
|
||
| After you see output similar to the following, the example application is up and running: | ||
|
|
||
| ``` | ||
| Server listening at http://localhost:3034 | ||
| ``` | ||
|
|
||
| If needed, to close the application, terminate the docker container or use the `Ctrl+C` keyboard shortcut. | ||
|
|
||
| ## Test the Example Application | ||
|
|
||
| The following table outlines and annotates the steps you may take to test and explore the example application. | ||
|
|
||
| | Step | Description | Comments | | ||
| |:----:|:------------|:---------| | ||
| | 1 | In your browser, navigate to the application main page at `http://localhost:3034`. | The displayed main (index) page provides a login form for the user to complete the UID2/EUID login process.</br>IMPORTANT: A real-life application must also display a form for the user to express their consent to targeted advertising. | | ||
| | 2 | Enter the user email address that you want to use for testing and click **Log In**. | This is a call to the `/login` endpoint ([server.js](server.js)). The login initiated on the server side uses the JavaScript SDK's `setIdentityFromEmail` method to generate a token and processes the received response. The SDK handles all encryption/decryption automatically, just as it does in the browser. | | ||
| | | The main page is updated to display the established identity information. | The displayed identity information is the `body` property of the response from the SDK's `setIdentityFromEmail` call. If the response is successful, the returned identity is saved to a session cookie (a real-world application would use a different way to store session data) and the protected index page is rendered. | | ||
| | 3 | Review the displayed identity information. | The server reads the user session and extracts the current identity ([server.js](server.js)). The `advertising_token` on the identity can be used for targeted advertising. Note that the identity contains several timestamps that determine when the advertising token becomes invalid (`identity_expires`) and when the server should attempt to refresh it (`refresh_from`). The `verifyIdentity` function ([server.js](server.js)) uses the SDK to refresh the token as needed.<br/>The user is automatically logged out in the following cases:<br/>- If the identity expires without being refreshed and refresh attempt fails.<br/>- If the refresh token expires.<br/>- If the refresh attempt indicates that the user has opted out. | | ||
| | 4 | To exit the application, click **Log Out**. | This calls the `/logout` endpoint on the server ([server.js](server.js)), which clears the session and presents the user with the login form again.<br/> NOTE: The page displays the **Log Out** button as long as the user is logged in. | | ||
|
|
||
| ## Key Benefits | ||
|
|
||
| This example demonstrates the advantages of using the JavaScript SDK on the server: | ||
|
|
||
| - **Secure credential handling**: Public credentials (server public key and subscription ID) remain on the server and are not exposed to the browser | ||
| - **Simplified implementation**: The SDK handles the full token lifecycle including encryption, decryption, and refresh logic automatically | ||
| - **No manual cryptography**: Unlike traditional server-side integrations, there's no need to manually implement encryption/decryption processes |
33 changes: 33 additions & 0 deletions
33
web-integrations/javascript-sdk/server-side-node/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "name": "uid2-javascript-sdk-server-side", | ||
| "version": "1.0.0", | ||
| "description": "Server-Side UID2/EUID Integration Example using JavaScript SDK", | ||
| "main": "server.js", | ||
| "scripts": { | ||
| "start": "node server.js", | ||
| "dev": "nodemon server.js" | ||
| }, | ||
| "keywords": [ | ||
| "uid2", | ||
| "euid", | ||
| "identity", | ||
| "server-side" | ||
| ], | ||
| "author": "", | ||
| "license": "Apache-2.0", | ||
| "dependencies": { | ||
| "@uid2/uid2-sdk": "^4.0.1", | ||
| "@unified-id/euid-sdk": "^4.0.1", | ||
| "cookie-session": "^2.0.0", | ||
| "dotenv": "^16.0.3", | ||
| "ejs": "^3.1.9", | ||
| "express": "^4.18.2", | ||
| "jsdom": "^23.0.0", | ||
| "nocache": "^4.0.0", | ||
| "xhr2": "^0.2.1" | ||
| }, | ||
| "devDependencies": { | ||
| "nodemon": "^3.0.1" | ||
| } | ||
| } | ||
|
|
Binary file added
BIN
+1.93 KB
web-integrations/javascript-sdk/server-side-node/public/images/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 99 additions & 0 deletions
99
web-integrations/javascript-sdk/server-side-node/public/stylesheets/app.css
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| body { | ||
| padding: 50px; | ||
| font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; | ||
| } | ||
|
|
||
| a { | ||
| color: #00B7FF; | ||
| } | ||
|
|
||
| .button { | ||
| border-style: none; | ||
| cursor: pointer; | ||
| align-items: center; | ||
| height: 40px; | ||
| width: 401px; | ||
| text-align: center; | ||
| position: absolute; | ||
| letter-spacing: 0.28px; | ||
| box-sizing: border-box; | ||
| color: white; | ||
| font-family: 'Raleway', Helvetica, Arial, serif; | ||
| font-size: 14px; | ||
| font-style: normal; | ||
| font-weight: 700; | ||
| text-transform: none; | ||
| text-indent: 0px; | ||
| text-shadow: none; | ||
| margin: 0em; | ||
| padding: 1px 6px; | ||
| background-color: rgba(2,10,64,1.0); | ||
| border-image: initial | ||
| } | ||
|
|
||
| .form { | ||
| margin-top: 40px; | ||
| } | ||
|
|
||
| .email_prompt { | ||
| align-items: center; | ||
| align-self: center; | ||
| background-color: white; | ||
| border: 1px solid rgba(2,10,64,1.0); | ||
| border-radius: 2px; | ||
| box-sizing: border-box; | ||
| display: inline-flex; | ||
| flex-direction: row; | ||
| flex-shrink: 0; | ||
| height: 40px; | ||
| justify-content: flex-start; | ||
| margin-right: 1.0px; | ||
| margin-bottom: 20px; | ||
| min-width: 399px; | ||
| padding: 0 16.0px; | ||
| position: relative; | ||
| width: auto; | ||
| } | ||
|
|
||
| #email { | ||
| background-color: white; | ||
| flex-shrink: 0; | ||
| height: auto; | ||
| letter-spacing: 0.12px; | ||
| line-height: 16px; | ||
| min-height: 16px; | ||
| position: relative; | ||
| text-align: left; | ||
| white-space: nowrap; | ||
| width: 351px; | ||
| color: rgba(2,10,64,1.0); | ||
| font-family: 'Raleway', Helvetica, Arial, serif; | ||
| font-size: 12px; | ||
| font-style: normal; | ||
| font-weight: 500; | ||
| padding: 1px 2px; | ||
| outline: none; | ||
| } | ||
|
|
||
| h1 { | ||
| padding-bottom: 20px; | ||
| } | ||
|
|
||
| #uid2_state .label { | ||
| white-space: nowrap; | ||
| padding-right: 20px; | ||
| } | ||
| #uid2_state tr { | ||
| margin-top: 10px; | ||
| } | ||
|
|
||
| .message { | ||
| color: green; | ||
| padding: 20px; | ||
| margin-left: -22px; | ||
| font-size: 16px; | ||
| font-weight: 500; | ||
| border: 2px solid green; | ||
| border-radius: 5px; | ||
| } | ||
|
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is added since we have to replicate our own CORS/origin header on node.js