Skip to content

Commit f5505bd

Browse files
clean up comments in server.js
1 parent f31fcc7 commit f5505bd

File tree

1 file changed

+37
-98
lines changed
  • web-integrations/prebid-integrations/client-server

1 file changed

+37
-98
lines changed
Lines changed: 37 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
1-
// ============================================================================
2-
// UID2 Prebid.js Client-Server Integration Example - Server
3-
// ============================================================================
4-
// This server demonstrates how to generate UID2 tokens on the server side
5-
// for use with Prebid.js in a client-server integration.
6-
//
7-
// Key responsibilities:
8-
// 1. Accept user email from the front-end
9-
// 2. Encrypt the email and send it to the UID2 API
10-
// 3. Decrypt the UID2 token response
11-
// 4. Return the token to the front-end for use with Prebid.js
12-
// ============================================================================
13-
1+
// UID2 Prebid.js Client-Server Integration - Server
2+
// Generates UID2 tokens server-side for use with Prebid.js
143

154
require('dotenv').config({path: '../../../.env'});
165

@@ -21,86 +10,52 @@ const crypto = require('crypto');
2110
const app = express();
2211
const port = 3052;
2312

24-
// UID2 API Configuration
25-
// These values should be set via environment variables for security
13+
// UID2 API Configuration (set via .env file)
2614
const uid2BaseUrl = process.env.UID2_BASE_URL || 'https://operator-integ.uidapi.com';
27-
const uid2ApiKey = process.env.UID2_API_KEY; // Your API Key from UID2 Portal
28-
const uid2ClientSecret = process.env.UID2_CLIENT_SECRET; // Your Client Secret from UID2 Portal
15+
const uid2ApiKey = process.env.UID2_API_KEY;
16+
const uid2ClientSecret = process.env.UID2_CLIENT_SECRET;
2917

30-
// Encryption constants required by UID2 API
31-
const ivLength = 12;
32-
const nonceLength = 8;
33-
const timestampLength = 8;
34-
const encryptionAlgo = 'aes-256-gcm';
18+
// Encryption constants
19+
const ivLength = 12;
20+
const nonceLength = 8;
21+
const timestampLength = 8;
22+
const encryptionAlgo = 'aes-256-gcm';
3523

36-
// Middleware setup
37-
app.use(express.static('public'));
38-
app.use(express.json());
39-
app.use(express.urlencoded({ extended: true }));
24+
// Middleware
25+
app.use(express.static('public'));
26+
app.use(express.json());
27+
app.use(express.urlencoded({ extended: true }));
4028

4129
// ============================================================================
42-
// HELPER FUNCTIONS FOR ENCRYPTION/DECRYPTION
30+
// Encryption/Decryption Helpers
4331
// ============================================================================
44-
// The UID2 API requires all requests and responses to be encrypted for security.
45-
// These functions handle the encryption/decryption process.
46-
47-
/**
48-
* Converts a Buffer to a base64-encoded string
49-
* @param {Buffer} arrayBuffer - The buffer to convert
50-
* @returns {string} Base64-encoded string
51-
*/
32+
5233
function bufferToBase64(arrayBuffer) {
5334
return Buffer.from(arrayBuffer).toString('base64');
5435
}
5536

56-
/**
57-
* Converts a base64-encoded string back to a Buffer
58-
* @param {string} base64 - The base64 string to convert
59-
* @returns {Buffer} The decoded buffer
60-
*/
6137
function base64ToBuffer(base64) {
6238
return Buffer.from(base64, 'base64');
6339
}
6440

65-
/**
66-
* Encrypts a message using AES-256-GCM encryption
67-
* This is required by the UID2 API to protect user data in transit.
68-
* @param {string|Buffer} message - The message to encrypt (typically user email)
69-
* @param {string} base64Key - Your UID2 Client Secret (base64-encoded)
70-
* @returns {Object} Object containing the ciphertext and initialization vector
71-
*/
41+
// Encrypts data using AES-256-GCM
7242
function encryptRequest(message, base64Key) {
7343
const iv = crypto.randomBytes(ivLength);
7444
const cipher = crypto.createCipheriv(encryptionAlgo, base64ToBuffer(base64Key), iv);
7545
const ciphertext = Buffer.concat([cipher.update(message), cipher.final(), cipher.getAuthTag()]);
76-
77-
return { ciphertext: ciphertext, iv: iv };
46+
return { ciphertext, iv };
7847
}
7948

80-
/**
81-
* Compares two byte arrays for equality
82-
* Used to verify that the nonce in the response matches the request (prevents tampering)
83-
* @param {Uint8Array} array1 - First array to compare
84-
* @param {Uint8Array} array2 - Second array to compare
85-
* @returns {boolean} True if arrays are equal, false otherwise
86-
*/
49+
// Compares two byte arrays
8750
function isEqual(array1, array2) {
8851
for (let i = 0; i < array1.byteLength; i++) {
8952
if (array1[i] !== array2[i]) return false;
9053
}
9154
return true;
9255
}
9356

