import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.json());
// HMAC signature generation
function generateHmacSignature(privateKey, method, path, body) {
const bodyJson = JSON.stringify(body);
const canonical = `${method.toUpperCase()}|${path}|${bodyJson}`;
const hmac = crypto.createHmac('sha256', privateKey);
hmac.update(canonical);
return hmac.digest('hex');
}
// Validate entitlements endpoint
app.post('/api/validate-entitlements', async (req, res) => {
try {
const { userId } = req.body;
if (!userId) {
return res.status(400).json({ error: 'userId is required' });
}
const method = 'POST';
const path = '/encore/v1/entitlements/server';
const body = { user_id: userId };
const signature = generateHmacSignature(
process.env.ENCORE_PRIVATE_API_KEY,
method,
path,
body
);
const timestamp = Math.floor(Date.now() / 1000);
const response = await fetch(`${process.env.ENCORE_BASE_URL}${path}`, {
method,
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.ENCORE_PUBLIC_API_KEY,
'X-Signature': signature,
'X-Timestamp': timestamp.toString(),
},
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(`Encore API error: ${response.statusText}`);
}
const entitlements = await response.json();
res.json(entitlements);
} catch (error) {
console.error('Validation error:', error);
res.status(500).json({ error: 'Failed to validate entitlements' });
}
});
// Check specific entitlement
app.post('/api/check-entitlement', async (req, res) => {
try {
const { userId, entitlementType, scope = 'all' } = req.body;
// Get all entitlements
const entitlements = await validateEntitlements(userId);
// Check specific entitlement in scope
const scopeData = entitlements[scope] || {};
const isActive = scopeData.hasOwnProperty(entitlementType);
res.json({
isActive,
entitlementType,
scope,
details: isActive ? scopeData[entitlementType] : null,
});
} catch (error) {
console.error('Check entitlement error:', error);
res.status(500).json({ error: 'Failed to check entitlement' });
}
});
// Helper function
async function validateEntitlements(userId) {
const method = 'POST';
const path = '/encore/v1/entitlements/server';
const body = { user_id: userId };
const signature = generateHmacSignature(
process.env.ENCORE_PRIVATE_API_KEY,
method,
path,
body
);
const timestamp = Math.floor(Date.now() / 1000);
const response = await fetch(`${process.env.ENCORE_BASE_URL}${path}`, {
method,
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.ENCORE_PUBLIC_API_KEY,
'X-Signature': signature,
'X-Timestamp': timestamp.toString(),
},
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(`Encore API error: ${response.statusText}`);
}
return await response.json();
}
app.listen(3000, () => {
console.log('Server running on port 3000');
});