Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verify expires_time #100

Merged
merged 8 commits into from
Nov 26, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
check accept and esxires_time
  • Loading branch information
volodymyr-basiuk committed Nov 25, 2024
commit e4623c3b2b429544b673189002ad47d41e5faf1e
72 changes: 60 additions & 12 deletions src/auth/auth.ts
Original file line number Diff line number Diff line change
@@ -24,13 +24,29 @@
ICircuitStorage,
cacheLoader,
byteEncoder,
JSONObject
JSONObject,
verifyExpiresTime,

Check failure on line 28 in src/auth/auth.ts

GitHub Actions / build (18.14.0)

Module '"@0xpolygonid/js-sdk"' has no exported member 'verifyExpiresTime'.
parseAcceptProfile

Check failure on line 29 in src/auth/auth.ts

GitHub Actions / build (18.14.0)

Module '"@0xpolygonid/js-sdk"' has no exported member 'parseAcceptProfile'.
} from '@0xpolygonid/js-sdk';
import { Resolvable } from 'did-resolver';
import { Options, DocumentLoader } from '@iden3/js-jsonld-merklization';
import path from 'path';
import { DID } from '@iden3/js-iden3-core';
import { DID, getUnixTimestamp } from '@iden3/js-iden3-core';
import { ZeroKnowledgeProofRequest } from '@0xpolygonid/js-sdk';
import {

Check failure on line 36 in src/auth/auth.ts

GitHub Actions / build (18.14.0)

Module '"@0xpolygonid/js-sdk/dist/types/iden3comm/constants"' has no exported member 'ProtocolVersion'.
MediaType,
ProtocolVersion
} from '@0xpolygonid/js-sdk/dist/types/iden3comm/constants';

/**
* Options to pass to createAuthorizationRequest function
* @public
*/
export type AuthorizationRequestCreateOptions = {
accept?: string[];
scope?: ZeroKnowledgeProofRequest[];
expires_time?: Date;
};

