diff --git a/.eslintrc b/.eslintrc index bb868dd1..c0f71c3d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,7 +12,6 @@ "files": [ "src/keri/app/**", "src/keri/core/**", - "src/keri/end/**", "examples/integration-scripts/**" ], "rules": { diff --git a/src/keri/core/authing.ts b/src/keri/core/authing.ts index 3b1650d6..f372032f 100644 --- a/src/keri/core/authing.ts +++ b/src/keri/core/authing.ts @@ -77,8 +77,9 @@ export class Authenticater { items.push(`"@signature-params: ${params}"`); const ser = items.join('\n'); const signage = designature(signature!); - const cig = signage[0].markers.get(input.name); - if (!this._verfer.verify(cig.raw, ser)) { + const markers = signage[0].markers as Map; + const cig = markers.get(input.name); + if (!cig || !this._verfer.verify(cig.raw, ser)) { throw new Error(`Signature for ${input.keyid} invalid.`); } }); diff --git a/src/keri/end/ending.ts b/src/keri/end/ending.ts index bc8f75dd..ea9d26d0 100644 --- a/src/keri/end/ending.ts +++ b/src/keri/end/ending.ts @@ -6,94 +6,94 @@ export const TRUTHY = [true, 1, '?1', 'yes', 'true', 'True', 'on']; export class Signage { constructor( - markers: any, - indexed?: boolean, - signer?: string, - ordinal?: string, - digest?: string, - kind?: string - ) { - this.markers = markers; - this.indexed = indexed; - this.signer = signer; - this.ordinal = ordinal; - this.digest = digest; - this.kind = kind; - } - public markers: any; - public indexed: boolean | undefined = false; - public signer: string | undefined; - public ordinal: string | undefined; - public digest: string | undefined; - public kind: string | undefined; + public readonly markers: + | (Siger | Cigar)[] + | Map, + public readonly indexed?: boolean, + public readonly signer?: string, + public readonly ordinal?: string, + public readonly digest?: string, + public readonly kind?: string + ) {} } -export function signature(signages: Array): Headers { - const values = new Array(); +export function signature(signages: Signage[]): Headers { + const values: string[] = []; for (const signage of signages) { - let markers: Array; - let indexed = signage.indexed; - const signer = signage.signer; - const ordinal = signage.ordinal; - const digest = signage.digest; - const kind = signage.kind; - let tags: Array; + let markers: Array; + let tags: string[]; if (signage.markers instanceof Map) { - tags = Array.from(signage.markers.keys()); markers = Array.from(signage.markers.values()); + tags = Array.from(signage.markers.keys()); } else { markers = signage.markers as Array; - tags = new Array(); - } - - if (indexed == undefined) { - indexed = markers[0] instanceof Siger; + tags = []; } const items = new Array(); - const tag = 'indexed'; + const indexed = signage.indexed ?? markers[0] instanceof Siger; - let val = indexed ? '?1' : '?0'; - items.push(`${tag}="${val}"`); + if (indexed) { + items.push('indexed="?1"'); + } else { + items.push('indexed="?0"'); + } - if (signer != undefined) { - items.push(`signer="${signer}"`); + if (signage.signer != undefined) { + items.push(`signer="${signage.signer}"`); } - if (ordinal != undefined) { - items.push(`ordinal="${ordinal}"`); + if (signage.ordinal != undefined) { + items.push(`ordinal="${signage.ordinal}"`); } - if (digest != undefined) { - items.push(`digest="${digest}"`); + if (signage.digest != undefined) { + items.push(`digest="${signage.digest}"`); } - if (kind != undefined) { - items.push(`kind="${kind}"`); + if (signage.kind != undefined) { + items.push(`kind="${signage.kind}"`); } - markers.forEach((marker, idx) => { - let tag: string; - if (tags != undefined && tags.length > idx) { - tag = tags[idx]; - } else if (marker instanceof Siger) { - if (!indexed) - throw new Error( - `Indexed signature marker ${marker} when indexed False.` - ); - - tag = marker.index.toString(); - } else { - // Must be a Cigar - if (indexed) - throw new Error( - `Unindexed signature marker ${marker} when indexed True.` - ); - tag = marker.verfer!.qb64; - } + items.push( + ...markers.map((marker, idx) => { + let tag: string | undefined = undefined; + let val: string; - val = marker.qb64; - items.push(`${tag}="${val}"`); - }); + if (tags != undefined && tags.length > idx) { + tag = tags[idx]; + } + + if (marker instanceof Siger) { + if (!indexed) { + throw new Error( + `Indexed signature marker ${marker} when indexed False.` + ); + } + + tag = tag ?? marker.index.toString(); + val = marker.qb64; + } else if (marker instanceof Cigar) { + if (indexed) { + throw new Error( + `Unindexed signature marker ${marker} when indexed True.` + ); + } + if (!marker.verfer) { + throw new Error( + `Indexed signature marker is missing verfer` + ); + } + + tag = tag ?? marker.verfer.qb64; + val = marker.qb64; + } else { + tag = tag ?? idx.toString(); + val = marker; + } + + return `${tag}="${val}"`; + }) + ); values.push(items.join(';')); } @@ -104,8 +104,7 @@ export function signature(signages: Array): Headers { export function designature(value: string) { const values = value.replace(' ', '').split(','); - const signages = new Array(); - values.forEach((val) => { + const signages = values.map((val) => { const dict = new Map(); val.split(';').forEach((v) => { const splits = v.split('=', 2); @@ -147,23 +146,21 @@ export function designature(value: string) { kind = 'CESR'; } - let markers: Map; if (kind == 'CESR') { - markers = new Map(); - dict.forEach((val, key) => { + const markers = new Map(); + + for (const [key, val] of dict.entries()) { if (indexed) { - markers.set(key, new Siger({ qb64: val as string })); + markers.set(key, new Siger({ qb64: val })); } else { - markers.set(key, new Cigar({ qb64: val as string })); + markers.set(key, new Cigar({ qb64: val })); } - }); + } + + return new Signage(markers, indexed, signer, ordinal, digest, kind); } else { - markers = dict; + return new Signage(dict, indexed, signer, ordinal, digest, kind); } - - signages.push( - new Signage(markers, indexed, signer, ordinal, digest, kind) - ); }); return signages; diff --git a/test/core/authing.test.ts b/test/core/authing.test.ts index 27466437..e1ad5069 100644 --- a/test/core/authing.test.ts +++ b/test/core/authing.test.ts @@ -20,11 +20,19 @@ describe('Authenticater.verify', () => { ['Content-Type', 'application/json'], [ 'Signature', - 'indexed="?0";signify="0BDLh8QCytVBx1YMam4Vt8s4b9HAW1dwfE4yU5H_w1V6gUvPBoVGWQlIMdC16T3WFWHDHCbMcuceQzrr6n9OULsK"', + [ + 'indexed="?0"', + 'signify="0BDLh8QCytVBx1YMam4Vt8s4b9HAW1dwfE4yU5H_w1V6gUvPBoVGWQlIMdC16T3WFWHDHCbMcuceQzrr6n9OULsK"', + ].join(';'), ], [ 'Signature-Input', - 'signify=("signify-resource" "@method" "@path" "signify-timestamp");created=1684715820;keyid="EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei";alg="ed25519"', + [ + 'signify=("signify-resource" "@method" "@path" "signify-timestamp")', + 'created=1684715820', + 'keyid="EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei"', + 'alg="ed25519"', + ].join(';'), ], [ 'Signify-Resource', @@ -52,7 +60,7 @@ describe('Authenticater.sign', () => { const aaid = 'DDK2N5_fVCWIEO9d8JLhk7hKrkft6MbtkUhaHQsmABHY'; const verfer = new Verfer({ qb64: aaid }); - let headers = new Headers([ + const headers = new Headers([ ['Content-Type', 'application/json'], ['Content-Length', '256'], ['Connection', 'close'], @@ -67,17 +75,23 @@ describe('Authenticater.sign', () => { ); const authn = new Authenticater(signer, verfer); - headers = authn.sign(headers, 'POST', '/boot'); + const result = authn.sign(headers, 'POST', '/boot'); - assert.equal(headers.has('Signature-Input'), true); - assert.equal(headers.has('Signature'), true); - assert.equal( - headers.get('Signature-Input'), - 'signify=("@method" "@path" "signify-resource" "signify-timestamp");created=1609459200;keyid="DN54yRad_BTqgZYUSi_NthRBQrxSnqQdJXWI5UHcGOQt";alg="ed25519"' - ); - assert.equal( - headers.get('Signature'), - 'indexed="?0";signify="0BChvN_BWAf-mgEuTnWfNnktgHdWOuOh9cWc4o0GFWuZOwra3DyJT5dJ_6BX7AANDOTnIlAKh5Sg_9qGQXHjj5oJ"' - ); + assert.equal(result.has('Signature-Input'), true); + assert.equal(result.has('Signature'), true); + + const expectedSignatureInput = [ + 'signify=("@method" "@path" "signify-resource" "signify-timestamp")', + 'created=1609459200', + 'keyid="DN54yRad_BTqgZYUSi_NthRBQrxSnqQdJXWI5UHcGOQt"', + 'alg="ed25519"', + ].join(';'); + assert.equal(result.get('Signature-Input'), expectedSignatureInput); + + const expectedSignature = [ + 'indexed="?0"', + 'signify="0BChvN_BWAf-mgEuTnWfNnktgHdWOuOh9cWc4o0GFWuZOwra3DyJT5dJ_6BX7AANDOTnIlAKh5Sg_9qGQXHjj5oJ"', + ].join(';'); + assert.equal(result.get('Signature'), expectedSignature); }); }); diff --git a/test/end/ending.test.ts b/test/end/ending.test.ts index bea7bf21..412d472c 100644 --- a/test/end/ending.test.ts +++ b/test/end/ending.test.ts @@ -6,151 +6,251 @@ import { MtrDex } from '../../src/keri/core/matter'; import { designature, Signage, signature } from '../../src/keri/end/ending'; import { Siger } from '../../src/keri/core/siger'; import { Cigar } from '../../src/keri/core/cigar'; +import { Signer } from '../../src/keri/core/signer'; -describe('ending_signature_designature', () => { - it('should create and parse signature headers', async () => { - await libsodium.ready; +function createSigner(name: string): Signer { + const temp = true; - const name = 'Hilga'; - const temp = true; + const salter = new Salter({ raw: b('0123456789abcdef') }); + const signer0 = salter.signer( + MtrDex.Ed25519_Seed, + true, + name, + Tier.low, + temp + ); - const salter = new Salter({ raw: b('0123456789abcdef') }); - const signer0 = salter.signer( - MtrDex.Ed25519_Seed, - true, - `${name}00`, - Tier.low, - temp - ); - const signer1 = salter.signer( - MtrDex.Ed25519_Seed, - true, - `${name}01`, - Tier.low, - temp - ); - const signer2 = salter.signer( - MtrDex.Ed25519_Seed, - true, - `${name}02`, - Tier.low, - temp - ); - const signers = [signer0, signer1, signer2]; + return signer0; +} - const text = b( - '{"seid":"BA89hKezugU2LFKiFVbitoHAxXqJh6HQ8Rn9tH7fxd68","name":"wit0","dts":"2021-01-01T00' + - ':00:00.000000+00:00","scheme":"http","host":"localhost","port":8080,"path":"/witness"}' - ); +let sigers: Siger[]; +let cigars: Cigar[]; +let text: Uint8Array; +let pre: string; +let digest: string; - const sigers = Array.from(signers, (signer, idx) => - signer.sign(text, idx) - ); - const pre = 'EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-'; // Hab.pre from KERIpy test - const digest = pre; +beforeAll(async () => { + await libsodium.ready; + + const name = 'Hilga'; + const signer0 = createSigner(`${name}00`); + const signer1 = createSigner(`${name}01`); + const signer2 = createSigner(`${name}02`); + const signers = [signer0, signer1, signer2]; + text = b( + JSON.stringify({ + seid: 'BA89hKezugU2LFKiFVbitoHAxXqJh6HQ8Rn9tH7fxd68', + name: 'wit0', + dts: '2021-01-01T00:00:00.000000+00:00', + scheme: 'http', + host: 'localhost', + port: 8080, + path: '/witness', + }) + ); + sigers = signers.map((signer, idx) => signer.sign(text, idx) as Siger); + cigars = signers.map((s) => s.sign(text) as Cigar); + pre = 'EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-'; // Hab.pre from KERIpy test + digest = pre; +}); - let signage = new Signage(sigers); - let header = signature([signage]); +describe('When indexed signatures', () => { + const expectedHeader = [ + 'indexed="?1"', + '0="AACsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN"', + '1="ABDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA"', + '2="ACDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"', + ].join(';'); + + it('Can create signature header', async () => { + const signage = new Signage(sigers); + const header = signature([signage]); assert.equal(header.has('Signature'), true); - assert.equal( - header.get('Signature'), - 'indexed="?1";0="AACsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN";1="ABDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA";2="ACDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"' - ); + assert.equal(header.get('Signature'), expectedHeader); + }); - let signages = designature(header.get('Signature')!); + it('Can parse signature header', async () => { + const signages = designature(expectedHeader); assert.equal(signages.length, 1); - signage = signages[0]; + const signage = signages[0]; + + assert(signage.markers instanceof Map); assert.equal(signage.markers.size, 3); - signage.markers.forEach((item: string | Siger | Cigar, tag: string) => { - const marker = item as Siger; + signage.markers.forEach((marker, tag) => { + assert(marker instanceof Siger); const idx = parseInt(tag); - const siger = sigers[idx] as Siger; + const siger = sigers[idx]; assert.equal(marker.qb64, siger.qb64); assert.equal(parseInt(tag), siger.index); }); + }); +}); - signage = new Signage(sigers, true, pre, '0', digest, 'CESR'); - header = signature([signage]); - assert.equal(header.has('Signature'), true); - assert.equal( - header.get('Signature'), - 'indexed="?1";signer="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-";ordinal="0";digest="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-";kind="CESR";0="AACsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN";1="ABDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA";2="ACDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"' +describe('When named signatures', () => { + const expectedHeader = [ + 'indexed="?1"', + 'siger0="AACsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN"', + 'siger1="ABDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA"', + 'siger2="ACDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"', + ].join(';'); + + let markers: Map; + + beforeEach(() => { + markers = new Map( + sigers.map((s, idx) => [`siger${idx}`, s]) ); + }); - signages = designature(header.get('Signature')!); + it('Can create signature header', async () => { + const signage = new Signage(markers); + const header = signature([signage]); + assert.equal(header.has('Signature'), true); + assert.equal(header.get('Signature'), expectedHeader); + }); + + it('Can parse signature header', async () => { + const signages = designature(expectedHeader); assert.equal(signages.length, 1); - signage = signages[0]; + const signage = signages[0]; + + assert(signage.markers instanceof Map); + assert.equal(signage.markers.size, 3); + signage.markers.forEach((marker, tag) => { + const siger = markers.get(tag); + + assert(marker instanceof Siger); + assert(siger); + assert.equal(marker.qb64, siger.qb64); + }); + }); +}); + +describe('When indexed CESR signatures', () => { + const expectedHeader = [ + 'indexed="?1"', + 'signer="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-"', + 'ordinal="0"', + 'digest="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-"', + 'kind="CESR"', + '0="AACsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN"', + '1="ABDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA"', + '2="ACDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"', + ].join(';'); + + it('Should create headers', async () => { + const signage = new Signage(sigers, true, pre, '0', digest, 'CESR'); + const headers = signature([signage]); + assert.equal(headers.has('Signature'), true); + assert.equal(headers.get('Signature'), expectedHeader); + }); + + it('Should parse headers', async () => { + const signages = designature(expectedHeader); + assert.equal(signages.length, 1); + const signage = signages[0]; assert.equal(signage.indexed, true); assert.equal(signage.signer, pre); assert.equal(signage.digest, digest); assert.equal(signage.kind, 'CESR'); + assert(signage.markers instanceof Map); assert.equal(signage.markers.size, 3); - signage.markers.forEach((item: string | Siger | Cigar, tag: string) => { - const marker = item as Siger; + signage.markers.forEach((marker, tag) => { + assert(marker instanceof Siger); const idx = parseInt(tag); - const siger = sigers[idx] as Siger; + const siger = sigers[idx]; assert.equal(marker.qb64, siger.qb64); assert.equal(parseInt(tag), siger.index); }); + }); +}); + +describe('When non-indexed signatures', () => { + const expectedHeader = [ + 'indexed="?0"', + 'DAi2TaRNVtGmV8eSUvqHIBzTzIgrQi57vKzw5Svmy7jw="0BCsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN"', + 'DNK2KFnL0jUGlmvZHRse7HwNGVdtkM-ORvTZfFw7mDbt="0BDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA"', + 'DDvIoIYqeuXJ4Zb8e2luWfjPTg4FeIzfHzIO8lC56WjD="0BDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"', + ].join(';'); - const cigars = Array.from(signers, (signer) => signer.sign(text)); - signage = new Signage(cigars); - header = signature([signage]); + it('Should create headers', () => { + const signage = new Signage(cigars); + const header = signature([signage]); assert.equal(header.has('Signature'), true); - assert.equal( - header.get('Signature'), - 'indexed="?0";DAi2TaRNVtGmV8eSUvqHIBzTzIgrQi57vKzw5Svmy7jw="0BCsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN";DNK2KFnL0jUGlmvZHRse7HwNGVdtkM-ORvTZfFw7mDbt="0BDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA";DDvIoIYqeuXJ4Zb8e2luWfjPTg4FeIzfHzIO8lC56WjD="0BDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"' - ); - signages = designature(header.get('Signature')!); + assert.equal(header.get('Signature'), expectedHeader); + }); + + it('Should parse headers', () => { + const signages = designature(expectedHeader); assert.equal(signages.length, 1); - signage = signages[0]; + const signage = signages[0]; assert.equal(signage.indexed, false); + assert(signage.markers instanceof Map); assert.equal(signage.markers.size, 3); - signage.markers.forEach((marker: Cigar, tag: string) => { + + signage.markers.forEach((marker, tag) => { + assert(marker instanceof Cigar); const cigar = cigars.find((cigar) => cigar.verfer!.qb64 == tag); assert.notEqual(cigar, undefined); assert.equal(marker.qb64, cigar!.qb64); assert.equal(tag, cigar!.verfer!.qb64); }); + }); +}); - // now combine into one header - signages = new Array(); - signages.push( - new Signage(sigers, true, pre, undefined, undefined, 'CESR') - ); - signages.push( - new Signage(cigars, false, pre, undefined, undefined, 'CESR') - ); +describe('Combined headers', () => { + const expectedHeader = [ + 'indexed="?1"', + 'signer="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-"', + 'kind="CESR"', + '0="AACsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN"', + '1="ABDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA"', + '2="ACDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F",indexed="?0"', + 'signer="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-"', + 'kind="CESR"', + 'DAi2TaRNVtGmV8eSUvqHIBzTzIgrQi57vKzw5Svmy7jw="0BCsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN"', + 'DNK2KFnL0jUGlmvZHRse7HwNGVdtkM-ORvTZfFw7mDbt="0BDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA"', + 'DDvIoIYqeuXJ4Zb8e2luWfjPTg4FeIzfHzIO8lC56WjD="0BDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"', + ].join(';'); + + it('Should create header', () => { + const signages: Signage[] = [ + new Signage(sigers, true, pre, undefined, undefined, 'CESR'), + new Signage(cigars, false, pre, undefined, undefined, 'CESR'), + ]; - header = signature(signages); + const header = signature(signages); assert.equal(header.has('Signature'), true); - assert.equal( - header.get('Signature'), - 'indexed="?1";signer="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-";kind="CESR";0="AACsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN";1="ABDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA";2="ACDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F",indexed="?0";signer="EGqHykT1gVyuWxsVW6LUUsz_KtLJGYMi_SrohInwvjC-";kind="CESR";DAi2TaRNVtGmV8eSUvqHIBzTzIgrQi57vKzw5Svmy7jw="0BCsufRGYI-sRvS2c0rsOueSoSRtrjODaf48DYLJbLvvD8aHe7b2sWGebZ-y9ichhsxMF3Hhn-3LYSKIrnmH3oIN";DNK2KFnL0jUGlmvZHRse7HwNGVdtkM-ORvTZfFw7mDbt="0BDs7m2-h5l7vpjYtbFXtksicpZK5Oclm43EOkE2xoQOfr08doj73VrlKZOKNfJmRumD3tfaiFFgVZqPgiHuFVoA";DDvIoIYqeuXJ4Zb8e2luWfjPTg4FeIzfHzIO8lC56WjD="0BDVOy2LvGgFINUneL4iwA55ypJR6vDpLLbdleEsiANmFazwZARypJMiw9vu2Iu0oL7XCUiUT4JncU8P3HdIp40F"' - ); - signages = designature(header.get('Signature')!); + assert.equal(header.get('Signature'), expectedHeader); + }); + + it('Should parse hader', () => { + const signages = designature(expectedHeader); assert.equal(signages.length, 2); - signage = signages[0]; - assert.equal(signage.indexed, true); - assert.equal(signage.signer, pre); - assert.equal(signage.kind, 'CESR'); - assert.equal(signage.markers.size, 3); - signage.markers.forEach((item: string | Siger | Cigar, tag: string) => { - const marker = item as Siger; + const signage0 = signages[0]; + assert.equal(signage0.indexed, true); + assert.equal(signage0.signer, pre); + assert.equal(signage0.kind, 'CESR'); + assert(signage0.markers instanceof Map); + assert.equal(signage0.markers.size, 3); + signage0.markers.forEach((marker, tag) => { + assert(marker instanceof Siger); const idx = parseInt(tag); - const siger = sigers[idx] as Siger; + const siger = sigers[idx]; assert.equal(marker.qb64, siger.qb64); assert.equal(parseInt(tag), siger.index); }); - signage = signages[1]; - assert.equal(signage.indexed, false); - assert.equal(signage.signer, pre); - assert.equal(signage.kind, 'CESR'); - assert.equal(signage.markers.size, 3); - signage.markers.forEach((marker: Cigar, tag: string) => { + const signage1 = signages[1]; + assert.equal(signage1.indexed, false); + assert.equal(signage1.signer, pre); + assert.equal(signage1.kind, 'CESR'); + assert(signage1.markers instanceof Map); + assert.equal(signage1.markers.size, 3); + signage1.markers.forEach((marker, tag) => { + assert(marker instanceof Cigar); const cigar = cigars.find((cigar) => cigar.verfer!.qb64 == tag); assert.notEqual(cigar, undefined); assert.equal(marker.qb64, cigar!.qb64);