Skip to content
Merged
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
3 changes: 3 additions & 0 deletions src/commands/document-store/grant-role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
extractOADocumentInfo,
NetworkAndWalletSignerOption,
GasPriceScale,
verifyDocumentSignature,
} from '../../utils';
import { connectToDocumentStore, waitForTransaction } from '../helpers';
import { documentStoreGrantRole } from '@trustvc/trustvc';
Expand Down Expand Up @@ -48,6 +49,8 @@ export const promptForInputs = async (): Promise<DocumentStoreGrantRoleCommand>
// Extract document information using utility function
const document = await promptAndReadDocument();

await verifyDocumentSignature(document);

const { documentStoreAddress, network } = await extractOADocumentInfo(document);

// Role selection
Expand Down
3 changes: 3 additions & 0 deletions src/commands/document-store/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
promptAndReadDocument,
performDryRunWithConfirmation,
extractOADocumentInfo,
verifyDocumentSignature,
} from '../../utils';
import { connectToDocumentStore, waitForTransaction } from '../helpers';
import { documentStoreIssue } from '@trustvc/trustvc';
Expand All @@ -37,6 +38,8 @@ export const promptForInputs = async (): Promise<DocumentStoreIssueCommand> => {
// Extract document information using utility function
const document = await promptAndReadDocument();

await verifyDocumentSignature(document);

const { documentStoreAddress, tokenId, network } = await extractOADocumentInfo(document);

// Wallet selection
Expand Down
3 changes: 3 additions & 0 deletions src/commands/document-store/revoke-role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
extractOADocumentInfo,
NetworkAndWalletSignerOption,
GasPriceScale,
verifyDocumentSignature,
} from '../../utils';
import { connectToDocumentStore, waitForTransaction } from '../helpers';
import { documentStoreRevokeRole } from '@trustvc/trustvc';
Expand Down Expand Up @@ -48,6 +49,8 @@ export const promptForInputs = async (): Promise<DocumentStoreRevokeRoleCommand>
// Extract document information using utility function
const document = await promptAndReadDocument();

await verifyDocumentSignature(document);

const { documentStoreAddress, network } = await extractOADocumentInfo(document);

// Role selection
Expand Down
3 changes: 3 additions & 0 deletions src/commands/document-store/revoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
promptAndReadDocument,
performDryRunWithConfirmation,
extractOADocumentInfo,
verifyDocumentSignature,
} from '../../utils';
import { connectToDocumentStore, waitForTransaction } from '../helpers';
import { documentStoreRevoke } from '@trustvc/trustvc';
Expand All @@ -37,6 +38,8 @@ export const promptForInputs = async (): Promise<DocumentStoreIssueCommand> => {
// Extract document information using utility function
const document = await promptAndReadDocument();

await verifyDocumentSignature(document);

const { documentStoreAddress, tokenId, network } = await extractOADocumentInfo(document);

// Wallet selection
Expand Down
3 changes: 3 additions & 0 deletions src/commands/document-store/transfer-ownership.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
extractOADocumentInfo,
NetworkAndWalletSignerOption,
GasPriceScale,
verifyDocumentSignature,
} from '../../utils';
import { waitForTransaction } from '../helpers';
import { documentStoreTransferOwnership } from '@trustvc/trustvc';
Expand Down Expand Up @@ -45,6 +46,8 @@ export const promptForInputs = async (): Promise<DocumentStoreTransferOwnershipC
// Extract document information using utility function
const document = await promptAndReadDocument();

await verifyDocumentSignature(document);

const { documentStoreAddress, network } = await extractOADocumentInfo(document);

// New owner address to transfer ownership to
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/accept-return-to-issuer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
promptAndReadDocument,
promptRemark,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import { connectToTokenRegistry, validateAndEncryptRemark } from '../helpers';

