Skip to content

Commit

Permalink
chore: implement typings in ending module (WebOfTrust#280)
Browse files Browse the repository at this point in the history
* chore: implement typings and enforce linting in ending module

* enable strict linting for src/keri/end
  • Loading branch information
lenkan authored Oct 8, 2024
1 parent 5801e63 commit 8597038
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 195 deletions.
1 change: 0 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"files": [
"src/keri/app/**",
"src/keri/core/**",
"src/keri/end/**",
"examples/integration-scripts/**"
],
"rules": {
Expand Down
5 changes: 3 additions & 2 deletions src/keri/core/authing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, Siger | Cigar>;
const cig = markers.get(input.name);
if (!cig || !this._verfer.verify(cig.raw, ser)) {
throw new Error(`Signature for ${input.keyid} invalid.`);
}
});
Expand Down
159 changes: 78 additions & 81 deletions src/keri/end/ending.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string | Siger | Cigar>,
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<Signage>): Headers {
const values = new Array<string>();
export function signature(signages: Signage[]): Headers {
const values: string[] = [];

for (const signage of signages) {
let markers: Array<Siger | Cigar>;
let indexed = signage.indexed;
const signer = signage.signer;
const ordinal = signage.ordinal;
const digest = signage.digest;
const kind = signage.kind;
let tags: Array<string>;
let markers: Array<string | Siger | Cigar>;
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<Siger | Cigar>;
tags = new Array<string>();
}

if (indexed == undefined) {
indexed = markers[0] instanceof Siger;
tags = [];
}

const items = new Array<string>();
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(';'));
}
Expand All @@ -104,8 +104,7 @@ export function signature(signages: Array<Signage>): Headers {
export function designature(value: string) {
const values = value.replace(' ', '').split(',');

const signages = new Array<Signage>();
values.forEach((val) => {
const signages = values.map((val) => {
const dict = new Map<string, string>();
val.split(';').forEach((v) => {
const splits = v.split('=', 2);
Expand Down Expand Up @@ -147,23 +146,21 @@ export function designature(value: string) {
kind = 'CESR';
}

let markers: Map<string, string | Siger | Cigar>;
if (kind == 'CESR') {
markers = new Map<string, Siger | Cigar>();
dict.forEach((val, key) => {
const markers = new Map<string, Siger | Cigar>();

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;
Expand Down
42 changes: 28 additions & 14 deletions test/core/authing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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'],
Expand All @@ -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);
});
});
Loading

0 comments on commit 8597038

Please sign in to comment.