94-
/**
95-
* Decrypts a response from the UID2 API
96-
* Verifies the nonce to ensure the response hasn't been tampered with.
97-
* @param {string} base64Response - The encrypted response from UID2 API
98-
* @param {string} base64Key - Your UID2 Client Secret (base64-encoded)
99-
* @param {Buffer} nonceInRequest - The nonce that was sent in the request
100-
* @returns {Object} The decrypted JSON response containing the UID2 token
101-
* @throws {Error} If the nonce doesn't match (indicates tampering)
102-
*/
103-
function decrypt(base64Response, base64Key, nonceInRequest) {
57+
// Decrypts UID2 API response and verifies nonce
58+
function decrypt(base64Response, base64Key, nonceInRequest) {
10459
const responseBytes = base64ToBuffer(base64Response);
10560
const iv = responseBytes.subarray(0, ivLength);
10661

@@ -110,25 +65,23 @@ function decrypt(base64Response, base64Key, nonceInRequest) {
11065
const tag = responseBytes.subarray(responseBytes.length - tagLength);
11166
decipher.setAuthTag(tag);
11267

113-
const decrypted = Buffer.concat([decipher.update(responseBytes.subarray(ivLength, responseBytes.length - tagLength)), decipher.final()]);
68+
const decrypted = Buffer.concat([
69+
decipher.update(responseBytes.subarray(ivLength, responseBytes.length - tagLength)),
70+
decipher.final()
71+
]);
11472

73+
// Verify nonce matches
11574
const nonceInResponse = decrypted.subarray(timestampLength, timestampLength + nonceLength);
11675
if (!isEqual(nonceInRequest, new Uint8Array(nonceInResponse))) {
117-
throw new Error('Nonce in request does not match nonce in response');
76+
throw new Error('Nonce mismatch');
11877
}
119-
const payload = decrypted.subarray(timestampLength + nonceLength);
12078

79+
const payload = decrypted.subarray(timestampLength + nonceLength);
12180
const responseString = String.fromCharCode.apply(String, new Uint8Array(payload));
12281
return JSON.parse(responseString);
12382
}
12483

125-
/**
126-
* Creates an encrypted "envelope" to send to the UID2 API
127-
* The envelope contains: timestamp, nonce, and the payload (user email)
128-
* This format is required by the UID2 API for all token generation requests.
129-
* @param {string} payload - The JSON string to encrypt (e.g., '{"email": "user@example.com"}')
130-
* @returns {Object} Object containing the encrypted envelope and nonce
131-
*/
84+
// Creates encrypted envelope for UID2 API request
13285
function createEnvelope(payload) {
13386
const millisec = BigInt(Date.now());
13487
const bufferMillisec = new ArrayBuffer(timestampLength);
@@ -140,28 +93,16 @@ function createEnvelope(payload) {
14093

14194
const { ciphertext, iv } = encryptRequest(body, uid2ClientSecret);
14295

143-
const envelopeVersion = Buffer.alloc(1, 1);
144-
const envelope = bufferToBase64(Buffer.concat([envelopeVersion, iv, Buffer.from( new Uint8Array(ciphertext))]));
145-
return { envelope: envelope, nonce: nonce };
96+
const envelopeVersion = Buffer.alloc(1, 1);
97+
const envelope = bufferToBase64(Buffer.concat([envelopeVersion, iv, Buffer.from(new Uint8Array(ciphertext))]));
98+
return { envelope, nonce };
14699
}
147100

148101
// ============================================================================
149-
// API ENDPOINT: Token Generation
102+
// API Endpoint
150103
// ============================================================================
151104

152-
/**
153-
* POST /login
154-
* Generates a UID2 token for the given email address
155-
*
156-
* This endpoint:
157-
* 1. Receives an email from the front-end
158-
* 2. Encrypts it and sends to UID2 API's /v2/token/generate endpoint
159-
* 3. Decrypts the response
160-
* 4. Returns the UID2 identity (token) as JSON to the front-end
161-
*
162-
* Request body: { email: "user@example.com" }
163-
* Response: { identity: { advertising_token: "...", refresh_token: "...", ... } }
164-
*/
105+
// POST /login - Generates UID2 token for email address
165106
app.post('/login', async (req, res) => {
166107
const jsonEmail = JSON.stringify({ email: req.body.email });
167108
const { envelope, nonce } = createEnvelope(jsonEmail);
@@ -179,14 +120,12 @@ app.post('/login', async (req, res) => {
179120
const response = decrypt(encryptedResponse.data, uid2ClientSecret, nonce);
180121

181122
if (response.status === 'optout') {
182-
// Opt-out is a valid state, return 200 with status
183123
res.json({ status: 'optout' });
184124
} else if (response.status !== 'success') {
185125
res.status(400).json({ error: 'Token generation failed', status: response.status });
186126
} else if (typeof response.body !== 'object') {
187127
res.status(400).json({ error: 'Unexpected response format' });
188128
} else {
189-
// Return the identity (UID2 token) as JSON
190129
res.json({ identity: response.body });
191130
}
192131
} catch (error) {
@@ -196,9 +135,9 @@ app.post('/login', async (req, res) => {
196135
});
197136

198137
// ============================================================================
199-
// START THE SERVER
138+
// Start Server
200139
// ============================================================================
140+
201141
app.listen(port, () => {
202-
console.log(`UID2 Prebid Client-Server example listening at http://localhost:${port}`);
142+
console.log(`UID2 Prebid Client-Server example listening at http://localhost:${port}`);
203143
});
204-

0 commit comments

Comments
 (0)