Skip to content

Commit e4623c3

Browse files
check accept and esxires_time
1 parent 6c52a8d commit e4623c3

File tree

4 files changed

+125
-28
lines changed

4 files changed

+125
-28
lines changed

src/auth/auth.ts

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,29 @@ import {
2424
ICircuitStorage,
2525
cacheLoader,
2626
byteEncoder,
27-
JSONObject
27+
JSONObject,
28+
verifyExpiresTime,
29+
parseAcceptProfile
2830
} from '@0xpolygonid/js-sdk';
2931
import { Resolvable } from 'did-resolver';
3032
import { Options, DocumentLoader } from '@iden3/js-jsonld-merklization';
3133
import path from 'path';
32-
import { DID } from '@iden3/js-iden3-core';
34+
import { DID, getUnixTimestamp } from '@iden3/js-iden3-core';
3335
import { ZeroKnowledgeProofRequest } from '@0xpolygonid/js-sdk';
36+
import {
37+
MediaType,
38+
ProtocolVersion
39+
} from '@0xpolygonid/js-sdk/dist/types/iden3comm/constants';
40+
41+
/**
42+
* Options to pass to createAuthorizationRequest function
43+
* @public
44+
*/
45+
export type AuthorizationRequestCreateOptions = {
46+
accept?: string[];
47+
scope?: ZeroKnowledgeProofRequest[];
48+
expires_time?: Date;
49+
};
3450