/**
* createAuthorizationRequest is a function to create protocol authorization request
@@ -42,9 +58,10 @@
export function createAuthorizationRequest(
reason: string,
sender: string,
callbackUrl: string
callbackUrl: string,
opts?: AuthorizationRequestCreateOptions
): AuthorizationRequestMessage {
return createAuthorizationRequestWithMessage(reason, '', sender, callbackUrl);
return createAuthorizationRequestWithMessage(reason, '', sender, callbackUrl, opts);
}
/**
* createAuthorizationRequestWithMessage is a function to create protocol authorization request with explicit message to sign
@@ -58,7 +75,8 @@
reason: string,
message: string,
sender: string,
callbackUrl: string
callbackUrl: string,
opts?: AuthorizationRequestCreateOptions
): AuthorizationRequestMessage {
const uuid = uuidv4();
const request: AuthorizationRequestMessage = {
@@ -70,9 +88,11 @@
body: {
reason: reason,
message: message,
callbackUrl: callbackUrl,

Check failure on line 91 in src/auth/auth.ts

GitHub Actions / build (18.14.0)

Type '{ id: string; thid: string; from: string; typ: PROTOCOL_CONSTANTS.MediaType.PlainMessage; type: "https://iden3-communication.io/authorization/1.0/request"; body: { reason: string; message: string; callbackUrl: string; scope: ZeroKnowledgeProofRequest[]; }; created_time: number; expires_time: number | undefined; }' is not assignable to type 'AuthorizationRequestMessage'.
scope: []
}
scope: opts?.scope || []
},
created_time: getUnixTimestamp(new Date()),
expires_time: opts?.expires_time ? getUnixTimestamp(opts.expires_time) : undefined
};
return request;
}
@@ -207,10 +227,11 @@
return this.setPacker(jwsPacker);
}

public verifyAuthRequest(request: AuthorizationRequestMessage) {
if (request?.expires_time && request.expires_time < Math.floor(Date.now() / 1000)) {
throw new Error('Message expired');
public verifyAuthRequest(request: AuthorizationRequestMessage, opts?: VerifyOpts) {
if (!opts?.allowExpiredMessages) {

Check failure on line 231 in src/auth/auth.ts

GitHub Actions / build (18.14.0)

Property 'accept' does not exist on type 'AuthorizationRequestMessageBody'.
verifyExpiresTime(request);
}
this.verifyProfile(request.type, request.body.accept);
const groupIdValidationMap: { [k: string]: ZeroKnowledgeProofRequest[] } = {};
const requestScope = request.body.scope;
for (const proofRequest of requestScope) {
@@ -258,8 +279,8 @@
request: AuthorizationRequestMessage,
opts?: VerifyOpts
) {
if (response?.expires_time && response.expires_time < Math.floor(Date.now() / 1000)) {
throw new Error('Message expired');
if (!opts?.allowExpiredMessages) {
verifyExpiresTime(request);
}
if ((request.body.message ?? '') !== (response.body.message ?? '')) {
throw new Error('message for signing from request is not presented in response');
@@ -414,4 +435,31 @@
this.setupJWSPacker(new KMS(), didResolver);
}
}

private verifyProfile(messageType: string, profile?: string[] | undefined) {
if (!profile?.length) {
return;
}
const supportedMediaTypes: MediaType[] = [];
for (const acceptProfile of profile) {
// 1. check protocol version
const { protocolVersion, env } = parseAcceptProfile(acceptProfile);
const messageTypeVersion = Number(messageType.split('/').at(-2));
if (
protocolVersion !== ProtocolVersion.V1 ||
(protocolVersion === ProtocolVersion.V1 &&
(messageTypeVersion < 1 || messageTypeVersion >= 2))
) {
continue;

Check failure on line 453 in src/auth/auth.ts

GitHub Actions / build (18.14.0)

Property 'isProfileSupported' does not exist on type 'PackageManager'.
}
// 2. check packer support
if (this.packageManager.isProfileSupported(env, acceptProfile)) {
supportedMediaTypes.push(env);
}
}

if (!supportedMediaTypes.length) {
throw new Error('no packer with profile which meets `accept` header requirements');
}
}
}
5 changes: 4 additions & 1 deletion src/circuits/atomicV3.ts
Original file line number Diff line number Diff line change
@@ -31,7 +31,10 @@ const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour
* Verifies the public signals for the AtomicQueryV3 circuit.
* @beta
*/
export class AtomicQueryV3PubSignalsVerifier extends IDOwnershipPubSignals implements PubSignalsVerifier {
export class AtomicQueryV3PubSignalsVerifier
extends IDOwnershipPubSignals
implements PubSignalsVerifier
{
pubSignals = new AtomicQueryV3PubSignals();

constructor(pubSignals: string[]) {
2 changes: 2 additions & 0 deletions src/circuits/registry.ts
Original file line number Diff line number Diff line change
@@ -13,6 +13,8 @@ export type VerifyOpts = {
acceptedStateTransitionDelay?: number;
// acceptedProofGenerationDelay is the period of time in milliseconds that a generated proof remains valid.
acceptedProofGenerationDelay?: number;
// allowExpiredMessages is a flag that allows the verification of expired messages.
allowExpiredMessages?: boolean;
};

export interface PubSignalsVerifier {
74 changes: 59 additions & 15 deletions test/auth.test.ts
Original file line number Diff line number Diff line change
@@ -3,12 +3,14 @@ import { v4 as uuidv4 } from 'uuid';
import {
AuthorizationRequestMessage,
AuthorizationResponseMessage,
CircuitId,
FSCircuitStorage,
KMS,
NativeProver,
PROTOCOL_CONSTANTS,
PackageManager,
ZeroKnowledgeProofRequest
ZeroKnowledgeProofRequest,
buildAccept
} from '@0xpolygonid/js-sdk';
import { AuthPubSignalsV2 } from '@lib/circuits/authV2';
import {
@@ -19,9 +21,23 @@ import {
import { Circuits } from '@lib/circuits/registry';
import path from 'path';
import { resolveDIDDocument, resolvers, schemaLoader, testOpts } from './mocks';
import { getDateFromUnixTimestamp, getUnixTimestamp } from '@iden3/js-iden3-core';
import {
AcceptAuthCircuits,
MediaType,
ProtocolVersion
} from '@0xpolygonid/js-sdk/dist/types/iden3comm/constants';

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

const proofRequest: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: 'credentialAtomicQueryMTPV2',
circuitId: CircuitId.AtomicQueryMTPV2,
query: {
allowedIssuers: ['1195GJqgw6YEsKFwj63GY87MMxPL9kwDKxPUiwMLN9'],
type: 'KYCAgeCredential',
@@ -63,7 +79,11 @@ describe('auth tests', () => {
'kyc verification',
msg,
sender,
callback
callback,
{
accept: acceptProfile,
expires_time: expiresTime
}
);

const response: AuthorizationResponseMessage = {
@@ -101,7 +121,11 @@ describe('auth tests', () => {
reason,
message,
sender,
callback
callback,
{
accept: acceptProfile,
expires_time: expiresTime
}
);
expect(request.body.scope.length).toEqual(0);
expect(request.body.callbackUrl).toEqual(callback);
@@ -112,7 +136,7 @@ describe('auth tests', () => {

const proofRequest: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: 'credentialAtomicQueryMTPV2',
circuitId: CircuitId.AtomicQueryMTPV2,
query: {
allowedIssuers: ['*'],
context:
@@ -266,7 +290,11 @@ describe('auth tests', () => {
reason,
message,
sender,
callback
callback,
{
accept: acceptProfile,
expires_time: expiresTime
}
);
expect(request.body.scope.length).toEqual(0);
expect(request.body.callbackUrl).toEqual(callback);
@@ -277,7 +305,7 @@ describe('auth tests', () => {

const proofRequest: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
circuitId: CircuitId.AtomicQuerySigV2,
query: {
allowedIssuers: ['*'],
context:
@@ -444,7 +472,11 @@ describe('auth tests', () => {
reason,
'message to sign',
sender,
callback
callback,
{
accept: acceptProfile,
expires_time: expiresTime
}
);
expect(request.body.scope.length).toEqual(0);
expect(request.body.callbackUrl).toEqual(callback);
@@ -453,7 +485,7 @@ describe('auth tests', () => {

const proofRequest: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
circuitId: CircuitId.AtomicQuerySigV2,
query: {
allowedIssuers: ['*'],
context:
@@ -492,7 +524,11 @@ describe('auth tests', () => {
const request: AuthorizationRequestMessage = createAuthorizationRequest(
reason,
sender,
callback
callback,
{
accept: acceptProfile,
expires_time: expiresTime
}
);
expect(request.body.scope.length).toEqual(0);
expect(request.body.callbackUrl).toEqual(callback);
@@ -506,7 +542,7 @@ describe('auth tests', () => {

const proofRequest: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
circuitId: CircuitId.AtomicQuerySigV2,
query: {
allowedIssuers: ['*'],
context:
@@ -561,7 +597,11 @@ describe('auth tests', () => {
reason,
'message to sign',
sender,
callback
callback,
{
accept: acceptProfile,
expires_time: expiresTime
}
);
expect(request.body.scope.length).toEqual(0);
expect(request.body.callbackUrl).toEqual(callback);
@@ -570,7 +610,7 @@ describe('auth tests', () => {

const proofRequest: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
circuitId: CircuitId.AtomicQuerySigV2,
query: {
allowedIssuers: ['*'],
context:
@@ -607,7 +647,11 @@ describe('auth tests', () => {
reason,
'message to sign',
sender,
callback
callback,
{
accept: acceptProfile,
expires_time: expiresTime
}
);
expect(request.body.scope.length).toEqual(0);
expect(request.body.callbackUrl).toEqual(callback);
@@ -616,7 +660,7 @@ describe('auth tests', () => {

const proofRequest: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
circuitId: CircuitId.AtomicQuerySigV2,
query: {
allowedIssuers: ['*'],
context:
Loading