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

fix: jsonLd tests & trust registry improvments [DEV-4432] #612

Merged
merged 13 commits into from
Oct 28, 2024
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
Loading