3551
/**
3652
* createAuthorizationRequest is a function to create protocol authorization request
@@ -42,9 +58,10 @@ import { ZeroKnowledgeProofRequest } from '@0xpolygonid/js-sdk';
4258
export function createAuthorizationRequest(
4359
reason: string,
4460
sender: string,
45-
callbackUrl: string
61+
callbackUrl: string,
62+
opts?: AuthorizationRequestCreateOptions
4663
): AuthorizationRequestMessage {
47-
return createAuthorizationRequestWithMessage(reason, '', sender, callbackUrl);
64+
return createAuthorizationRequestWithMessage(reason, '', sender, callbackUrl, opts);
4865
}
4966
/**
5067
* createAuthorizationRequestWithMessage is a function to create protocol authorization request with explicit message to sign
@@ -58,7 +75,8 @@ export function createAuthorizationRequestWithMessage(
5875
reason: string,
5976
message: string,
6077
sender: string,
61-
callbackUrl: string
78+
callbackUrl: string,
79+
opts?: AuthorizationRequestCreateOptions
6280
): AuthorizationRequestMessage {
6381
const uuid = uuidv4();
6482
const request: AuthorizationRequestMessage = {
@@ -71,8 +89,10 @@ export function createAuthorizationRequestWithMessage(
7189
reason: reason,
7290
message: message,
7391
callbackUrl: callbackUrl,
74-
scope: []
75-
}
92+
scope: opts?.scope || []
93+
},
94+
created_time: getUnixTimestamp(new Date()),
95+
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
7696
};
7797
return request;
7898
}
@@ -207,10 +227,11 @@ export class Verifier {
207227
return this.setPacker(jwsPacker);
208228
}
209229

210-
public verifyAuthRequest(request: AuthorizationRequestMessage) {
211-
if (request?.expires_time && request.expires_time < Math.floor(Date.now() / 1000)) {
212-
throw new Error('Message expired');
230+
public verifyAuthRequest(request: AuthorizationRequestMessage, opts?: VerifyOpts) {
231+
if (!opts?.allowExpiredMessages) {
232+
verifyExpiresTime(request);
213233
}
234+
this.verifyProfile(request.type, request.body.accept);
214235
const groupIdValidationMap: { [k: string]: ZeroKnowledgeProofRequest[] } = {};
215236
const requestScope = request.body.scope;
216237
for (const proofRequest of requestScope) {
@@ -258,8 +279,8 @@ export class Verifier {
258279
request: AuthorizationRequestMessage,
259280
opts?: VerifyOpts
260281
) {
261-
if (response?.expires_time && response.expires_time < Math.floor(Date.now() / 1000)) {
262-
throw new Error('Message expired');
282+
if (!opts?.allowExpiredMessages) {
283+
verifyExpiresTime(request);
263284
}
264285
if ((request.body.message ?? '') !== (response.body.message ?? '')) {
265286
throw new Error('message for signing from request is not presented in response');
@@ -414,4 +435,31 @@ export class Verifier {
414435
this.setupJWSPacker(new KMS(), didResolver);
415436
}
416437
}
438+
439+
private verifyProfile(messageType: string, profile?: string[] | undefined) {
440+
if (!profile?.length) {
441+
return;
442+
}
443+
const supportedMediaTypes: MediaType[] = [];
444+
for (const acceptProfile of profile) {
445+
// 1. check protocol version
446+
const { protocolVersion, env } = parseAcceptProfile(acceptProfile);
447+
const messageTypeVersion = Number(messageType.split('/').at(-2));
448+
if (
449+
protocolVersion !== ProtocolVersion.V1 ||
450+
(protocolVersion === ProtocolVersion.V1 &&
451+
(messageTypeVersion < 1 || messageTypeVersion >= 2))
452+
) {
453+
continue;
454+
}
455+
// 2. check packer support
456+
if (this.packageManager.isProfileSupported(env, acceptProfile)) {
457+
supportedMediaTypes.push(env);
458+
}
459+
}
460+
461+
if (!supportedMediaTypes.length) {
462+
throw new Error('no packer with profile which meets `accept` header requirements');
463+
}
464+
}
417465
}

src/circuits/atomicV3.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
3131
* Verifies the public signals for the AtomicQueryV3 circuit.
3232
* @beta
3333
*/
34-
export class AtomicQueryV3PubSignalsVerifier extends IDOwnershipPubSignals implements PubSignalsVerifier {
34+
export class AtomicQueryV3PubSignalsVerifier
35+
extends IDOwnershipPubSignals
36+
implements PubSignalsVerifier
37+
{
3538
pubSignals = new AtomicQueryV3PubSignals();
3639

3740
constructor(pubSignals: string[]) {

src/circuits/registry.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export type VerifyOpts = {
1313
acceptedStateTransitionDelay?: number;
1414
// acceptedProofGenerationDelay is the period of time in milliseconds that a generated proof remains valid.
1515
acceptedProofGenerationDelay?: number;
16+
// allowExpiredMessages is a flag that allows the verification of expired messages.
17+
allowExpiredMessages?: boolean;
1618
};
1719

1820
export interface PubSignalsVerifier {

test/auth.test.ts

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { v4 as uuidv4 } from 'uuid';
33
import {
44
AuthorizationRequestMessage,
55
AuthorizationResponseMessage,
6+
CircuitId,
67
FSCircuitStorage,
78
KMS,
89
NativeProver,
910
PROTOCOL_CONSTANTS,
1011
PackageManager,
11-
ZeroKnowledgeProofRequest
12+
ZeroKnowledgeProofRequest,
13+
buildAccept
1214
} from '@0xpolygonid/js-sdk';
1315
import { AuthPubSignalsV2 } from '@lib/circuits/authV2';
1416
import {
@@ -19,9 +21,23 @@ import {
1921
import { Circuits } from '@lib/circuits/registry';
2022
import path from 'path';
2123
import { resolveDIDDocument, resolvers, schemaLoader, testOpts } from './mocks';
24+
import { getDateFromUnixTimestamp, getUnixTimestamp } from '@iden3/js-iden3-core';
25+
import {
26+
AcceptAuthCircuits,
27+
MediaType,
28+
ProtocolVersion
29+
} from '@0xpolygonid/js-sdk/dist/types/iden3comm/constants';
2230

2331
describe('auth tests', () => {
2432
const connectionString = process.env.IPFS_URL ?? 'https://ipfs.io';
33+
const acceptProfile = buildAccept([
34+
{
35+
protocolVersion: ProtocolVersion.V1,
36+
env: MediaType.ZKPMessage,
37+
circuits: [AcceptAuthCircuits.AuthV2]
38+
}
39+
]);
40+
const expiresTime = getDateFromUnixTimestamp(getUnixTimestamp(new Date()) + 5 * 60);
2541
it('createAuthorizationRequest', () => {
2642
const sender = 'did:iden3:polygon:amoy:xCRp75DgAdS63W65fmXHz6p9DwdonuRU9e46DifhX';
2743
const callback = 'https://test.com/callback';
@@ -37,7 +53,7 @@ describe('auth tests', () => {
3753

3854
const proofRequest: ZeroKnowledgeProofRequest = {
3955
id: 1,
40-
circuitId: 'credentialAtomicQueryMTPV2',
56+
circuitId: CircuitId.AtomicQueryMTPV2,
4157
query: {
4258
allowedIssuers: ['1195GJqgw6YEsKFwj63GY87MMxPL9kwDKxPUiwMLN9'],
4359
type: 'KYCAgeCredential',
@@ -63,7 +79,11 @@ describe('auth tests', () => {
6379
'kyc verification',
6480
msg,
6581
sender,
66-
callback
82+
callback,
83+
{
84+
accept: acceptProfile,
85+
expires_time: expiresTime
86+
}
6787
);
6888

6989
const response: AuthorizationResponseMessage = {
@@ -101,7 +121,11 @@ describe('auth tests', () => {
101121
reason,
102122
message,
103123
sender,
104-
callback
124+
callback,
125+
{
126+
accept: acceptProfile,
127+
expires_time: expiresTime
128+
}
105129
);
106130
expect(request.body.scope.length).toEqual(0);
107131
expect(request.body.callbackUrl).toEqual(callback);
@@ -112,7 +136,7 @@ describe('auth tests', () => {
112136

113137
const proofRequest: ZeroKnowledgeProofRequest = {
114138
id: 1,
115-
circuitId: 'credentialAtomicQueryMTPV2',
139+
circuitId: CircuitId.AtomicQueryMTPV2,
116140
query: {
117141
allowedIssuers: ['*'],
118142
context:
@@ -266,7 +290,11 @@ describe('auth tests', () => {
266290
reason,
267291
message,
268292
sender,
269-
callback
293+
callback,
294+
{
295+
accept: acceptProfile,
296+
expires_time: expiresTime
297+
}
270298
);
271299
expect(request.body.scope.length).toEqual(0);
272300
expect(request.body.callbackUrl).toEqual(callback);
@@ -277,7 +305,7 @@ describe('auth tests', () => {
277305

278306
const proofRequest: ZeroKnowledgeProofRequest = {
279307
id: 1,
280-
circuitId: 'credentialAtomicQuerySigV2',
308+
circuitId: CircuitId.AtomicQuerySigV2,
281309
query: {
282310
allowedIssuers: ['*'],
283311
context:
@@ -444,7 +472,11 @@ describe('auth tests', () => {
444472
reason,
445473
'message to sign',
446474
sender,
447-
callback
475+
callback,
476+
{
477+
accept: acceptProfile,
478+
expires_time: expiresTime
479+
}
448480
);
449481
expect(request.body.scope.length).toEqual(0);
450482
expect(request.body.callbackUrl).toEqual(callback);
@@ -453,7 +485,7 @@ describe('auth tests', () => {
453485

454486
const proofRequest: ZeroKnowledgeProofRequest = {
455487
id: 1,
456-
circuitId: 'credentialAtomicQuerySigV2',
488+
circuitId: CircuitId.AtomicQuerySigV2,
457489
query: {
458490
allowedIssuers: ['*'],
459491
context:
@@ -492,7 +524,11 @@ describe('auth tests', () => {
492524
const request: AuthorizationRequestMessage = createAuthorizationRequest(
493525
reason,
494526
sender,
495-
callback
527+
callback,
528+
{
529+
accept: acceptProfile,
530+
expires_time: expiresTime
531+
}
496532
);
497533
expect(request.body.scope.length).toEqual(0);
498534
expect(request.body.callbackUrl).toEqual(callback);
@@ -506,7 +542,7 @@ describe('auth tests', () => {
506542

507543
const proofRequest: ZeroKnowledgeProofRequest = {
508544
id: 1,
509-
circuitId: 'credentialAtomicQuerySigV2',
545+
circuitId: CircuitId.AtomicQuerySigV2,
510546
query: {
511547
allowedIssuers: ['*'],
512548
context:
@@ -561,7 +597,11 @@ describe('auth tests', () => {
561597
reason,
562598
'message to sign',
563599
sender,
564-
callback
600+
callback,
601+
{
602+
accept: acceptProfile,
603+
expires_time: expiresTime
604+
}
565605
);
566606
expect(request.body.scope.length).toEqual(0);
567607
expect(request.body.callbackUrl).toEqual(callback);
@@ -570,7 +610,7 @@ describe('auth tests', () => {
570610

571611
const proofRequest: ZeroKnowledgeProofRequest = {
572612
id: 1,
573-
circuitId: 'credentialAtomicQuerySigV2',
613+
circuitId: CircuitId.AtomicQuerySigV2,
574614
query: {
575615
allowedIssuers: ['*'],
576616
context:
@@ -607,7 +647,11 @@ describe('auth tests', () => {
607647
reason,
608648
'message to sign',
609649
sender,
610-
callback
650+
callback,
651+
{
652+
accept: acceptProfile,
653+
expires_time: expiresTime
654+
}
611655
);
612656
expect(request.body.scope.length).toEqual(0);
613657
expect(request.body.callbackUrl).toEqual(callback);
@@ -616,7 +660,7 @@ describe('auth tests', () => {
616660

617661
const proofRequest: ZeroKnowledgeProofRequest = {
618662
id: 1,
619-
circuitId: 'credentialAtomicQuerySigV2',
663+
circuitId: CircuitId.AtomicQuerySigV2,
620664
query: {
621665
allowedIssuers: ['*'],
622666
context:

0 commit comments

Comments
 (0)