Skip to content

Commit

Permalink
fix: delete credentials (#770)
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Richardson <[email protected]>
  • Loading branch information
NB-MikeRichardson authored May 19, 2022
1 parent 6c2dfdb commit f1e0412
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 47 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/modules/credentials/CredentialsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export class CredentialsModule implements CredentialsModule {
public async deleteById(credentialId: string, options?: DeleteCredentialOptions) {
const credentialRecord = await this.getById(credentialId)
const service = this.getService(credentialRecord.protocolVersion)
return service.deleteById(credentialId, options)
return service.delete(credentialRecord, options)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -803,24 +803,24 @@ describe('CredentialService', () => {

describe('deleteCredential', () => {
it('should call delete from repository', async () => {
const credential = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credential))
const credentialRecord = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credentialRecord))

const repositoryDeleteSpy = jest.spyOn(credentialRepository, 'delete')
await credentialService.deleteById(credential.id)
expect(repositoryDeleteSpy).toHaveBeenNthCalledWith(1, credential)
await credentialService.delete(credentialRecord)
expect(repositoryDeleteSpy).toHaveBeenNthCalledWith(1, credentialRecord)
})

it('deleteAssociatedCredential parameter should call deleteCredential in indyHolderService with credentialId', async () => {
const storeCredentialMock = indyHolderService.deleteCredential as jest.Mock<Promise<void>, [string]>
const deleteCredentialMock = indyHolderService.deleteCredential as jest.Mock<Promise<void>, [string]>

const credential = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credential))
const credentialRecord = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credentialRecord))

await credentialService.deleteById(credential.id, {
await credentialService.delete(credentialRecord, {
deleteAssociatedCredentials: true,
})
expect(storeCredentialMock).toHaveBeenNthCalledWith(1, credential.credentials[0].credentialRecordId)
expect(deleteCredentialMock).toHaveBeenNthCalledWith(1, credentialRecord.credentials[0].credentialRecordId)
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -793,24 +793,24 @@ describe('CredentialService', () => {

describe('deleteCredential', () => {
it('should call delete from repository', async () => {
const credential = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credential))
const credentialRecord = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credentialRecord))

const repositoryDeleteSpy = jest.spyOn(credentialRepository, 'delete')
await credentialService.deleteById(credential.id)
expect(repositoryDeleteSpy).toHaveBeenNthCalledWith(1, credential)
await credentialService.delete(credentialRecord)
expect(repositoryDeleteSpy).toHaveBeenNthCalledWith(1, credentialRecord)
})

it('deleteAssociatedCredential parameter should call deleteCredential in indyHolderService with credentialId', async () => {
const storeCredentialMock = indyHolderService.deleteCredential as jest.Mock<Promise<void>, [string]>

const credential = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credential))
const credentialRecord = mockCredentialRecord()
mockFunction(credentialRepository.getById).mockReturnValue(Promise.resolve(credentialRecord))

await credentialService.deleteById(credential.id, {
await credentialService.delete(credentialRecord, {
deleteAssociatedCredentials: true,
})
expect(storeCredentialMock).toHaveBeenNthCalledWith(1, credential.credentials[0].credentialRecordId)
expect(storeCredentialMock).toHaveBeenNthCalledWith(1, credentialRecord.credentials[0].credentialRecordId)
})
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { EventEmitter } from '../../../agent/EventEmitter'
import type {
DeleteCredentialOptions,
ServiceAcceptCredentialOptions,
ServiceAcceptProposalOptions,
ServiceOfferCredentialOptions,
Expand Down Expand Up @@ -66,10 +65,7 @@ export abstract class CredentialFormatService {
abstract shouldAutoRespondToRequest(options: HandlerAutoAcceptOptions): boolean
abstract shouldAutoRespondToCredential(options: HandlerAutoAcceptOptions): boolean

abstract deleteCredentialById(
credentialRecord: CredentialExchangeRecord,
options: DeleteCredentialOptions
): Promise<void>
abstract deleteCredentialById(credentialRecordId: string): Promise<void>

/**
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type {
} from '../../CredentialsModuleOptions'
import type { CredentialPreviewAttribute } from '../../models/CredentialPreviewAttributes'
import type {
DeleteCredentialOptions,
ServiceAcceptCredentialOptions,
ServiceAcceptOfferOptions as ServiceOfferOptions,
ServiceAcceptProposalOptions,
Expand Down Expand Up @@ -547,19 +546,8 @@ export class IndyCredentialFormatService extends CredentialFormatService {
}
return false
}
public async deleteCredentialById(
credentialRecord: CredentialExchangeRecord,
options: DeleteCredentialOptions
): Promise<void> {
const indyCredential = credentialRecord.credentials.filter((binding) => {
return binding.credentialRecordType == CredentialFormatType.Indy
})
if (indyCredential.length != 1) {
throw new AriesFrameworkError(`Could not find Indy record id for credential record ${credentialRecord.id}`)
}
if (options?.deleteAssociatedCredentials && indyCredential[0].credentialRecordId) {
await this.indyHolderService.deleteCredential(indyCredential[0].credentialRecordId)
}
public async deleteCredentialById(credentialRecordId: string): Promise<void> {
await this.indyHolderService.deleteCredential(credentialRecordId)
}

public async checkPreviewAttributesMatchSchemaAttributes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ describe('credentials', () => {

const deleteCredentialSpy = jest.spyOn(holderService, 'deleteCredential')
await aliceAgent.credentials.deleteById(holderCredential.id, { deleteAssociatedCredentials: true })
expect(deleteCredentialSpy).toHaveBeenCalledTimes(1)
expect(deleteCredentialSpy).toHaveBeenNthCalledWith(1, holderCredential.credentials[0].credentialRecordId)

return expect(aliceAgent.credentials.getById(holderCredential.id)).rejects.toThrowError(
`CredentialRecord: record with id ${holderCredential.id} not found.`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ export type DefaultCredentialTags = {
connectionId?: string
state: CredentialState
credentialIds: string[]
indyRevocationRegistryId?: string
indyCredentialRevocationId?: string
}

export interface CredentialRecordBinding {
credentialRecordType: CredentialFormatType
credentialRecordId: string
credentialId?: string
indyRevocationRegistryId?: string
indyCredentialRevocationId?: string
}

export class CredentialExchangeRecord extends BaseRecord<
Expand Down Expand Up @@ -97,16 +97,18 @@ export class CredentialExchangeRecord extends BaseRecord<

public getTags() {
const metadata = this.metadata.get(CredentialMetadataKeys.IndyCredential)
let Ids: string[] = []
let credentialIds: string[] = []

if (this.credentials) {
Ids = this.credentials.map((c) => c.credentialRecordId)
credentialIds = this.credentials.map((c) => c.credentialRecordId)
}

return {
...this._tags,
threadId: this.threadId,
connectionId: this.connectionId,
state: this.state,
credentialIds: Ids,
credentialIds: credentialIds,
indyRevocationRegistryId: metadata?.indyRevocationRegistryId,
indyCredentialRevocationId: metadata?.indyCredentialRevocationId,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,18 +247,17 @@ export abstract class CredentialService {
return this.credentialRepository.findById(connectionId)
}

public async deleteById(credentialId: string, options?: DeleteCredentialOptions): Promise<void> {
const credentialRecord = await this.getById(credentialId)

public async delete(credentialRecord: CredentialExchangeRecord, options?: DeleteCredentialOptions): Promise<void> {
await this.credentialRepository.delete(credentialRecord)

if (options?.deleteAssociatedCredentials) {
for (const credential of credentialRecord.credentials) {
const formatService: CredentialFormatService = this.getFormatService(credential.credentialRecordType)
await formatService.deleteCredentialById(credentialRecord, options)
await formatService.deleteCredentialById(credential.credentialRecordId)
}
}
}

/**
* Retrieve a credential record by connection id and thread id
*
Expand Down

0 comments on commit f1e0412

Please sign in to comment.