67 lines
2.5 KiB
JavaScript
67 lines
2.5 KiB
JavaScript
import crypto from 'node:crypto';
|
|
import dotenv from 'dotenv';
|
|
|
|
dotenv.config({ path: '.env.development' });
|
|
process.env.NODE_ENV = 'development';
|
|
process.env.SAAS_TO_PIM_SHARED_SECRET = crypto.randomBytes(32).toString('hex');
|
|
|
|
const { connectDatabase, default: sequelize } = await import('../src/shared/database/connection.js');
|
|
await connectDatabase();
|
|
const { default: app } = await import('../app.js');
|
|
const { signatureFor } = await import('../src/shared/middleware/saasTrust.middleware.js');
|
|
|
|
const payload = {
|
|
canonical_tenant_id: 'e2f12014-4828-4ac7-95e9-ee99a736c38c',
|
|
tenant_name: 'Microservice Tenant',
|
|
tenant_domain: 'mstenant.com',
|
|
is_active: true
|
|
};
|
|
|
|
const body = JSON.stringify(payload);
|
|
const server = app.listen(0, '127.0.0.1');
|
|
await new Promise((resolve, reject) => {
|
|
server.once('listening', resolve);
|
|
server.once('error', reject);
|
|
});
|
|
|
|
const { port } = server.address();
|
|
const endpoint = `http://127.0.0.1:${port}/api/v1/internal/saas/tenants/provision`;
|
|
|
|
async function send({ validSignature = true } = {}) {
|
|
const timestamp = String(Date.now());
|
|
const signature = validSignature
|
|
? signatureFor({ timestamp, rawBody: Buffer.from(body), secret: process.env.SAAS_TO_PIM_SHARED_SECRET })
|
|
: '0'.repeat(64);
|
|
const response = await fetch(endpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'content-type': 'application/json',
|
|
'x-saas-timestamp': timestamp,
|
|
'x-saas-signature': signature
|
|
},
|
|
body
|
|
});
|
|
return { status: response.status, json: await response.json() };
|
|
}
|
|
|
|
try {
|
|
const first = await send();
|
|
if (![200, 201].includes(first.status) || !first.json?.success) throw new Error(`First provisioning failed: ${JSON.stringify(first)}`);
|
|
const second = await send();
|
|
if (second.status !== 200 || second.json?.created !== false) throw new Error(`Idempotent retry failed: ${JSON.stringify(second)}`);
|
|
if (first.json.data.id !== second.json.data.id) throw new Error('Provisioning retry returned a different PIM tenant');
|
|
const rejected = await send({ validSignature: false });
|
|
if (rejected.status !== 401) throw new Error(`Invalid signature was not rejected: ${JSON.stringify(rejected)}`);
|
|
console.log(JSON.stringify({
|
|
success: true,
|
|
canonicalTenantId: payload.canonical_tenant_id,
|
|
pimTenantId: first.json.data.id,
|
|
firstStatus: first.status,
|
|
retryStatus: second.status,
|
|
invalidSignatureStatus: rejected.status
|
|
}, null, 2));
|
|
} finally {
|
|
await new Promise(resolve => server.close(resolve));
|
|
await sequelize.close();
|
|
}
|