-
Notifications
You must be signed in to change notification settings - Fork 16
Qa - sign and verify methods #277
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
Changes from all commits
4ce11e2
c6b0a64
9fe7670
1a7b66a
075f101
1eb96e4
8cfa466
9b74e01
edeabf3
d422e8a
510e4d2
36ec9ec
b9603b0
9bd5464
96f5ff0
eb2ea01
8f40640
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,7 @@ | ||||||||||||||
| /* eslint-disable prettier/prettier */ | ||||||||||||||
| import type { RestAgentModules, RestMultiTenantAgentModules } from '../../cliAgent' | ||||||||||||||
| import type { Version } from '../examples' | ||||||||||||||
| import type { RecipientKeyOption, SchemaMetadata } from '../types' | ||||||||||||||
| import type { CustomW3cJsonLdSignCredentialOptions, RecipientKeyOption, SafeW3cJsonLdVerifyCredentialOptions, SchemaMetadata } from '../types' | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clean up imports: remove unused and fix type imports. Apply these diffs to fix the import issues:
-import type { CustomW3cJsonLdSignCredentialOptions, RecipientKeyOption, SafeW3cJsonLdVerifyCredentialOptions, SchemaMetadata } from '../types'
+import type { CustomW3cJsonLdSignCredentialOptions, RecipientKeyOption, SafeW3cJsonLdVerifyCredentialOptions, SchemaMetadata, SignDataOptions, VerifyDataOptions } from '../types'
W3cJsonLdSignCredentialOptions,
- W3cVerifiableCredential} from '@credo-ts/core'
+} from '@credo-ts/core' W3cJsonLdVerifiableCredential,
- W3cCredential,
ClaimFormat} from '@credo-ts/core'
- VerifyDataOptions , SignDataOptions } from '../types'
+} from '../types'Also applies to: 19-19, 51-52, 96-96 🤖 Prompt for AI Agents |
||||||||||||||
| import type { PolygonDidCreateOptions } from '@ayanworks/credo-polygon-w3c-module/build/dids' | ||||||||||||||
| import type { | ||||||||||||||
| AcceptProofRequestOptions, | ||||||||||||||
|
|
@@ -15,7 +15,8 @@ import type { | |||||||||||||
| ProofExchangeRecordProps, | ||||||||||||||
| ProofsProtocolVersionType, | ||||||||||||||
| Routing, | ||||||||||||||
| } from '@credo-ts/core' | ||||||||||||||
| W3cJsonLdSignCredentialOptions, | ||||||||||||||
| W3cVerifiableCredential} from '@credo-ts/core' | ||||||||||||||
| import type { IndyVdrDidCreateOptions, IndyVdrDidCreateResult } from '@credo-ts/indy-vdr' | ||||||||||||||
| import type { QuestionAnswerRecord, ValidResponse } from '@credo-ts/question-answer' | ||||||||||||||
| import type { TenantRecord } from '@credo-ts/tenants' | ||||||||||||||
|
|
@@ -27,6 +28,7 @@ import { | |||||||||||||
| parseIndyCredentialDefinitionId, | ||||||||||||||
| parseIndySchemaId, | ||||||||||||||
| } from '@credo-ts/anoncreds' | ||||||||||||||
| import { assertAskarWallet } from '@credo-ts/askar/build/utils/assertAskarWallet' | ||||||||||||||
| import { | ||||||||||||||
| AcceptCredentialOfferOptions, | ||||||||||||||
| Agent, | ||||||||||||||
|
|
@@ -45,7 +47,9 @@ import { | |||||||||||||
| injectable, | ||||||||||||||
| createPeerDidDocumentFromServices, | ||||||||||||||
| PeerDidNumAlgo, | ||||||||||||||
| } from '@credo-ts/core' | ||||||||||||||
| W3cJsonLdVerifiableCredential, | ||||||||||||||
| W3cCredential, | ||||||||||||||
| ClaimFormat} from '@credo-ts/core' | ||||||||||||||
| import { QuestionAnswerRole, QuestionAnswerState } from '@credo-ts/question-answer' | ||||||||||||||
| import axios from 'axios' | ||||||||||||||
| import * as fs from 'fs' | ||||||||||||||
|
|
@@ -89,7 +93,7 @@ import { | |||||||||||||
| CreateProofRequestOobOptions, | ||||||||||||||
| CreateOfferOobOptions, | ||||||||||||||
| CreateSchemaInput, | ||||||||||||||
| } from '../types' | ||||||||||||||
| VerifyDataOptions , SignDataOptions } from '../types' | ||||||||||||||
|
|
||||||||||||||
| import { Body, Controller, Delete, Get, Post, Query, Route, Tags, Path, Example, Security, Response } from 'tsoa' | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -1913,4 +1917,124 @@ export class MultiTenancyController extends Controller { | |||||||||||||
| throw ErrorHandlingService.handle(error) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Verify data using a key | ||||||||||||||
| * | ||||||||||||||
| * @param tenantId Tenant identifier | ||||||||||||||
| * @param request Verify options | ||||||||||||||
| * data - Data has to be in base64 format | ||||||||||||||
| * publicKeyBase58 - Public key in base58 format | ||||||||||||||
| * signature - Signature in base64 format | ||||||||||||||
| * @returns isValidSignature - true if signature is valid, false otherwise | ||||||||||||||
| */ | ||||||||||||||
| @Security('apiKey') | ||||||||||||||
| @Post('/verify/:tenantId') | ||||||||||||||
| public async verify(@Path('tenantId') tenantId: string, @Body() request: VerifyDataOptions) { | ||||||||||||||
| try { | ||||||||||||||
| const isValidSignature = await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { | ||||||||||||||
| assertAskarWallet(tenantAgent.context.wallet) | ||||||||||||||
| const isValidSignature = await tenantAgent.context.wallet.verify({ | ||||||||||||||
| data: TypedArrayEncoder.fromBase64(request.data), | ||||||||||||||
| key: Key.fromPublicKeyBase58(request.publicKeyBase58, request.keyType), | ||||||||||||||
| signature: TypedArrayEncoder.fromBase64(request.signature), | ||||||||||||||
| }) | ||||||||||||||
| return isValidSignature | ||||||||||||||
| }) | ||||||||||||||
| return isValidSignature | ||||||||||||||
| } catch (error) { | ||||||||||||||
| throw ErrorHandlingService.handle(error) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
Comment on lines
+1931
to
+1949
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add input validation for verify method parameters. The method implementation is solid, but consider adding validation for the input parameters to prevent potential issues with invalid data. Add validation before processing: public async verify(@Path('tenantId') tenantId: string, @Body() request: VerifyDataOptions) {
try {
+ // Validate input parameters
+ if (!request.data || !request.publicKeyBase58 || !request.signature || !request.keyType) {
+ throw new BadRequestError('Missing required parameters: data, publicKeyBase58, signature, and keyType are required')
+ }
+
const isValidSignature = await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => {🤖 Prompt for AI Agents |
||||||||||||||
| @Security('apiKey') | ||||||||||||||
| @Post('/credential/sign/:tenantId') | ||||||||||||||
| public async signCredential( | ||||||||||||||
| @Path('tenantId') tenantId: string, | ||||||||||||||
| @Query('storeCredential') storeCredential: boolean, | ||||||||||||||
| @Query('dataTypeToSign') dataTypeToSign: 'rawData' | 'jsonLd', | ||||||||||||||
| @Body() data: CustomW3cJsonLdSignCredentialOptions | SignDataOptions | any | ||||||||||||||
| ) { | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid using The Consider using a union type: - @Body() data: CustomW3cJsonLdSignCredentialOptions | SignDataOptions | any
+ @Body() data: CustomW3cJsonLdSignCredentialOptions | SignDataOptions📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| try { | ||||||||||||||
| return await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { | ||||||||||||||
| // JSON-LD VC Signing | ||||||||||||||
| if (dataTypeToSign === 'jsonLd') { | ||||||||||||||
| const credentialData = data as unknown as W3cJsonLdSignCredentialOptions | ||||||||||||||
| credentialData.format = ClaimFormat.LdpVc | ||||||||||||||
|
|
||||||||||||||
| const signedCredential = await tenantAgent.w3cCredentials.signCredential(credentialData) as W3cJsonLdVerifiableCredential | ||||||||||||||
|
|
||||||||||||||
| if (storeCredential) { | ||||||||||||||
| return await tenantAgent.w3cCredentials.storeCredential({ credential: signedCredential }) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return signedCredential.toJson() | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Raw Data Signing | ||||||||||||||
| const rawData = data as SignDataOptions | ||||||||||||||
|
|
||||||||||||||
| if (!rawData.data) throw new BadRequestError('Missing "data" for raw data signing.') | ||||||||||||||
|
|
||||||||||||||
| const hasDidOrMethod = rawData.did || rawData.method | ||||||||||||||
| const hasPublicKey = rawData.publicKeyBase58 && rawData.keyType | ||||||||||||||
|
|
||||||||||||||
| if (!hasDidOrMethod && !hasPublicKey) { | ||||||||||||||
| throw new BadRequestError('Either (did or method) OR (publicKeyBase58 and keyType) must be provided.') | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| let keyToUse: Key | ||||||||||||||
|
|
||||||||||||||
| if (hasDidOrMethod) { | ||||||||||||||
| const dids = await tenantAgent.dids.getCreatedDids({ | ||||||||||||||
| method: rawData.method || undefined, | ||||||||||||||
| did: rawData.did || undefined, | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| const verificationMethod = dids[0]?.didDocument?.verificationMethod?.[0]?.publicKeyBase58 | ||||||||||||||
| if (!verificationMethod) { | ||||||||||||||
| throw new BadRequestError('No publicKeyBase58 found for the given DID or method.') | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| keyToUse = Key.fromPublicKeyBase58(verificationMethod, rawData.keyType) | ||||||||||||||
| } else { | ||||||||||||||
| keyToUse = Key.fromPublicKeyBase58(rawData.publicKeyBase58, rawData.keyType) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (!keyToUse) { | ||||||||||||||
| throw new Error('Unable to construct signing key.') | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| const signature = await tenantAgent.context.wallet.sign({ | ||||||||||||||
| data: TypedArrayEncoder.fromBase64(rawData.data), | ||||||||||||||
| key: keyToUse, | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| return TypedArrayEncoder.toBase64(signature) | ||||||||||||||
| }) | ||||||||||||||
| } catch (error) { | ||||||||||||||
| throw ErrorHandlingService.handle(error) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| @Security('apiKey') | ||||||||||||||
| @Post('/credential/verify/:tenantId') | ||||||||||||||
| public async verifyCredential( | ||||||||||||||
| @Path('tenantId') tenantId: string, | ||||||||||||||
| @Body() credentialToVerify: SafeW3cJsonLdVerifyCredentialOptions | any | ||||||||||||||
| ) { | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Remove Apply this diff to improve type safety: - @Body() credentialToVerify: SafeW3cJsonLdVerifyCredentialOptions | any
+ @Body() credentialToVerify: SafeW3cJsonLdVerifyCredentialOptions
🤖 Prompt for AI Agents |
||||||||||||||
| let formattedCredential | ||||||||||||||
| try { | ||||||||||||||
| await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { | ||||||||||||||
| const {credential, ...credentialOptions}= credentialToVerify | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused destructured variable. The Apply this diff to fix the issue: - const {credential, ...credentialOptions}= credentialToVerify
+ const { ...credentialOptions } = credentialToVerify📝 Committable suggestion
Suggested change
🧰 Tools🪛 ESLint[error] 2029-2029: 'credential' is assigned a value but never used. (@typescript-eslint/no-unused-vars) 🤖 Prompt for AI Agents |
||||||||||||||
| const transformedCredential = JsonTransformer.fromJSON(credentialToVerify?.credential, W3cJsonLdVerifiableCredential) | ||||||||||||||
| const signedCred = await tenantAgent.w3cCredentials.verifyCredential({credential: transformedCredential, ...credentialOptions}) | ||||||||||||||
| formattedCredential = signedCred | ||||||||||||||
| }) | ||||||||||||||
| return formattedCredential | ||||||||||||||
| } catch (error) { | ||||||||||||||
| throw ErrorHandlingService.handle(error) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -25,8 +25,16 @@ import type { | |||||||||||||||
| Attachment, | ||||||||||||||||
| KeyType, | ||||||||||||||||
| JsonLdCredentialFormat, | ||||||||||||||||
| JsonObject, | ||||||||||||||||
| W3cJsonLdVerifyCredentialOptions, | ||||||||||||||||
| DataIntegrityProofOptions, | ||||||||||||||||
| W3cJsonLdSignCredentialOptions, | ||||||||||||||||
| W3cCredential, | ||||||||||||||||
| W3cCredentialSubject, | ||||||||||||||||
| } from '@credo-ts/core' | ||||||||||||||||
| import type { SingleOrArray } from '@credo-ts/core/build/utils' | ||||||||||||||||
| import type { DIDDocument } from 'did-resolver' | ||||||||||||||||
| import { LinkedDataProofOptions } from '@credo-ts/core/build/modules/vc/data-integrity/models/LinkedDataProof' | ||||||||||||||||
|
Comment on lines
+35
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix import formatting and use type imports for type-only imports. Apply this diff to fix the import issues: } from '@credo-ts/core'
import type { SingleOrArray } from '@credo-ts/core/build/utils'
+
import type { DIDDocument } from 'did-resolver'
-import { LinkedDataProofOptions } from '@credo-ts/core/build/modules/vc/data-integrity/models/LinkedDataProof'
+import type { LinkedDataProofOptions } from '@credo-ts/core/build/modules/vc/data-integrity/models/LinkedDataProof'📝 Committable suggestion
Suggested change
🧰 Tools🪛 ESLint[error] 36-36: There should be at least one empty line between import groups (import/order) [error] 37-37: All imports in the declaration are only used as types. Use (@typescript-eslint/consistent-type-imports) 🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| export type TenantConfig = Pick<InitConfig, 'label' | 'connectionImageUrl'> & { | ||||||||||||||||
| walletConfig: Pick<WalletConfig, 'id' | 'key' | 'keyDerivationMethod'> | ||||||||||||||||
|
|
@@ -37,10 +45,6 @@ export interface AgentInfo { | |||||||||||||||
| endpoints: string[] | ||||||||||||||||
| isInitialized: boolean | ||||||||||||||||
| publicDid: void | ||||||||||||||||
| // publicDid?: { | ||||||||||||||||
| // did: string | ||||||||||||||||
| // verkey: string | ||||||||||||||||
| // } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| export interface AgentMessageType { | ||||||||||||||||
|
|
@@ -388,3 +392,48 @@ export interface SchemaMetadata { | |||||||||||||||
| * @example "ea4e5e69-fc04-465a-90d2-9f8ff78aa71d" | ||||||||||||||||
| */ | ||||||||||||||||
| export type ThreadId = string | ||||||||||||||||
|
|
||||||||||||||||
| export type SignDataOptions = { | ||||||||||||||||
| data: string | ||||||||||||||||
| keyType: KeyType | ||||||||||||||||
| publicKeyBase58: string | ||||||||||||||||
| did?: string | ||||||||||||||||
| method?: string | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| export type VerifyDataOptions = { | ||||||||||||||||
| data: string | ||||||||||||||||
| keyType: KeyType | ||||||||||||||||
| publicKeyBase58: string | ||||||||||||||||
| signature: string | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| export interface jsonLdCredentialOptions { | ||||||||||||||||
| '@context': Array<string | JsonObject> | ||||||||||||||||
| type: Array<string> | ||||||||||||||||
| credentialSubject: SingleOrArray<JsonObject> | ||||||||||||||||
| proofType: string | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
|
Comment on lines
+412
to
+417
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use PascalCase for type names to maintain consistency. The type name Apply this diff to fix the naming: -export interface jsonLdCredentialOptions {
+export interface JsonLdCredentialOptions {
'@context': Array<string | JsonObject>
type: Array<string>
credentialSubject: SingleOrArray<JsonObject>
proofType: string
}Also update the reference in line 421: - credential: jsonLdCredentialOptions // TODO: add support for other credential format
+ credential: JsonLdCredentialOptions // TODO: add support for other credential format🤖 Prompt for AI Agents |
||||||||||||||||
| export interface credentialPayloadToSign { | ||||||||||||||||
| issuerDID: string | ||||||||||||||||
| method: string | ||||||||||||||||
| credential: jsonLdCredentialOptions // TODO: add support for other credential format | ||||||||||||||||
| } | ||||||||||||||||
| export interface SafeW3cJsonLdVerifyCredentialOptions extends W3cJsonLdVerifyCredentialOptions { | ||||||||||||||||
| // Ommited due to issues with TSOA | ||||||||||||||||
| proof: SingleOrArray<Omit<LinkedDataProofOptions, "cryptosuite"> | DataIntegrityProofOptions> | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| export type ExtensibleW3cCredentialSubject = W3cCredentialSubject & { | ||||||||||||||||
| [key: string]: unknown | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| export type ExtensibleW3cCredential = W3cCredential & { | ||||||||||||||||
| [key: string]: unknown | ||||||||||||||||
| credentialSubject: SingleOrArray<ExtensibleW3cCredentialSubject> | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| export type CustomW3cJsonLdSignCredentialOptions = Omit<W3cJsonLdSignCredentialOptions, 'format'> & { | ||||||||||||||||
| [key: string]: unknown | ||||||||||||||||
| } | ||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix formatting issues: remove trailing spaces and extra blank line.
The static analysis tools correctly identified formatting issues:
Apply this diff to fix the formatting:
📝 Committable suggestion
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 45-45: trailing spaces
(trailing-spaces)
[warning] 46-46: too many blank lines
(1 > 0) (empty-lines)
🤖 Prompt for AI Agents