Files
safetynet/tests/branding.test.mjs

5 lines
3.1 KiB
JavaScript

import test from 'node:test';import assert from 'node:assert/strict';import {BrandSchema,StartPageSchema} from '../packages/core/branding.mjs';import {defaultPolicy,verifyPolicy} from '../packages/core/policy.mjs';import {createApp} from '../apps/server/app.mjs';import {openStore,digest} from '../apps/server/store.mjs';import {mkdtempSync,rmSync} from 'node:fs';import {join,resolve,sep} from 'node:path';import {tmpdir} from 'node:os';
const logo='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aL1sAAAAASUVORK5CYII=';
test('company PNG and feed policy reject active content and preserve conservative defaults',()=>{assert.equal(BrandSchema.parse({name:'Example',color:'#137c66',logoDataUrl:logo}).logoDataUrl,logo);for(const v of ['https://bad/logo.svg','data:image/svg+xml,<svg/>','data:image/png;base64,AAAA'])assert.throws(()=>BrandSchema.parse({name:'Example',color:'#137c66',logoDataUrl:v}));assert.equal(StartPageSchema.parse({}).newsEnabled,false);assert.throws(()=>StartPageSchema.parse({newsEnabled:true}));assert.throws(()=>StartPageSchema.parse({newsEnabled:true,feedUrl:'http://company/feed'}));assert.equal(StartPageSchema.parse({newsEnabled:true,feedUrl:'https://company.example/feed?List=42'}).newsEnabled,true);});
test('branding rolls out in signed device policy and news stays device authenticated',async t=>{const dir=mkdtempSync(join(tmpdir(),'safetynet-branding-')),store=openStore(dir),adminToken='synthetic-admin-credential-at-least-thirty-two',deviceToken='synthetic-device-credential-at-least-thirty-two',config={publicUrl:'http://127.0.0.1',secure:false,adminToken};store.db.prepare('INSERT INTO devices(id,name,platform,user,token_hash,last_seen) VALUES(?,?,?,?,?,?)').run('3b19cb2b-852f-4df7-bf88-bb16d164d130','Fixture','win32','User',digest(deviceToken),'now');const server=createApp(store,config).listen(0,'127.0.0.1');await new Promise(r=>server.once('listening',r));const base=`http://127.0.0.1:${server.address().port}`;t.after(async()=>{server.closeAllConnections();await new Promise(r=>server.close(r));store.db.close();if(!resolve(dir).startsWith(resolve(tmpdir())+sep))throw Error('Unsafe cleanup');rmSync(dir,{recursive:true,force:true});});const p=defaultPolicy();p.version=2;p.brand={name:'Example Company',color:'#224466',logoDataUrl:logo};p.startPage={title:'Company portal',subtitle:'Welcome to your company',newsEnabled:false};const publication=await fetch(base+'/api/admin/policy',{method:'PUT',headers:{authorization:`Bearer ${adminToken}`,'content-type':'application/json'},body:JSON.stringify(p)});assert.equal(publication.status,200);const signed=store.envelope('3b19cb2b-852f-4df7-bf88-bb16d164d130');const delivered=verifyPolicy(signed,store.publicKey());assert.equal(delivered.brand.logoDataUrl,logo);assert.equal(delivered.startPage.title,'Company portal');assert.equal((await fetch(base+'/api/device/start-page/news')).status,401);const news=await fetch(base+'/api/device/start-page/news',{headers:{authorization:`Bearer ${deviceToken}`}});assert.equal(news.status,200);assert.deepEqual(await news.json(),{policyVersion:2,news:[]});});