Expand All @@ -41,6 +42,9 @@ export const promptForInputs = async (): Promise<TitleEscrowReturnDocumentComman
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/endorse-transfer-owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
promptAndReadDocument,
promptAddress,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import {
connectToTitleEscrow,
Expand Down Expand Up @@ -47,6 +48,9 @@ export const promptForInputs = async (): Promise<TitleEscrowNominateBeneficiaryC
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/nominate-transfer-owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
promptRemark,
promptAddress,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import {
connectToTitleEscrow,
Expand Down Expand Up @@ -46,6 +47,9 @@ export const promptForInputs = async (): Promise<TitleEscrowNominateBeneficiaryC
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/reject-return-to-issuer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
promptAndReadDocument,
promptRemark,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import { connectToTokenRegistry, validateAndEncryptRemark } from '../helpers';

Expand All @@ -41,6 +42,9 @@ export const promptForInputs = async (): Promise<TitleEscrowReturnDocumentComman
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/reject-transfer-holder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
promptAndReadDocument,
promptRemark,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import { connectToTitleEscrow, validatePreviousHolder, validateAndEncryptRemark } from '../helpers';

Expand All @@ -41,6 +42,9 @@ export const promptForInputs = async (): Promise<TitleEscrowRejectTransferComman
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/reject-transfer-owner-holder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
promptAndReadDocument,
promptRemark,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import {
connectToTitleEscrow,
Expand Down Expand Up @@ -46,6 +47,9 @@ export const promptForInputs = async (): Promise<TitleEscrowRejectTransferComman
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/reject-transfer-owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
promptAndReadDocument,
promptRemark,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import {
connectToTitleEscrow,
Expand Down Expand Up @@ -48,6 +49,9 @@ export const promptForInputs = async (): Promise<TitleEscrowRejectTransferComman
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/return-to-issuer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
promptAndReadDocument,
promptRemark,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import { connectToTitleEscrow, validateAndEncryptRemark } from '../helpers';

Expand All @@ -41,6 +42,9 @@ export const promptForInputs = async (): Promise<TitleEscrowReturnDocumentComman
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/transfer-holder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
promptAndReadDocument,
promptAddress,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import { connectToTitleEscrow, validateAndEncryptRemark } from '../helpers';

Expand All @@ -42,6 +43,9 @@ export const promptForInputs = async (): Promise<TitleEscrowTransferHolderComman
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
4 changes: 4 additions & 0 deletions src/commands/title-escrow/transfer-owner-holder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
promptAndReadDocument,
promptAddress,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import {
connectToTitleEscrow,
Expand Down Expand Up @@ -47,6 +48,9 @@ export const promptForInputs = async (): Promise<TitleEscrowEndorseTransferOfOwn
// Extract document information using utility function
const document = await promptAndReadDocument();

// Verify document signature before proceeding
await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
3 changes: 3 additions & 0 deletions src/commands/token-registry/mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
promptRemark,
promptAddress,
performDryRunWithConfirmation,
verifyDocumentSignature,
} from '../../utils';
import { connectToTokenRegistry, validateAndEncryptRemark } from '../helpers';
import { TransactionReceipt } from 'ethers';
Expand All @@ -40,6 +41,8 @@ export const promptForInputs = async (): Promise<TokenRegistryMintCommand> => {
// Extract document information using utility function
const document = await promptAndReadDocument();

await verifyDocumentSignature(document);

// Extract document information using utility function
const { tokenRegistry, tokenId, network, documentId, registryVersion } =
await extractDocumentInfo(document);
Expand Down
59 changes: 59 additions & 0 deletions src/utils/document-verification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import signale from 'signale';
import {
isWrappedV2Document,
isWrappedV3Document,
SignedVerifiableCredential,
verifyOASignature,
verifyW3CSignature,
deriveW3C,
vc,
} from '@trustvc/trustvc';

/**
* Verifies the signature of a document (W3C or OpenAttestation).
* Throws an error if the document signature is invalid.
*
* @param document - The document to verify
* @throws Error if document signature verification fails
*/
export const verifyDocumentSignature = async (
document: SignedVerifiableCredential,
): Promise<void> => {
signale.info('Verifying document signature...');

const isOpenAttestation = isWrappedV2Document(document) || isWrappedV3Document(document);
let verificationResult: boolean;

try {
if (isOpenAttestation) {
verificationResult = await verifyOASignature(document);
} else if (vc.isSignedDocument(document) || vc.isRawDocument(document)) {
const verificationValue = await verifyW3CSignature(document);

// Handle derivation if needed
if (
!verificationValue.verified &&
verificationValue.error?.includes('Use deriveCredential() first')
) {
const derivedCredential = await deriveW3C(document, []);
verificationResult =
derivedCredential && derivedCredential.derived
? (await verifyW3CSignature(derivedCredential.derived)).verified
: false;
} else {
verificationResult = verificationValue.verified;
}
} else throw new Error('Document cannot be verified');

if (!verificationResult) {
throw new Error('Document signature verification failed: Document is tampered');
}

signale.success('Document signature verified successfully');
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
}
throw new Error('Document verification failed: Unknown error');
}
};
3 changes: 3 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ export * from './wallet';

// Dry Run
export * from './dryRun';

// Document Verification
export * from './document-verification';
6 changes: 6 additions & 0 deletions tests/commands/document-store/grant-role.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ vi.mock('@trustvc/trustvc', () => ({
v4SupportInterfaceIds: {},
v5SupportInterfaceIds: {},
encrypt: vi.fn(),
isWrappedV2Document: vi.fn(),
isWrappedV3Document: vi.fn(),
verifyOASignature: vi.fn(),
verifyW3CSignature: vi.fn(),
deriveW3C: vi.fn(),
DocumentStore__factory: {
connect: vi.fn(),
},
Expand Down Expand Up @@ -88,6 +93,7 @@ vi.mock('../../../src/utils', async (importOriginal) => {
promptAddress: vi.fn(),
promptWalletSelection: vi.fn(),
performDryRunWithConfirmation: vi.fn(async () => true),
verifyDocumentSignature: vi.fn(),
};
});

Expand Down
6 changes: 6 additions & 0 deletions tests/commands/document-store/issue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ vi.mock('@trustvc/trustvc', () => ({
getTokenRegistryAddress: vi.fn(),
getTokenId: vi.fn(),
getChainId: vi.fn(),
isWrappedV2Document: vi.fn(),
isWrappedV3Document: vi.fn(),
verifyOASignature: vi.fn(),
verifyW3CSignature: vi.fn(),
deriveW3C: vi.fn(),
DocumentStore__factory: {
connect: vi.fn(),
},
Expand Down Expand Up @@ -86,6 +91,7 @@ vi.mock('../../../src/utils', async (importOriginal) => {
promptWalletSelection: vi.fn(),
promptRemark: vi.fn(),
performDryRunWithConfirmation: vi.fn(async () => true),
verifyDocumentSignature: vi.fn(),
};
});

Expand Down
Loading