Skip to content

Commit cd001c6

Browse files
DIDComm alignment: expires_time & created_time (#288)
* DIDComm alignement: expires_time & created_time
1 parent d55d5e7 commit cd001c6

15 files changed

+215
-64
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@0xpolygonid/js-sdk",
3-
"version": "1.22.0",
3+
"version": "1.23.0",
44
"description": "SDK to work with Polygon ID",
55
"main": "dist/node/cjs/index.js",
66
"module": "dist/node/esm/index.js",

src/iden3comm/handlers/auth.ts

+24-12
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,19 @@ import {
1212
ZeroKnowledgeProofRequest,
1313
JSONObject
1414
} from '../types';
15-
import { DID } from '@iden3/js-iden3-core';
15+
import { DID, getUnixTimestamp } from '@iden3/js-iden3-core';
1616
import { proving } from '@iden3/js-jwz';
1717

1818
import * as uuid from 'uuid';
1919
import { ProofQuery } from '../../verifiable';
2020
import { byteDecoder, byteEncoder } from '../../utils';
21-
import { processZeroKnowledgeProofRequests } from './common';
21+
import { processZeroKnowledgeProofRequests, verifyExpiresTime } from './common';
2222
import { CircuitId } from '../../circuits';
23-
import { AbstractMessageHandler, IProtocolMessageHandler } from './message-handler';
23+
import {
24+
AbstractMessageHandler,
25+
BasicHandlerOptions,
26+
IProtocolMessageHandler
27+
} from './message-handler';
2428
import { parseAcceptProfile } from '../utils';
2529

2630
/**
@@ -30,6 +34,7 @@ import { parseAcceptProfile } from '../utils';
3034
export type AuthorizationRequestCreateOptions = {
3135
accept?: string[];
3236
scope?: ZeroKnowledgeProofRequest[];
37+
expires_time?: Date;
3338
};
3439

3540
/**
@@ -77,7 +82,9 @@ export function createAuthorizationRequestWithMessage(
7782
message: message,
7883
callbackUrl: callbackUrl,
7984
scope: opts?.scope ?? []
80-
}
85+
},
86+
created_time: getUnixTimestamp(new Date()),
87+
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
8188
};
8289
return request;
8390
}
@@ -88,10 +95,11 @@ export function createAuthorizationRequestWithMessage(
8895
*
8996
* @public
9097
*/
91-
export type AuthResponseHandlerOptions = StateVerificationOpts & {
92-
// acceptedProofGenerationDelay is the period of time in milliseconds that a generated proof remains valid.
93-
acceptedProofGenerationDelay?: number;
94-
};
98+
export type AuthResponseHandlerOptions = StateVerificationOpts &
99+
BasicHandlerOptions & {
100+
// acceptedProofGenerationDelay is the period of time in milliseconds that a generated proof remains valid.
101+
acceptedProofGenerationDelay?: number;
102+
};
95103

96104
/**
97105
* Interface that allows the processing of the authorization request in the raw format for given identifier
@@ -169,10 +177,10 @@ export type AuthMessageHandlerOptions = AuthReqOptions | AuthRespOptions;
169177
* @public
170178
* @interface AuthHandlerOptions
171179
*/
172-
export interface AuthHandlerOptions {
180+
export type AuthHandlerOptions = BasicHandlerOptions & {
173181
mediaType: MediaType;
174182
packerOptions?: JWSPackerParams;
175-
}
183+
};
176184

177185
/**
178186
*
@@ -243,7 +251,6 @@ export class AuthHandler
243251
if (authRequest.type !== PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_REQUEST_MESSAGE_TYPE) {
244252
throw new Error('Invalid message type for authorization request');
245253
}
246-
247254
// override sender did if it's explicitly specified in the auth request
248255
const to = authRequest.to ? DID.parse(authRequest.to) : ctx.senderDid;
249256
const guid = uuid.v4();
@@ -295,7 +302,9 @@ export class AuthHandler
295302
authResponse: AuthorizationResponseMessage;
296303
}> {
297304
const authRequest = await this.parseAuthorizationRequest(request);
298-
305+
if (!opts?.allowExpiredMessages) {
306+
verifyExpiresTime(authRequest);
307+
}
299308
if (!opts) {
300309
opts = {
301310
mediaType: MediaType.ZKPMessage
@@ -428,6 +437,9 @@ export class AuthHandler
428437
request: AuthorizationRequestMessage;
429438
response: AuthorizationResponseMessage;
430439
}> {
440+
if (!opts?.allowExpiredMessages) {
441+
verifyExpiresTime(response);
442+
}
431443
const authResp = (await this.handleAuthResponse(response, {
432444
request,
433445
acceptedStateTransitionDelay: opts?.acceptedStateTransitionDelay,

src/iden3comm/handlers/common.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getRandomBytes } from '@iden3/js-crypto';
22
import {
3+
BasicMessage,
34
JsonDocumentObject,
45
JWSPackerParams,
56
ZeroKnowledgeProofQuery,
@@ -8,7 +9,7 @@ import {
89
} from '../types';
910
import { mergeObjects } from '../../utils';
1011
import { RevocationStatus, W3CCredential } from '../../verifiable';
11-
import { DID } from '@iden3/js-iden3-core';
12+
import { DID, getUnixTimestamp } from '@iden3/js-iden3-core';
1213
import { IProofService } from '../../proof';
1314
import { CircuitId } from '../../circuits';
1415
import { MediaType } from '../constants';
@@ -134,3 +135,14 @@ export const processZeroKnowledgeProofRequests = async (
134135

135136
return zkpResponses;
136137
};
138+
139+
/**
140+
* Verifies that the expires_time field of a message is not in the past. Throws an error if it is.
141+
*
142+
* @param message - Basic message to verify.
143+
*/
144+
export const verifyExpiresTime = (message: BasicMessage) => {
145+
if (message?.expires_time && message.expires_time < getUnixTimestamp(new Date())) {
146+
throw new Error('Message expired');
147+
}
148+
};

src/iden3comm/handlers/contract-request.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ import { IProofService } from '../../proof/proof-service';
33
import { PROTOCOL_MESSAGE_TYPE } from '../constants';
44
import { BasicMessage, IPackageManager, ZeroKnowledgeProofResponse } from '../types';
55
import { ContractInvokeRequest, ContractInvokeResponse } from '../types/protocol/contract-request';
6-
import { DID, ChainIds } from '@iden3/js-iden3-core';
6+
import { DID, ChainIds, getUnixTimestamp } from '@iden3/js-iden3-core';
77
import { FunctionSignatures, IOnChainZKPVerifier } from '../../storage';
88
import { Signer } from 'ethers';
9-
import { processZeroKnowledgeProofRequests } from './common';
10-
import { AbstractMessageHandler, IProtocolMessageHandler } from './message-handler';
9+
import { processZeroKnowledgeProofRequests, verifyExpiresTime } from './common';
10+
import {
11+
AbstractMessageHandler,
12+
BasicHandlerOptions,
13+
IProtocolMessageHandler
14+
} from './message-handler';
1115

1216
/**
1317
* Interface that allows the processing of the contract request
@@ -40,7 +44,7 @@ export interface IContractRequestHandler {
4044
}
4145

4246
/** ContractInvokeHandlerOptions represents contract invoke handler options */
43-
export type ContractInvokeHandlerOptions = {
47+
export type ContractInvokeHandlerOptions = BasicHandlerOptions & {
4448
ethSigner: Signer;
4549
challenge?: bigint;
4650
};
@@ -193,7 +197,8 @@ export class ContractRequestHandler
193197
body: {
194198
transaction_data: request.body.transaction_data,
195199
scope: []
196-
}
200+
},
201+
created_time: getUnixTimestamp(new Date())
197202
};
198203
for (const [txHash, zkpResponses] of txHashToZkpResponseMap) {
199204
for (const zkpResponse of zkpResponses) {
@@ -222,7 +227,9 @@ export class ContractRequestHandler
222227
opts: ContractInvokeHandlerOptions
223228
): Promise<Map<string, ZeroKnowledgeProofResponse>> {
224229
const ciRequest = await this.parseContractInvokeRequest(request);
225-
230+
if (!opts.allowExpiredMessages) {
231+
verifyExpiresTime(ciRequest);
232+
}
226233
if (ciRequest.body.transaction_data.method_id !== FunctionSignatures.SubmitZKPResponseV1) {
227234
throw new Error(`please use handle method to work with other method ids`);
228235
}

src/iden3comm/handlers/credential-proposal.ts

+29-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
PackerParams
1010
} from '../types';
1111

12-
import { DID } from '@iden3/js-iden3-core';
12+
import { DID, getUnixTimestamp } from '@iden3/js-iden3-core';
1313
import * as uuid from 'uuid';
1414
import { proving } from '@iden3/js-jwz';
1515
import {
@@ -21,13 +21,24 @@ import {
2121
import { IIdentityWallet } from '../../identity';
2222
import { byteEncoder } from '../../utils';
2323
import { W3CCredential } from '../../verifiable';
24-
import { AbstractMessageHandler, IProtocolMessageHandler } from './message-handler';
24+
import {
25+
AbstractMessageHandler,
26+
BasicHandlerOptions,
27+
IProtocolMessageHandler
28+
} from './message-handler';
29+
import { verifyExpiresTime } from './common';
2530

2631
/** @beta ProposalRequestCreationOptions represents proposal-request creation options */
2732
export type ProposalRequestCreationOptions = {
2833
credentials: ProposalRequestCredential[];
2934
metadata?: { type: string; data?: JsonDocumentObject };
3035
did_doc?: DIDDocument;
36+
expires_time?: Date;
37+
};
38+
39+
/** @beta ProposalCreationOptions represents proposal creation options */
40+
export type ProposalCreationOptions = {
41+
expires_time?: Date;
3142
};
3243

3344
/**
@@ -51,7 +62,9 @@ export function createProposalRequest(
5162
to: receiver.string(),
5263
typ: MediaType.PlainMessage,
5364
type: PROTOCOL_MESSAGE_TYPE.PROPOSAL_REQUEST_MESSAGE_TYPE,
54-
body: opts
65+
body: opts,
66+
created_time: getUnixTimestamp(new Date()),
67+
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
5568
};
5669
return request;
5770
}
@@ -67,7 +80,8 @@ export function createProposalRequest(
6780
export function createProposal(
6881
sender: DID,
6982
receiver: DID,
70-
proposals?: Proposal[]
83+
proposals?: Proposal[],
84+
opts?: ProposalCreationOptions
7185
): ProposalMessage {
7286
const uuidv4 = uuid.v4();
7387
const request: ProposalMessage = {
@@ -79,7 +93,9 @@ export function createProposal(
7993
type: PROTOCOL_MESSAGE_TYPE.PROPOSAL_MESSAGE_TYPE,
8094
body: {
8195
proposals: proposals || []
82-
}
96+
},
97+
created_time: getUnixTimestamp(new Date()),
98+
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
8399
};
84100
return request;
85101
}
@@ -129,10 +145,10 @@ export interface ICredentialProposalHandler {
129145
}
130146

131147
/** @beta ProposalRequestHandlerOptions represents proposal-request handler options */
132-
export type ProposalRequestHandlerOptions = object;
148+
export type ProposalRequestHandlerOptions = BasicHandlerOptions;
133149

134150
/** @beta ProposalHandlerOptions represents proposal handler options */
135-
export type ProposalHandlerOptions = {
151+
export type ProposalHandlerOptions = BasicHandlerOptions & {
136152
proposalRequest?: ProposalRequestMessage;
137153
};
138154

@@ -310,6 +326,9 @@ export class CredentialProposalHandler
310326
if (!proposalRequest.from) {
311327
throw new Error(`failed request. empty 'from' field`);
312328
}
329+
if (!opts?.allowExpiredMessages) {
330+
verifyExpiresTime(proposalRequest);
331+
}
313332

314333
const senderDID = DID.parse(proposalRequest.from);
315334
const message = await this.handleProposalRequestMessage(proposalRequest);
@@ -332,6 +351,9 @@ export class CredentialProposalHandler
332351
* @inheritdoc ICredentialProposalHandler#handleProposal
333352
*/
334353
async handleProposal(proposal: ProposalMessage, opts?: ProposalHandlerOptions) {
354+
if (!opts?.allowExpiredMessages) {
355+
verifyExpiresTime(proposal);
356+
}
335357
if (opts?.proposalRequest && opts.proposalRequest.from !== proposal.to) {
336358
throw new Error(
337359
`sender of the request is not a target of response - expected ${opts.proposalRequest.from}, given ${proposal.to}`

0 commit comments

Comments
 (0)