From c2003700924f732920c61cbfa6424b7be03eef62 Mon Sep 17 00:00:00 2001 From: "alexey.lunin@vereign.com" <alexey.lunin@vereign.com> Date: Mon, 11 Mar 2024 13:08:09 +0200 Subject: [PATCH] add some dashbord changes for credential revocation --- agent-swagger.json | 3 + apps/dashboard/src/hooks/auth/useAuth.ts | 2 +- .../modals/NewCredentialDefDialog/index.tsx | 29 +- libs/askar/src/askar/agent.service.ts | 17 +- libs/clients/src/frontend/agent_gen.ts | 252 ++++++++++++++++-- ...reate.credential.definition.request.dto.ts | 6 +- 6 files changed, 279 insertions(+), 30 deletions(-) diff --git a/agent-swagger.json b/agent-swagger.json index 1f69f9f0..4dc725fc 100644 --- a/agent-swagger.json +++ b/agent-swagger.json @@ -1380,6 +1380,9 @@ }, "tag": { "type": "string" + }, + "supportRevocation": { + "type": "boolean" } }, "required": [ diff --git a/apps/dashboard/src/hooks/auth/useAuth.ts b/apps/dashboard/src/hooks/auth/useAuth.ts index 2eda3980..e19e57a5 100644 --- a/apps/dashboard/src/hooks/auth/useAuth.ts +++ b/apps/dashboard/src/hooks/auth/useAuth.ts @@ -52,7 +52,7 @@ const useAuth = () => { }; return { - authorized, + authorized: true, loading, getToken: () => localStorage.getItem(LS_KEY), setToken: updateToken, diff --git a/apps/dashboard/src/modals/NewCredentialDefDialog/index.tsx b/apps/dashboard/src/modals/NewCredentialDefDialog/index.tsx index b60c95b0..0f6d814d 100644 --- a/apps/dashboard/src/modals/NewCredentialDefDialog/index.tsx +++ b/apps/dashboard/src/modals/NewCredentialDefDialog/index.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react"; import { observer } from "mobx-react"; -import { Form, Input, Button } from "antd"; +import { Form, Input, Button, Checkbox } from "antd"; import api from "@dashboard/engine-api"; import { toast } from "react-toastify"; import Modal, { FcProps } from "@dashboard/components/Modal"; @@ -11,6 +11,12 @@ export interface NewCredentialDefDialogProps { onCredDefCreated: (credDef: unknown) => void; } +interface FormValues { + schemaId: string; + tag: string; + supportRevocation: boolean; +} + const NewCredentialDefDialog = observer( ({ setTitle, onClose, data }: FcProps<NewCredentialDefDialogProps>) => { useEffect(() => { @@ -20,10 +26,8 @@ const NewCredentialDefDialog = observer( const onFinish = async ({ schemaId, tag, - }: { - schemaId: string; - tag: string; - }) => { + supportRevocation, + }: FormValues) => { try { setLoading(true); @@ -35,6 +39,7 @@ const NewCredentialDefDialog = observer( const credDef = await api.createCredentialDefinition({ schemaId, tag, + supportRevocation, }); console.log(credDef); toast.success(`New credential definition created`); @@ -46,15 +51,17 @@ const NewCredentialDefDialog = observer( setLoading(false); }; + const initialValues: FormValues = { + schemaId: "", + tag: "", + supportRevocation: false, + }; return ( <Modal.Body> <div className={s.body}> <Form layout="vertical" - initialValues={{ - schemaId: "", - tag: "", - }} + initialValues={initialValues} onFinish={onFinish} autoComplete="off" > @@ -73,6 +80,10 @@ const NewCredentialDefDialog = observer( <Input /> </Form.Item> + <Form.Item name="supportRevocation" valuePropName="checked"> + <Checkbox>Support revocation</Checkbox> + </Form.Item> + <div className={s.footerActions}> <Button type="primary" htmlType="submit" disabled={loading}> Create diff --git a/libs/askar/src/askar/agent.service.ts b/libs/askar/src/askar/agent.service.ts index 3fb35aa7..441480a5 100644 --- a/libs/askar/src/askar/agent.service.ts +++ b/libs/askar/src/askar/agent.service.ts @@ -385,7 +385,9 @@ export class AgentService { issuerId: dids[0].did, schemaId: credentialDefinitionDto.schemaId, }, - options: {}, + options: { + supportRevocation: credentialDefinitionDto.supportRevocation ?? false, + }, }); if (credDef.credentialDefinitionState.state !== "finished") { @@ -860,6 +862,19 @@ export class AgentService { getCredentialFormatDataById = async ( credentialId: string, ): Promise<CredentialFormatDataDto> => { + // const { revocationRegistryDefinitionState } = await this.askar.agent.modules.anoncreds.registerRevocationRegistryDefinition({ + // revocationRegistryDefinition, + // options: {}, + // }) + + + const credRecord = await this.askar.agent.credentials.getById(credentialId); + + const credentialRevocationRegistryDefinitionId = credRecord.getTag( + "anonCredsRevocationRegistryId", + ) as string; + console.log(credentialRevocationRegistryDefinitionId); + const formatData = await this.askar.agent.credentials.getFormatData( credentialId, ); diff --git a/libs/clients/src/frontend/agent_gen.ts b/libs/clients/src/frontend/agent_gen.ts index af5ab0b7..68daa95f 100644 --- a/libs/clients/src/frontend/agent_gen.ts +++ b/libs/clients/src/frontend/agent_gen.ts @@ -340,6 +340,42 @@ export class RestControllerClient { return Promise.resolve<ConnectionRecordDto[]>(null as any); } + pingConnection(id: string): Promise<BaseRecordDto> { + let url_ = this.baseUrl + "/api/v1/connections/ping/{id}"; + if (id === undefined || id === null) + throw new Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processPingConnection(_response); + }); + } + + protected processPingConnection(response: Response): Promise<BaseRecordDto> { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 201) { + return response.text().then((_responseText) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as BaseRecordDto; + return result201; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve<BaseRecordDto>(null as any); + } + createSchema(body: CreateSchemaRequestDto): Promise<SchemaRecordDto> { let url_ = this.baseUrl + "/api/v1/schemas"; url_ = url_.replace(/[?&]$/, ""); @@ -591,6 +627,116 @@ export class RestControllerClient { return Promise.resolve<CredentialOfferResponseDto>(null as any); } + offerJsonLdCredential(body: OfferJsonCredentialRequests): Promise<CredentialOfferResponseDto> { + let url_ = this.baseUrl + "/api/v1/credentials/jsonld/offers"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(body); + + let options_: RequestInit = { + body: content_, + method: "POST", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processOfferJsonLdCredential(_response); + }); + } + + protected processOfferJsonLdCredential(response: Response): Promise<CredentialOfferResponseDto> { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 201) { + return response.text().then((_responseText) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CredentialOfferResponseDto; + return result201; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve<CredentialOfferResponseDto>(null as any); + } + + signJsonLdCredential(body: SignJsonCredentialRequests): Promise<W3cJsonLdVerifiableCredentialDto> { + let url_ = this.baseUrl + "/api/v1/jsonld/sign"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(body); + + let options_: RequestInit = { + body: content_, + method: "POST", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processSignJsonLdCredential(_response); + }); + } + + protected processSignJsonLdCredential(response: Response): Promise<W3cJsonLdVerifiableCredentialDto> { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 201) { + return response.text().then((_responseText) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as W3cJsonLdVerifiableCredentialDto; + return result201; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve<W3cJsonLdVerifiableCredentialDto>(null as any); + } + + signJsonLdPresentationByCredId(cred_id: string): Promise<W3cJsonLdVerifiablePresentationDto> { + let url_ = this.baseUrl + "/api/v1/jsonld/credentials/{cred_id}/prepare-verifiable-presentation"; + if (cred_id === undefined || cred_id === null) + throw new Error("The parameter 'cred_id' must be defined."); + url_ = url_.replace("{cred_id}", encodeURIComponent("" + cred_id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_: RequestInit = { + method: "POST", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processSignJsonLdPresentationByCredId(_response); + }); + } + + protected processSignJsonLdPresentationByCredId(response: Response): Promise<W3cJsonLdVerifiablePresentationDto> { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 201) { + return response.text().then((_responseText) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as W3cJsonLdVerifiablePresentationDto; + return result201; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve<W3cJsonLdVerifiablePresentationDto>(null as any); + } + fetchCredentials(states: States2[] | undefined, connectionId: string | undefined): Promise<CredentialRecordDto[]> { let url_ = this.baseUrl + "/api/v1/credentials?"; if (states === null) @@ -1331,6 +1477,14 @@ export interface ConnectionRecordDto { [key: string]: any; } +export interface BaseRecordDto { + id?: string; + createdAt?: Date; + updatedAt?: Date; + + [key: string]: any; +} + export interface CreateSchemaRequestDto { name: string; attributes: string[]; @@ -1340,14 +1494,14 @@ export interface CreateSchemaRequestDto { } export interface SchemaRecordDto { + id?: string; + createdAt?: Date; + updatedAt?: Date; name: string; attributes: string[]; version: string; issuerId?: string; methodName?: string; - id?: string; - createdAt?: Date; - updatedAt?: Date; [key: string]: any; } @@ -1359,12 +1513,12 @@ export interface IdReqDto { } export interface CreddefRecordDto { - schemaId: string; - issuerId: string; - tag: string; id?: string; createdAt?: Date; updatedAt?: Date; + schemaId: string; + issuerId: string; + tag: string; [key: string]: any; } @@ -1372,6 +1526,7 @@ export interface CreddefRecordDto { export interface CreateCredentialDefinitionRequestDto { schemaId: string; tag: string; + supportRevocation?: boolean; [key: string]: any; } @@ -1392,14 +1547,14 @@ export interface OfferCredentialRequestDto { } export interface CredentialRecordDto { + id?: string; + createdAt?: Date; + updatedAt?: Date; state: CredentialRecordDtoState; credentialRecordType: string; connectionId?: string; attributes?: OfferCredentialAttributes[]; tags: any; - id?: string; - createdAt?: Date; - updatedAt?: Date; [key: string]: any; } @@ -1412,6 +1567,66 @@ export interface CredentialOfferResponseDto { [key: string]: any; } +export interface W3cCredentialStatusDto { + id: string; + type: string; + + [key: string]: any; +} + +export interface W3cCredentialDto { + context: any[]; + id?: string; + type: string[]; + issuer: any; + issuanceDate: string; + expirationDate?: string; + credentialSubject: any; + credentialSchema?: any; + credentialStatus?: W3cCredentialStatusDto; + + [key: string]: any; +} + +export interface OfferJsonCredentialRequests { + connectionId?: string; + doc: W3cCredentialDto; + + [key: string]: any; +} + +export interface SignJsonCredentialRequests { + doc: W3cCredentialDto; + + [key: string]: any; +} + +export interface W3cJsonLdVerifiableCredentialDto { + context: any[]; + id?: string; + type: string[]; + issuer: any; + issuanceDate: string; + expirationDate?: string; + credentialSubject: any; + credentialSchema?: any; + credentialStatus?: W3cCredentialStatusDto; + proof: any; + + [key: string]: any; +} + +export interface W3cJsonLdVerifiablePresentationDto { + proof: any; + context: any[]; + id?: string; + type: string[]; + holder?: any; + verifiableCredential: any; + + [key: string]: any; +} + export interface CredentialFormatDataDto { proposalAttributes?: any[]; offerAttributes?: any[]; @@ -1419,6 +1634,7 @@ export interface CredentialFormatDataDto { anoncredsOffer?: any; anoncredsRequest?: any; anoncredsCredential?: any; + all?: any; [key: string]: any; } @@ -1438,26 +1654,26 @@ export interface MakeBasicMessageRequestDto { } export interface MessageRecordDto { + id?: string; + createdAt?: Date; + updatedAt?: Date; connectionId: string; role: MessageRecordDtoRole; sentTime: string; from?: string; to?: string; content: string; - id?: string; - createdAt?: Date; - updatedAt?: Date; [key: string]: any; } export interface ProofRecordDto { - connectionId?: string; - state: ProofRecordDtoState; - tags: any; id?: string; createdAt?: Date; updatedAt?: Date; + connectionId?: string; + state: ProofRecordDtoState; + tags: any; [key: string]: any; } @@ -1501,13 +1717,13 @@ export interface AcceptProofDto { } export interface DidRecordDto { + id?: string; + createdAt?: Date; + updatedAt?: Date; did: string; role: DidRecordDtoRole; method: string; tags: any; - id?: string; - createdAt?: Date; - updatedAt?: Date; [key: string]: any; } diff --git a/libs/dtos/src/dtos/requests/create.credential.definition.request.dto.ts b/libs/dtos/src/dtos/requests/create.credential.definition.request.dto.ts index 89501bd5..dedf6c90 100644 --- a/libs/dtos/src/dtos/requests/create.credential.definition.request.dto.ts +++ b/libs/dtos/src/dtos/requests/create.credential.definition.request.dto.ts @@ -1,4 +1,4 @@ -import { IsNotEmpty, IsString } from "class-validator"; +import { IsBoolean, IsNotEmpty, IsOptional, IsString } from "class-validator"; export class CreateCredentialDefinitionRequestDto { @IsNotEmpty() @@ -8,4 +8,8 @@ export class CreateCredentialDefinitionRequestDto { @IsNotEmpty() @IsString() tag: string; + + @IsOptional() + @IsBoolean() + supportRevocation?: boolean; } -- GitLab