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

feat: add revocation store fragment #94

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion src/common/smartContract/documentStoreContractInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ export const getIssuersDocumentStore = (
): string[] => {
if (utils.isWrappedV2Document(document)) {
const data = getData(document);
return data.issuers.map((issuer) => issuer.documentStore || issuer.certificateStore || "");
return data.issuers.map(
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
(issuer) => issuer.documentStore || issuer.certificateStore || issuer.revocationStore || ""
);
}
return [getData(document).proof.value];
};
Expand Down
8 changes: 8 additions & 0 deletions src/types/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ export enum OpenAttestationEthereumDocumentStoreRevokedCode {
SKIPPED = 4,
CONTRACT_NOT_FOUND = 404,
}
export enum OpenAttestationRevocationCode {
UNEXPECTED_ERROR = 0,
DOCUMENT_REVOKED = 1,
CONTRACT_ADDRESS_INVALID = 2,
ETHERS_UNHANDLED_ERROR = 3,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc there are some ethers error correctly handled some not, this is in the case it's an unknown error from ethers

SKIPPED = 4,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is skipped in the revocation code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not ? I dont understand ?

CONTRACT_NOT_FOUND = 404,
}
export enum OpenAttestationEthereumTokenRegistryMintedCode {
UNEXPECTED_ERROR = 0,
DOCUMENT_NOT_MINTED = 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { openAttestationRevocationStore } from "./openAttestationRevocationStore";
import { verificationBuilder } from "../verificationBuilder";
import { documentRopstenValidWithDocumentStore } from "../../../test/fixtures/v2/documentRopstenValidWithDocumentStore";
import { documentRopstenRevocationStoreNotRevoked, documentRopstenRevocationStoreRevoked } from "./revocationStore";

const verify = verificationBuilder([openAttestationRevocationStore]);
describe("OpenAttestationRevocationStore", () => {
describe("v2", () => {
it("should return a skipped fragment when document store is used", async () => {
const fragment = await verify(documentRopstenValidWithDocumentStore, { network: "ropsten" });
expect(fragment).toStrictEqual([
{
name: "OpenAttestationRevocationStore",
type: "DOCUMENT_STATUS",
reason: {
code: 4,
codeString: "SKIPPED",
message: 'Document issuers doesn\'t have "revocationStore"',
},
yehjxraymond marked this conversation as resolved.
Show resolved Hide resolved
status: "SKIPPED",
},
]);
});
it("should return a valid fragment when revocation store is used and the document is not revoked", async () => {
const fragment = await verify(documentRopstenRevocationStoreNotRevoked, { network: "ropsten" });
expect(fragment).toStrictEqual([
{
name: "OpenAttestationRevocationStore",
type: "DOCUMENT_STATUS",
status: "VALID",
data: {
details: [
{
address: "0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",
revoked: false,
},
],
revokedOnAny: false,
},
},
]);
});
it("should return a invalid fragment when revocation store is used and the document is not revoked", async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it("should return a invalid fragment when revocation store is used and the document is not revoked", async () => {
it("should return a invalid fragment when revocation store is used and the document is revoked", async () => {

const fragment = await verify(documentRopstenRevocationStoreRevoked, { network: "ropsten" });
expect(fragment).toStrictEqual([
{
name: "OpenAttestationRevocationStore",
type: "DOCUMENT_STATUS",
reason: {
code: 1,
codeString: "DOCUMENT_REVOKED",
message:
"Certificate 0x856924fa2cf3374bf64697eb0dcf38d0251ff18aedae2bbc193398e8bb11fbd1 has been revoked under contract 0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Certificate 0x856924fa2cf3374bf64697eb0dcf38d0251ff18aedae2bbc193398e8bb11fbd1 has been revoked under contract 0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",
"Document 0x856924fa2cf3374bf64697eb0dcf38d0251ff18aedae2bbc193398e8bb11fbd1 has been revoked under contract 0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",

Can we change reference of certificate to document

},
status: "INVALID",
data: {
details: [
{
address: "0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",
reason: {
code: 1,
codeString: "DOCUMENT_REVOKED",
message:
"Certificate 0x856924fa2cf3374bf64697eb0dcf38d0251ff18aedae2bbc193398e8bb11fbd1 has been revoked under contract 0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",
},
revoked: true,
},
],
revokedOnAny: true,
},
},
]);
});
});
});
34 changes: 34 additions & 0 deletions src/verifiers/revocationStore/openAttestationRevocationStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { getData, utils, v2, WrappedDocument } from "@govtechsg/open-attestation";
import { VerificationFragmentType, Verifier } from "../../types/core";
import { OpenAttestationRevocationCode } from "../../types/error";
import { openAttestationEthereumDocumentStoreRevoked } from "../documentStoreRevoked/openAttestationEthereumDocumentStoreRevoked";

const name = "OpenAttestationRevocationStore";
const type: VerificationFragmentType = "DOCUMENT_STATUS";
export const openAttestationRevocationStore: Verifier<WrappedDocument<v2.OpenAttestationDocument>> = {
skip: () => {
return Promise.resolve({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wont this resolve be redundant? or can just add async to the function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could, just coding style :p (both are equivalent)

status: "SKIPPED",
type,
name,
reason: {
code: OpenAttestationRevocationCode.SKIPPED,
codeString: OpenAttestationRevocationCode[OpenAttestationRevocationCode.SKIPPED],
message: `Document issuers doesn't have "revocationStore"`,
},
});
},
test: (document) => {
if (utils.isWrappedV2Document(document)) {
const documentData = getData(document);
return documentData.issuers.every((issuer) => "revocationStore" in issuer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldnt this be any? Any failure should fail it?

Copy link
Contributor Author

@Nebulis Nebulis Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hum indeed used .some everywhere but for revoke 🤔

will change both 🙈

}
return false;
},
verify: async (document, options) => {
return {
...(await openAttestationEthereumDocumentStoreRevoked.verify(document, options)),
name,
};
},
};
51 changes: 51 additions & 0 deletions src/verifiers/revocationStore/revocationStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { SchemaId, v2, WrappedDocument } from "@govtechsg/open-attestation";

export const documentRopstenRevocationStoreNotRevoked: WrappedDocument<v2.OpenAttestationDocument> = {
version: SchemaId.v2,
data: {
issuers: [
{
name: "293d83b9-ffab-4888-b645-a294dce1a9f6:string:John",
identityProof: {
type: "846b133e-25af-4b3c-8464-088dcf0bd7f9:string:DNS-TXT",
location: "e5cf69ff-d95e-409f-a775-2a63694de710:string:tradetrust.io",
},
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
revocationStore: "79e3f87d-704e-486f-8b01-3c7a04d47896:string:0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",
},
],
foo: "6ccebe9c-7170-4d12-a2b4-34eef1d182d3:string:bar",
},
signature: {
type: "SHA3MerkleProof",
targetHash: "f5b228fc992405bdb96709f5a141678d8ca39576e211a3624807451039451af0",
proof: [],
merkleRoot: "f5b228fc992405bdb96709f5a141678d8ca39576e211a3624807451039451af0",
},
};

export const documentRopstenRevocationStoreRevoked: WrappedDocument<v2.OpenAttestationDocument> = {
version: SchemaId.v2,
data: {
issuers: [
{
name: "ca3d28a9-0bc5-4ec5-a020-3a42ba43146a:string:John",
identityProof: {
type: "0bf12863-5868-46f9-ab95-85a85d90c4c7:string:DNS-TXT",
location: "9fb9839a-c263-4976-b3dd-898495187ade:string:tradetrust.io",
},
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
revocationStore: "3d3766c0-b9bd-4a8f-8612-62e41887374f:string:0x8Fc57204c35fb9317D91285eF52D6b892EC08cD3",
},
],
foo: "95b7ea29-e768-4462-be9a-8464de48f55d:string:bar",
},
signature: {
type: "SHA3MerkleProof",
targetHash: "856924fa2cf3374bf64697eb0dcf38d0251ff18aedae2bbc193398e8bb11fbd1",
proof: [],
merkleRoot: "856924fa2cf3374bf64697eb0dcf38d0251ff18aedae2bbc193398e8bb11fbd1",
},
};