Add template animation editor

This commit is contained in:
2026-08-03 17:27:42 +01:00
parent e95928f31c
commit ed8d51580e
35 changed files with 3173 additions and 44 deletions
+103
View File
@@ -0,0 +1,103 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const {
createPageAuthBundle,
createPageAuthToken,
createPageFetchAuthScript,
createRequestAuthHeaders,
verifyPageAuthToken,
verifyRequestAuth,
PAGE_TOKEN_HEADER,
REQUEST_SIGNATURE_HEADER,
REQUEST_TIMESTAMP_HEADER
} = require('../src/request-auth');
const originalSecret = process.env.PULSE_SIGNAGE_SHARED_SECRET;
function setSecret(value) {
process.env.PULSE_SIGNAGE_SHARED_SECRET = value;
}
test.after(() => {
if (originalSecret === undefined) {
delete process.env.PULSE_SIGNAGE_SHARED_SECRET;
} else {
process.env.PULSE_SIGNAGE_SHARED_SECRET = originalSecret;
}
});
test('request auth headers verify empty parser bodies as null payloads', () => {
setSecret('test-secret');
const originalNow = Date.now;
Date.now = () => 1700000000000;
try {
const headers = createRequestAuthHeaders({ method: 'POST', pathname: '/api/media/config', body: null, timestamp: 1700000000000 });
const req = {
method: 'POST',
path: '/api/media/config',
body: {},
headers: {
[REQUEST_TIMESTAMP_HEADER]: headers[REQUEST_TIMESTAMP_HEADER],
[REQUEST_SIGNATURE_HEADER]: headers[REQUEST_SIGNATURE_HEADER]
}
};
assert.equal(verifyRequestAuth(req), true);
} finally {
Date.now = originalNow;
}
});
test('page auth bundles round-trip and expire as expected', () => {
setSecret('test-secret');
const originalNow = Date.now;
Date.now = () => 1700000000000;
try {
const bundle = createPageAuthBundle({ scope: 'player', slug: 'test2' });
assert.equal(typeof bundle.token, 'string');
assert.equal(bundle.issuedAt, 1700000000000);
assert.equal(bundle.expiresAt, 1700043200000);
assert.deepEqual(verifyPageAuthToken(bundle.token), {
scope: 'player',
slug: 'test2',
issuedAt: 1700000000000,
expiresAt: 1700043200000
});
assert.equal(createPageAuthToken({ scope: 'player' }).split('.').length, 2);
Date.now = () => 1700043200001;
assert.equal(verifyPageAuthToken(bundle.token), null);
} finally {
Date.now = originalNow;
}
});
test('request auth rejects mismatched signatures', () => {
setSecret('test-secret');
const headers = createRequestAuthHeaders({ method: 'PUT', pathname: '/api/media/config', body: { hello: 'world' }, timestamp: 1700000000000 });
const req = {
method: 'PUT',
path: '/api/media/config',
body: { hello: 'changed' },
headers: {
[REQUEST_TIMESTAMP_HEADER]: headers[REQUEST_TIMESTAMP_HEADER],
[REQUEST_SIGNATURE_HEADER]: headers[REQUEST_SIGNATURE_HEADER]
}
};
assert.equal(verifyRequestAuth(req), false);
assert.equal(PAGE_TOKEN_HEADER, 'x-pulse-page-auth');
});
test('page fetch auth script injects renew and header logic', () => {
const script = createPageFetchAuthScript({ token: 'abc123', expiresAt: 1700000000000 });
assert.match(script, /window\.__pulsePageAuthToken = pageAuthToken/);
assert.match(script, /"x-pulse-page-auth"/);
assert.match(script, /\/api\/auth\/page/);
assert.match(script, /abc123/);
});