Skip to content

Commit

Permalink
fix: jsonLd tests & trust registry improvments [DEV-4432] (#612)
Browse files Browse the repository at this point in the history
* chore: Rename authorize to authorise

* Switch type to types in accreditedFor

* Debug jsonLD tests

* fix: Add valid context in jsonld

* Update swagger

* fetchRemoteContexts

* Debug jsonwebkey

* Skip jsonwebkey test

* Add custom gas

* Update package-lock.json

* Update accreditation.ts

* Add custom fee

---------

Co-authored-by: Ankur Banerjee <[email protected]>
  • Loading branch information
DaevMithran and ankurdotb authored Oct 28, 2024
1 parent 7a0eac0 commit e61d3f8
Show file tree
Hide file tree
Showing 20 changed files with 87 additions and 81 deletions.
49 changes: 25 additions & 24 deletions src/controllers/api/accreditation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
RevokeAccreditationRequestBody,
RevokeAccreditationRequestQuery,
RevokeAccreditationResponseBody,
SchemaUrlType,
SuspendAccreditationRequestBody,
SuspendAccreditationRequestQuery,
SuspendAccreditationResponseBody,
Expand Down Expand Up @@ -35,7 +36,7 @@ export class AccreditationController {
query('accreditationType')
.exists()
.isIn([
AccreditationRequestType.authorize,
AccreditationRequestType.authorise,
AccreditationRequestType.accredit,
AccreditationRequestType.attest,
])
Expand All @@ -45,36 +46,36 @@ export class AccreditationController {
body('subjectDid').exists().isDID().bail(),
body('schemas').exists().isArray().withMessage('schemas must be a array').bail(),
body('schemas.*.url').isString().withMessage('schema urls must be a string').bail(),
body('schemas.*.type')
body('schemas.*.types')
.custom((value) => typeof value === 'string' || (Array.isArray(value) && typeof value[0] === 'string'))
.withMessage('schema type must be a string'),
.withMessage('schema.types must be a string or a string array'),
body('parentAccreditation').optional().isString().withMessage('parentAccreditation must be a string').bail(),
body('rootAuthorization').optional().isString().withMessage('rootAuthorization must be a string').bail(),
body('rootAuthorisation').optional().isString().withMessage('rootAuthorisation must be a string').bail(),
body('trustFramework').optional().isString().withMessage('trustFramework must be a string').bail(),
body('trustFrameworkId').optional().isString().withMessage('trustFrameworkId must be a string').bail(),
query('accreditationType')
.custom((value, { req }) => {
const { parentAccreditation, rootAuthorization, trustFramework, trustFrameworkId } = req.body;
const { parentAccreditation, rootAuthorisation, trustFramework, trustFrameworkId } = req.body;

const hasParentOrRoot = parentAccreditation || rootAuthorization;
const hasParentOrRoot = parentAccreditation || rootAuthorisation;

if (
!hasParentOrRoot &&
(value === AccreditationRequestType.accredit || value === AccreditationRequestType.attest)
) {
throw new Error('parentAccreditation or rootAuthorization is required');
throw new Error('parentAccreditation or rootAuthorisation is required');
}

if (hasParentOrRoot && value === AccreditationRequestType.authorize) {
if (hasParentOrRoot && value === AccreditationRequestType.authorise) {
throw new Error(
'parentAccreditation or rootAuthorization is not required for an authorize operation'
'parentAccreditation or rootAuthorisation is not required for an authorise operation'
);
}

const hasTrustFramework = trustFramework && trustFrameworkId;

if (!hasTrustFramework && value === AccreditationRequestType.authorize) {
throw new Error('trustFramework and trustFrameworkId are required for an authorize operation');
if (!hasTrustFramework && value === AccreditationRequestType.authorise) {
throw new Error('trustFramework and trustFrameworkId are required for an authorise operation');
}

return true;
Expand All @@ -96,9 +97,9 @@ export class AccreditationController {
body('resourceType').optional().isString().withMessage('resourceType should be a string').bail(),
body('schemas').optional().isArray().withMessage('schemas must be a array').bail(),
body('schemas.*.url').isString().withMessage('schema urls must be a string').bail(),
body('schemas.*.type')
body('schemas.*.types')
.custom((value) => typeof value === 'string' || (Array.isArray(value) && typeof value[0] === 'string'))
.withMessage('schema type must be a string'),
.withMessage('schema.types must be a string or a string array'),
body('did')
.custom((value, { req }) => {
const { didUrl, resourceId, resourceName, resourceType } = req.body;
Expand Down Expand Up @@ -149,7 +150,7 @@ export class AccreditationController {
* schema:
* type: string
* enum:
* - authorize
* - authorise
* - accredit
* - attest
* required: true
Expand Down Expand Up @@ -196,7 +197,7 @@ export class AccreditationController {
schemas,
type,
parentAccreditation,
rootAuthorization,
rootAuthorisation,
trustFramework,
trustFrameworkId,
attributes,
Expand Down Expand Up @@ -236,9 +237,9 @@ export class AccreditationController {
}

const resourceId = v4();
const accreditedFor = schemas.map(({ url, type }: any) => ({
const accreditedFor = schemas.map(({ url, types }: SchemaUrlType) => ({
schemaId: url,
type,
types: Array.isArray(types) ? types : [types],
}));

// construct credential request
Expand All @@ -259,7 +260,7 @@ export class AccreditationController {

let resourceType: string;
switch (accreditationType) {
case AccreditationRequestType.authorize:
case AccreditationRequestType.authorise:
resourceType = DIDAccreditationTypes.VerifiableAuthorisationForTrustChain;
credentialRequest.type = [...(type || []), resourceType];
credentialRequest.termsOfUse = {
Expand All @@ -274,7 +275,7 @@ export class AccreditationController {
credentialRequest.termsOfUse = {
type: resourceType,
parentAccreditation,
rootAuthorization,
rootAuthorisation,
};
break;
case AccreditationRequestType.attest:
Expand All @@ -283,7 +284,7 @@ export class AccreditationController {
credentialRequest.termsOfUse = {
type: resourceType,
parentAccreditation,
rootAuthorization,
rootAuthorisation,
};
break;
}
Expand All @@ -300,12 +301,12 @@ export class AccreditationController {
true,
false,
response.locals.customer,
rootAuthorization
rootAuthorisation
);

if (result.success === false) {
return response.status(result.status).send({
error: `Invalid Request: Root Authorization or parent Accreditation is not valid: ${result.error}`,
error: `Invalid Request: Root Authorisation or parent Accreditation is not valid: ${result.error}`,
});
}
}
Expand Down Expand Up @@ -402,9 +403,9 @@ export class AccreditationController {
}

try {
const accreditedFor = schemas?.map(({ url, type }: any) => ({
const accreditedFor = schemas?.map(({ url, types }: SchemaUrlType) => ({
schemaId: url,
type,
types: Array.isArray(types) ? types : [types],
}));

const result = await AccreditationService.instance.verify_accreditation(
Expand Down
6 changes: 4 additions & 2 deletions src/controllers/api/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ export class CredentialController {
public async verify(request: Request, response: Response) {
// Get params from request
const { credential, policies } = request.body as VerifyCredentialRequestBody;
const { verifyStatus, allowDeactivatedDid } = request.query as VerifyCredentialRequestQuery;
const { verifyStatus, allowDeactivatedDid, fetchRemoteContexts } =
request.query as VerifyCredentialRequestQuery;

// Create credential object
const cheqdCredential = new CheqdW3CVerifiableCredential(credential);
Expand All @@ -275,14 +276,15 @@ export class CredentialController {
{
verifyStatus,
policies,
fetchRemoteContexts,
},
response.locals.customer
);

if (verifyResult.error) {
return response.status(StatusCodes.BAD_REQUEST).json({
verified: verifyResult.verified,
error: `verify: ${verifyResult.error.message}`,
error: `verify: ${JSON.stringify(verifyResult.error)}`,
} satisfies UnsuccesfulVerifyCredentialResponseBody);
}

Expand Down
18 changes: 10 additions & 8 deletions src/services/api/accreditation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class AccreditationService {
verifyStatus: boolean,
allowDeactivatedDid: boolean,
customer: CustomerEntity,
rootAuthorization?: string,
rootAuthorisation?: string,
policies?: VerificationPolicies
): Promise<SafeAPIResponse<{ verified: boolean }>> {
// Get strategy e.g. postgres or local
Expand Down Expand Up @@ -74,7 +74,9 @@ export class AccreditationService {
if (
!accreditedFor.every((schema) =>
accreditation.credentialSubject.accreditedFor.some(
(accredited) => accredited.type === schema.type && accredited.schemaId === schema.schemaId
(accredited) =>
schema.types.every((value) => (accredited.types || []).includes(value)) &&
accredited.schemaId === schema.schemaId
)
)
) {
Expand All @@ -96,7 +98,7 @@ export class AccreditationService {
);

if (!initialVerifyResult) {
initialVerifyResult = { ...verifyResult, rootAuthorization };
initialVerifyResult = { ...verifyResult, rootAuthorisation };
}

if (verifyResult.error) {
Expand Down Expand Up @@ -134,12 +136,12 @@ export class AccreditationService {
isTypeAccreditation === DIDAccreditationTypes.VerifiableAccreditationToAttest
) {
const termsOfUse = accreditation.termsOfUse;
if (!termsOfUse || !termsOfUse.parentAccreditation || !termsOfUse.rootAuthorization) {
if (!termsOfUse || !termsOfUse.parentAccreditation || !termsOfUse.rootAuthorisation) {
return {
success: false,
status: StatusCodes.BAD_REQUEST,
data: initialVerifyResult,
error: `Error on verifying accreditation ${accreditationUrl}: Missing parentAccreditaiton and rootAuthorization in termsOfUse for accreditation: ${accreditationUrl}`,
error: `Error on verifying accreditation ${accreditationUrl}: Missing parentAccreditaiton and rootAuthorisation in termsOfUse for accreditation: ${accreditationUrl}`,
};
}

Expand All @@ -150,16 +152,16 @@ export class AccreditationService {
accreditedSubject = accreditorDid;
accreditedFor = accreditation.credentialSubject.accreditedFor;

if (rootAuthorization && rootAuthorization !== termsOfUse.rootAuthorization) {
if (rootAuthorisation && rootAuthorisation !== termsOfUse.rootAuthorisation) {
return {
status: StatusCodes.OK,
success: false,
data: initialVerifyResult,
error: `Error on verifying accreditation ${accreditationUrl}: Expected accreditation to be linked to root accreditation ${rootAuthorization}, but found it linked to DID ${termsOfUse.rootAuthorization} instead`,
error: `Error on verifying accreditation ${accreditationUrl}: Expected accreditation to be linked to root accreditation ${rootAuthorisation}, but found it linked to DID ${termsOfUse.rootAuthorisation} instead`,
};
}

rootAuthorization = termsOfUse.rootAuthorization;
rootAuthorisation = termsOfUse.rootAuthorisation;
} else {
return {
status: StatusCodes.OK,
Expand Down
6 changes: 5 additions & 1 deletion src/services/identity/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import {
DefaultStatusList2021StatusPurposeType,
TransactionResult,
} from '@cheqd/did-provider-cheqd';
import type { CheqdNetwork } from '@cheqd/sdk';
import { ResourceModule, type CheqdNetwork } from '@cheqd/sdk';
import { getDidKeyResolver as KeyDidResolver } from '@veramo/did-provider-key';
import { Resolver, ResolverRegistry } from 'did-resolver';
import { DefaultDidUrlPattern, CreateAgentRequest, VeramoAgent } from '../../types/shared.js';
Expand Down Expand Up @@ -305,6 +305,10 @@ export class Veramo {
payload,
network: network as CheqdNetwork,
signInputs: publicKeyHexs,
fee: {
amount: [ResourceModule.fees.DefaultCreateResourceJsonFee],
gas: '2000000',
},
} satisfies ICheqdCreateLinkedResourceArgs);
return result;
} catch (error) {
Expand Down
14 changes: 7 additions & 7 deletions src/static/swagger-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -557,16 +557,16 @@
"description": "DID URL of the parent Verifiable Accreditation, required for accredit/attest operation.",
"type": "string"
},
"rootAuthorization": {
"rootAuthorisation": {
"description": "DID URL of the root Verifiable Accreditation, required for accredit/attest operation.",
"type": "string"
},
"trustFramework": {
"description": "Name or Type of the Trust Framework, required for authorize operation.",
"description": "Name or Type of the Trust Framework, required for authorise operation.",
"type": "string"
},
"trustFrameworkId": {
"description": "Url of the Trust Framework, required for authorize operation.",
"description": "Url of the Trust Framework, required for authorise operation.",
"type": "string"
},
"type": {
Expand Down Expand Up @@ -702,11 +702,11 @@
}
],
"format": "jwt",
"accreditationName": "authorizeAccreditation",
"accreditationName": "authoriseAccreditation",
"trustFramework": "https://learn.cheqd.io/governance/start",
"trustFrameworkId": "cheqd Governance Framework",
"parentAccreditation": "did:cheqd:testnet:15b74787-6e48-4fd5-8020-eab24e990578?resourceName=accreditAccreditation&resourceType=VerifiableAccreditationToAccredit",
"rootAuthorization": "did:cheqd:testnet:5RpEg66jhhbmASWPXJRWrA?resourceName=authorizeAccreditation&resourceType=VerifiableAuthorisationForTrustChain",
"rootAuthorisation": "did:cheqd:testnet:5RpEg66jhhbmASWPXJRWrA?resourceName=authoriseAccreditation&resourceType=VerifiableAuthorisationForTrustChain",
"credentialStatus": {
"statusPurpose": "revocation",
"statusListName": "employee-credentials",
Expand Down Expand Up @@ -2350,7 +2350,7 @@
"SchemaUrl": {
"type": "object",
"properties": {
"type": {
"types": {
"type": "string"
},
"url": {
Expand Down Expand Up @@ -2517,7 +2517,7 @@
"schema": {
"type": "string",
"enum": [
"authorize",
"authorise",
"accredit",
"attest"
]
Expand Down
10 changes: 5 additions & 5 deletions src/types/accreditation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ export enum DIDAccreditationTypes {
}

export enum AccreditationRequestType {
authorize = 'authorize',
authorise = 'authorise',
accredit = 'accredit',
attest = 'attest',
}

export type AccreditationSchemaType = {
type: string;
types: string[];
schemaId: string;
};

export type SchemaUrlType = {
type: string;
types: string[] | string;
url: string;
};

Expand All @@ -40,14 +40,14 @@ export type DIDAccreditationRequestBody = Omit<
accreditationName: string;
attributes?: Record<string, unknown>;
type: string[] | undefined;
rootAuthorization?: string;
rootAuthorisation?: string;
parentAccreditation?: string;
trustFramework?: string;
trustFrameworkId?: string;
};

export type DIDAccreditationRequestParams = {
accreditationType: 'authorize' | 'accredit' | 'attest';
accreditationType: 'authorise' | 'accredit' | 'attest';
};

export interface DIDUrlParams {
Expand Down
Loading

0 comments on commit e61d3f8

Please sign in to comment.