Skip to content

Commit e72b3d0

Browse files
specify protocol version in getSupportedProfiles (#295)
* specify protocol version in getSupportedProfiles
1 parent 74069f7 commit e72b3d0

File tree

8 files changed

+106
-68
lines changed

8 files changed

+106
-68
lines changed

src/iden3comm/handlers/auth.ts

+18-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MediaType, ProtocolVersion } from '../constants';
1+
import { MediaType } from '../constants';
22
import { IProofService } from '../../proof/proof-service';
33
import { PROTOCOL_MESSAGE_TYPE } from '../constants';
44

@@ -489,35 +489,26 @@ export class AuthHandler
489489
profile?: string[] | undefined
490490
): MediaType {
491491
let mediaType: MediaType;
492-
if (profile?.length) {
493-
const supportedMediaTypes: MediaType[] = [];
494-
for (const acceptProfile of profile) {
495-
// 1. check protocol version
496-
const { protocolVersion, env } = parseAcceptProfile(acceptProfile);
497-
const responseTypeVersion = Number(responseType.split('/').at(-2));
498-
if (
499-
protocolVersion !== ProtocolVersion.V1 ||
500-
(protocolVersion === ProtocolVersion.V1 &&
501-
(responseTypeVersion < 1 || responseTypeVersion >= 2))
502-
) {
503-
continue;
504-
}
505-
// 2. check packer support
506-
if (this._packerMgr.isProfileSupported(env, acceptProfile)) {
507-
supportedMediaTypes.push(env);
508-
}
492+
if (!profile?.length) {
493+
return ctx.mediaType || MediaType.ZKPMessage;
494+
}
495+
const supportedMediaTypes: MediaType[] = [];
496+
for (const acceptProfile of profile) {
497+
const { env } = parseAcceptProfile(acceptProfile);
498+
if (this._packerMgr.isProfileSupported(env, acceptProfile)) {
499+
supportedMediaTypes.push(env);
509500
}
501+
}
510502

511-
if (!supportedMediaTypes.length) {
512-
throw new Error('no packer with profile which meets `accept` header requirements');
513-
}
503+
if (!supportedMediaTypes.length) {
504+
throw new Error('no packer with profile which meets `accept` header requirements');
505+
}
514506

515-
mediaType = supportedMediaTypes[0];
516-
if (ctx.mediaType && supportedMediaTypes.includes(ctx.mediaType)) {
517-
mediaType = ctx.mediaType;
518-
}
519-
} else {
520-
mediaType = ctx.mediaType || MediaType.ZKPMessage;
507+
mediaType = supportedMediaTypes.includes(MediaType.ZKPMessage)
508+
? MediaType.ZKPMessage
509+
: supportedMediaTypes[0];
510+
if (ctx.mediaType && supportedMediaTypes.includes(ctx.mediaType)) {
511+
mediaType = ctx.mediaType;
521512
}
522513
return mediaType;
523514
}

src/iden3comm/packers/jws.ts

+18-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { BasicMessage, IPacker, JWSPackerParams } from '../types';
2-
import { AcceptJwsAlgorithms, MediaType, SUPPORTED_PUBLIC_KEY_TYPES } from '../constants';
2+
import {
3+
AcceptJwsAlgorithms,
4+
MediaType,
5+
ProtocolVersion,
6+
SUPPORTED_PUBLIC_KEY_TYPES
7+
} from '../constants';
38
import { extractPublicKeyBytes, resolveVerificationMethods } from '../utils/did';
49
import { keyPath, KMS } from '../../kms/';
510

@@ -23,6 +28,9 @@ import { parseAcceptProfile } from '../utils';
2328
* @implements implements IPacker interface
2429
*/
2530
export class JWSPacker implements IPacker {
31+
private readonly supportedAlgorithms = [AcceptJwsAlgorithms.ES256K, AcceptJwsAlgorithms.ES256KR];
32+
private readonly supportedProtocolVersions = [ProtocolVersion.V1];
33+
2634
/**
2735
* Creates an instance of JWSPacker.
2836
*
@@ -105,12 +113,18 @@ export class JWSPacker implements IPacker {
105113

106114
/** {@inheritDoc IPacker.getSupportedProfiles} */
107115
getSupportedProfiles(): string[] {
108-
return [`env=${this.mediaType()}&alg=${this.getSupportedAlgorithms().join(',')}`];
116+
return this.supportedProtocolVersions.map(
117+
(v) => `${v};env=${this.mediaType()};alg=${this.supportedAlgorithms.join(',')}`
118+
);
109119
}
110120

111121
/** {@inheritDoc IPacker.isProfileSupported} */
112122
isProfileSupported(profile: string) {
113-
const { env, circuits, alg } = parseAcceptProfile(profile);
123+
const { protocolVersion, env, circuits, alg } = parseAcceptProfile(profile);
124+
125+
if (!this.supportedProtocolVersions.includes(protocolVersion)) {
126+
return false;
127+
}
114128
if (env !== this.mediaType()) {
115129
return false;
116130
}
@@ -119,16 +133,11 @@ export class JWSPacker implements IPacker {
119133
throw new Error(`Circuits are not supported for ${env} media type`);
120134
}
121135

122-
const supportedAlgArr = this.getSupportedAlgorithms();
123136
const algSupported =
124-
!alg?.length || alg.some((a) => supportedAlgArr.includes(a as AcceptJwsAlgorithms));
137+
!alg?.length || alg.some((a) => this.supportedAlgorithms.includes(a as AcceptJwsAlgorithms));
125138
return algSupported;
126139
}
127140

128-
private getSupportedAlgorithms(): AcceptJwsAlgorithms[] {
129-
return [AcceptJwsAlgorithms.ES256K, AcceptJwsAlgorithms.ES256KR];
130-
}
131-
132141
private async resolveDidDoc(from: string) {
133142
let didDocument: DIDDocument;
134143
try {

src/iden3comm/packers/plain.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { BasicMessage, IPacker } from '../types';
2-
import { MediaType } from '../constants';
2+
import { MediaType, ProtocolVersion } from '../constants';
33
import { byteDecoder, byteEncoder } from '../../utils';
44
import { parseAcceptProfile } from '../utils';
55

@@ -11,6 +11,8 @@ import { parseAcceptProfile } from '../utils';
1111
* @implements implements IPacker interface
1212
*/
1313
export class PlainPacker implements IPacker {
14+
private readonly supportedProtocolVersions = [ProtocolVersion.V1];
15+
1416
/**
1517
* Packs a basic message using the specified parameters.
1618
*
@@ -57,12 +59,16 @@ export class PlainPacker implements IPacker {
5759

5860
/** {@inheritDoc IPacker.getSupportedProfiles} */
5961
getSupportedProfiles(): string[] {
60-
return [`env=${this.mediaType()}`];
62+
return this.supportedProtocolVersions.map((v) => `${v};env=${this.mediaType()}`);
6163
}
6264

6365
/** {@inheritDoc IPacker.isProfileSupported} */
6466
isProfileSupported(profile: string) {
65-
const { env, circuits, alg } = parseAcceptProfile(profile);
67+
const { protocolVersion, env, circuits, alg } = parseAcceptProfile(profile);
68+
69+
if (!this.supportedProtocolVersions.includes(protocolVersion)) {
70+
return false;
71+
}
6672
if (env !== this.mediaType()) {
6773
return false;
6874
}

src/iden3comm/packers/zkp.ts

+19-17
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
ErrStateVerificationFailed,
2121
ErrUnknownCircuitID
2222
} from '../errors';
23-
import { AcceptAuthCircuits, AcceptJwzAlgorithms, MediaType } from '../constants';
23+
import { AcceptAuthCircuits, AcceptJwzAlgorithms, MediaType, ProtocolVersion } from '../constants';
2424
import { byteDecoder, byteEncoder } from '../../utils';
2525
import { DEFAULT_AUTH_VERIFY_DELAY } from '../constants';
2626
import { parseAcceptProfile } from '../utils';
@@ -86,6 +86,10 @@ export class VerificationHandlerFunc {
8686
* @implements implements IPacker interface
8787
*/
8888
export class ZKPPacker implements IPacker {
89+
private readonly supportedProtocolVersions = [ProtocolVersion.V1];
90+
private readonly supportedAlgorithms = [AcceptJwzAlgorithms.Groth16];
91+
private readonly supportedCircuitIds = [AcceptAuthCircuits.AuthV2];
92+
8993
/**
9094
* Creates an instance of ZKPPacker.
9195
* @param {Map<string, ProvingParams>} provingParamsMap - string is derived by JSON.parse(ProvingMethodAlg)
@@ -178,37 +182,35 @@ export class ZKPPacker implements IPacker {
178182

179183
/** {@inheritDoc IPacker.getSupportedProfiles} */
180184
getSupportedProfiles(): string[] {
181-
return [
182-
`env=${this.mediaType()}&alg=${this.getSupportedAlgorithms().join(
183-
','
184-
)}&circuitIds=${this.getSupportedCircuitIds().join(',')}`
185-
];
185+
return this.supportedProtocolVersions.map(
186+
(v) =>
187+
`${v};env=${this.mediaType()};alg=${this.supportedAlgorithms.join(
188+
','
189+
)};circuitIds=${this.supportedCircuitIds.join(',')}`
190+
);
186191
}
187192

188193
/** {@inheritDoc IPacker.isProfileSupported} */
189194
isProfileSupported(profile: string) {
190-
const { env, circuits, alg } = parseAcceptProfile(profile);
195+
const { protocolVersion, env, circuits, alg } = parseAcceptProfile(profile);
196+
197+
if (!this.supportedProtocolVersions.includes(protocolVersion)) {
198+
return false;
199+
}
200+
191201
if (env !== this.mediaType()) {
192202
return false;
193203
}
194204

195-
const supportedCircuitIds = this.getSupportedCircuitIds();
205+
const supportedCircuitIds = this.supportedCircuitIds;
196206
const circuitIdSupported =
197207
!circuits?.length || circuits.some((c) => supportedCircuitIds.includes(c));
198208

199-
const supportedAlgArr = this.getSupportedAlgorithms();
209+
const supportedAlgArr = this.supportedAlgorithms;
200210
const algSupported =
201211
!alg?.length || alg.some((a) => supportedAlgArr.includes(a as AcceptJwzAlgorithms));
202212
return algSupported && circuitIdSupported;
203213
}
204-
205-
private getSupportedAlgorithms(): AcceptJwzAlgorithms[] {
206-
return [AcceptJwzAlgorithms.Groth16];
207-
}
208-
209-
private getSupportedCircuitIds(): AcceptAuthCircuits[] {
210-
return [AcceptAuthCircuits.AuthV2];
211-
}
212214
}
213215

214216
const verifySender = async (token: Token, msg: BasicMessage): Promise<void> => {

tests/handlers/discover-protocol.test.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe('discovery-protocol', () => {
4949
expect(disclosures[0][DiscoverFeatureQueryType.FeatureType]).to.be.eq(
5050
DiscoveryProtocolFeatureType.Accept
5151
);
52-
expect(disclosures[0].id).to.be.eq('env=application/iden3comm-plain-json');
52+
expect(disclosures[0].id).to.be.eq('iden3comm/v1;env=application/iden3comm-plain-json');
5353
});
5454

5555
it('jws and plain message accept disclosures', async () => {
@@ -72,8 +72,10 @@ describe('discovery-protocol', () => {
7272
DiscoveryProtocolFeatureType.Accept
7373
);
7474
const disclosureIds = disclosures.map((d) => d.id);
75-
expect(disclosureIds).to.include('env=application/iden3comm-plain-json');
76-
expect(disclosureIds).to.include('env=application/iden3comm-signed-json&alg=ES256K,ES256K-R');
75+
expect(disclosureIds).to.include('iden3comm/v1;env=application/iden3comm-plain-json');
76+
expect(disclosureIds).to.include(
77+
'iden3comm/v1;env=application/iden3comm-signed-json;alg=ES256K,ES256K-R'
78+
);
7779
});
7880

7981
it('zkp and plain message accept disclosures', async () => {
@@ -95,9 +97,9 @@ describe('discovery-protocol', () => {
9597
DiscoveryProtocolFeatureType.Accept
9698
);
9799
const disclosureIds = disclosures.map((d) => d.id);
98-
expect(disclosureIds).to.include('env=application/iden3comm-plain-json');
100+
expect(disclosureIds).to.include('iden3comm/v1;env=application/iden3comm-plain-json');
99101
expect(disclosureIds).to.include(
100-
'env=application/iden3-zkp-json&alg=groth16&circuitIds=authV2'
102+
'iden3comm/v1;env=application/iden3-zkp-json;alg=groth16;circuitIds=authV2'
101103
);
102104
});
103105

@@ -123,11 +125,13 @@ describe('discovery-protocol', () => {
123125
DiscoveryProtocolFeatureType.Accept
124126
);
125127
const disclosureIds = disclosures.map((d) => d.id);
126-
expect(disclosureIds).to.include('env=application/iden3comm-plain-json');
128+
expect(disclosureIds).to.include('iden3comm/v1;env=application/iden3comm-plain-json');
129+
expect(disclosureIds).to.include(
130+
'iden3comm/v1;env=application/iden3-zkp-json;alg=groth16;circuitIds=authV2'
131+
);
127132
expect(disclosureIds).to.include(
128-
'env=application/iden3-zkp-json&alg=groth16&circuitIds=authV2'
133+
'iden3comm/v1;env=application/iden3comm-signed-json;alg=ES256K,ES256K-R'
129134
);
130-
expect(disclosureIds).to.include('env=application/iden3comm-signed-json&alg=ES256K,ES256K-R');
131135
});
132136

133137
it('zkp, jws and plain message accept disclosures with exact match', async () => {
@@ -140,7 +144,7 @@ describe('discovery-protocol', () => {
140144
const acceptQueryMessageWithMatch = createDiscoveryFeatureQueryMessage([
141145
{
142146
[DiscoverFeatureQueryType.FeatureType]: DiscoveryProtocolFeatureType.Accept,
143-
match: 'env=application/iden3-zkp-json&alg=groth16&circuitIds=authV2'
147+
match: 'iden3comm/v1;env=application/iden3-zkp-json;alg=groth16;circuitIds=authV2'
144148
}
145149
]);
146150

@@ -153,7 +157,7 @@ describe('discovery-protocol', () => {
153157
DiscoveryProtocolFeatureType.Accept
154158
);
155159
expect(disclosures[0].id).to.include(
156-
'env=application/iden3-zkp-json&alg=groth16&circuitIds=authV2'
160+
'iden3comm/v1;env=application/iden3-zkp-json;alg=groth16;circuitIds=authV2'
157161
);
158162
});
159163

@@ -306,7 +310,7 @@ describe('discovery-protocol', () => {
306310
DiscoveryProtocolFeatureType.Protocol
307311
);
308312
const disclosureIds = disclosures.map((d) => d.id);
309-
expect(disclosureIds).to.include('env=application/iden3comm-plain-json');
313+
expect(disclosureIds).to.include('iden3comm/v1;env=application/iden3comm-plain-json');
310314
expect(disclosureIds).to.include(PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_REQUEST_MESSAGE_TYPE);
311315
expect(disclosureIds).to.include(PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_REQUEST_MESSAGE_TYPE);
312316
});

tests/iden3comm/jws.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { DIDResolutionResult } from 'did-resolver';
1717
import { ES256KSigner } from 'did-jwt';
1818
import { DID, getChainId, Id } from '@iden3/js-iden3-core';
1919
import { Hex } from '@iden3/js-crypto';
20+
import { MediaType } from '../../src/iden3comm/constants';
2021

2122
const didExample = {
2223
'@context': [
@@ -217,4 +218,9 @@ describe('jws packer tests', () => {
217218
const data = await packer.unpack(tokenBytes);
218219
expect(data).to.not.be.undefined;
219220
});
221+
222+
it('test getSupportedProfiles', () => {
223+
const [accept] = packer.getSupportedProfiles();
224+
expect(accept).to.be.eq(`iden3comm/v1;env=${MediaType.SignedMessage};alg=ES256K,ES256K-R`);
225+
});
220226
});

tests/iden3comm/packageManager.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
DataPrepareHandlerFunc,
33
PackageManager,
4+
PlainPacker,
45
VerificationHandlerFunc,
56
ZKPPacker
67
} from '../../src/iden3comm/index';
@@ -70,6 +71,17 @@ describe('tests packageManager with ZKP Packer', () => {
7071
expect(senderDID.string()).to.deep.equal(unpackedMessage.from);
7172
expect(byteDecoder.decode(msgBytes)).to.deep.equal(JSON.stringify(unpackedMessage));
7273
});
74+
75+
it('test getSupportedProfiles', () => {
76+
const pm = new PackageManager();
77+
pm.registerPackers([new ZKPPacker(new Map(), new Map()), new PlainPacker()]);
78+
const supportedProfiles = pm.getSupportedProfiles();
79+
expect(supportedProfiles.length).to.be.eq(2);
80+
expect(supportedProfiles).to.include(
81+
`iden3comm/v1;env=${MediaType.ZKPMessage};alg=groth16;circuitIds=authV2`
82+
);
83+
expect(supportedProfiles).to.include(`iden3comm/v1;env=${MediaType.PlainMessage}`);
84+
});
7385
});
7486

7587
const createFetchCredentialMessage = (typ: MediaType, from: DID, to: DID) => {

tests/iden3comm/zkp.test.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { DID } from '@iden3/js-iden3-core';
22
import { Token, ProvingMethodAlg } from '@iden3/js-jwz';
33
import { ZKPPackerParams } from '../../src/iden3comm/types';
44
import { AuthV2PubSignals } from '../../src/circuits';
5-
import { PROTOCOL_MESSAGE_TYPE } from '../../src/iden3comm/constants';
5+
import { MediaType, PROTOCOL_MESSAGE_TYPE } from '../../src/iden3comm/constants';
66
import { byteDecoder, byteEncoder } from '../../src';
77
import { expect } from 'chai';
88
import { initZKPPacker } from './mock/proving';
@@ -41,4 +41,12 @@ describe('zkp packer tests', () => {
4141

4242
expect(PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_RESPONSE_MESSAGE_TYPE).to.deep.equal(iden3msg.type);
4343
});
44+
45+
it('test getSupportedProfiles', async () => {
46+
const p = await initZKPPacker();
47+
const [accept] = p.getSupportedProfiles();
48+
expect(accept).to.be.eq(
49+
`iden3comm/v1;env=${MediaType.ZKPMessage};alg=groth16;circuitIds=authV2`
50+
);
51+
});
4452
});

0 commit comments

Comments
 (0)