import test from 'node:test'; import assert from 'node:assert/strict'; import { generateKeyPairSync, sign } from 'node:crypto'; import { request } from 'node:http'; import { once } from 'node:events'; import { PublicKey } from '@solana/web3.js'; import { createGate, readPilotSettings } from '../partner/server.mjs'; const appOrigin='https://gallery.example'; import { sampleAddresses } from '../lib/wallet.mjs'; test('advanced pilot reads Solbound settings while preserving legacy configuration', () => { const old = { SOLMATE_ORIGIN:appOrigin, SOLMATE_PATH:'/members', SOLMATE_RULE:'balance', SOLMATE_ADDRESS:sampleAddresses.asset, SOLMATE_MINIMUM:'5', SOLMATE_HOLDER_MESSAGE:'Welcome' }; const renamed = Object.fromEntries(Object.entries(old).map(([key,value]) => [key.replace('SOLMATE_','SOLBOUND_'),value])); assert.deepEqual(readPilotSettings(renamed),readPilotSettings(old)); assert.equal(readPilotSettings({...old,SOLBOUND_ORIGIN:'https://club.example'}).origin,'https://club.example'); }); for (const rule of ['wallet', 'mint', 'collection','balance']) { test('Third-party HTTP sign-in, protected content, recheck and logout with ' + rule, async t => { let eligible = true, calls = 0, args; const content = 'Authenticated test content'; const check = input => { args = input; calls++; return {eligible,slot:701,reason:'No current matching grant.'}; }; const server = createGate({ origin: appOrigin, path:'/members/holders', address: rule==='wallet'?undefined:sampleAddresses.asset, minimum:'3', rule, holderMessage: content }, {check,find:check}); server.listen(0,'127.0.0.1'); await once(server,'listening'); t.after(() => new Promise(resolve => server.close(resolve))); function call(path, body, cookie, origin = appOrigin) { return new Promise((resolve,reject) => { const req = request({hostname:'127.0.0.1',port:server.address().port,path:'/members/holders'+path, method:body?'POST':'GET',headers:{host:'gallery.example',origin,'content-type':'application/json',cookie:cookie||''}}, res => { let text='';res.setEncoding('utf8');res.on('data',d=>{text+=d;}); res.on('end',()=>resolve({status:res.statusCode,headers:res.headers,text,body:res.headers['content-type']?.includes('json')?JSON.parse(text):null})); }); req.on('error',reject);req.end(body?JSON.stringify(body):undefined); }); } const details={vault:sampleAddresses.owner,mint:sampleAddresses.delegate,collection:sampleAddresses.delegate,authenticatedDelegate:sampleAddresses.owner}; assert.equal((await call('/',null)).text.includes(content),false); assert.equal((await call('/api/holder',details)).status,401); const {privateKey,publicKey}=generateKeyPairSync('ed25519'); const delegate=new PublicKey(publicKey.export({type:'spki',format:'der'}).subarray(-32)).toBase58(); assert.equal((await call('/api/challenge',{delegate},null,'https://other.example')).status,403); const start=await call('/api/challenge',{delegate}); assert.equal(start.status,200); const cookie = r => r.headers['set-cookie'][0].split(';')[0]; const token={id:start.body.id,signature:sign(null,Buffer.from(start.body.message),privateKey).toString('base64')}; assert.equal((await call('/api/sign-in',token)).status,401); const auth=await call('/api/sign-in',token,cookie(start)); assert.equal(auth.status,200);assert.match(auth.headers['set-cookie'][0],/HttpOnly.*SameSite=Strict.*Secure/); assert.notEqual(cookie(start),cookie(auth)); assert.equal((await call('/api/sign-in',token,cookie(start))).status,401); const allowed=await call('/api/holder',details,cookie(auth)); assert.equal(allowed.body.content,content);assert.match(allowed.headers['cache-control'],/no-store/); assert.equal(args.authenticatedDelegate,delegate);assert.equal(args.origin,appOrigin); assert.equal(args.qualifyingMint,rule==='collection'?details.mint:rule==='wallet'?undefined:sampleAddresses.asset); assert.equal(args.collection,rule==='collection'?sampleAddresses.asset:undefined); assert.equal((await call('/api/holder',{},cookie(auth))).body.content,content); assert.equal(args.address,rule==='wallet'?undefined:sampleAddresses.asset);assert.equal(args.authenticatedDelegate,delegate);assert.equal(args.rule,rule); eligible=false; const denied=await call('/api/holder',details,cookie(auth)); assert.equal(denied.status,403);assert.equal(denied.text.includes(content),false);assert.equal(calls,3); await call('/api/sign-out',{},cookie(auth)); assert.equal((await call('/api/holder',details,cookie(auth))).status,401); }); }