Skip to content

Commit

Permalink
Added the API for get oob verification qr code
Browse files Browse the repository at this point in the history
Signed-off-by: KulkarniShashank <shashank.kulkarni@ayanworks.com>
  • Loading branch information
KulkarniShashank committed Oct 25, 2023
1 parent fc6c998 commit d296cac
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 25 deletions.
13 changes: 13 additions & 0 deletions apps/api-gateway/src/issuance/issuance.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ export class IssuanceController {
) { }
private readonly logger = new Logger('IssuanceController');

@Get('/issuance/oob/qr/:base64Image')
@ApiOperation({ summary: 'Out-Of-Band issuance QR', description: 'Out-Of-Band issuance QR' })
@ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto })
@ApiExcludeEndpoint()
async getOgPofile(@Param('base64Image') base64Image: string, @Res() res: Response): Promise<Response> {

const base64Data = base64Image.replace(/^data:image\/\w+;base64,/, '');

const imageBuffer = Buffer.from(base64Data, 'base64');
res.setHeader('Content-Type', 'image/png');
return res.send(imageBuffer);
}

/**
* Description: Get all issued credentials
* @param user
Expand Down
6 changes: 3 additions & 3 deletions apps/api-gateway/src/verification/dto/request-proof.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ export class OutOfBandRequestProof {
@IsNotEmpty({ message: 'please provide valid attributes' })
attributes: ProofRequestAttribute[];

@ApiProperty({ example: ['exmaple@example.com'] })
@IsArray({ message: 'emailId should be array' })
emailId: string[];
@ApiProperty()
@IsString({ each: true, message: 'Each emailId in the array should be a string' })
emailId: string | string[];

@ApiProperty()
@IsOptional()
Expand Down
20 changes: 19 additions & 1 deletion apps/api-gateway/src/verification/verification.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,34 @@ import { WebhookPresentationProof } from './dto/webhook-proof.dto';
import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler';

@UseFilters(CustomExceptionFilter)
@ApiBearerAuth()
@Controller()
@ApiTags('verifications')
export class VerificationController {
constructor(private readonly verificationService: VerificationService) { }

private readonly logger = new Logger('VerificationController');

@Get('/verification/oob/qr/:base64Image')
@ApiOperation({ summary: 'Out-Of-Band issuance QR', description: 'Out-Of-Band issuance QR' })
@ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto })
@ApiExcludeEndpoint()
async getOgPofile(@Param('base64Image') base64Image: string, @Res() res: Response): Promise<Response> {

const base64Data = base64Image.replace(/^data:image\/\w+;base64,/, '');

const imageBuffer = Buffer.from(base64Data, 'base64');
res.setHeader('Content-Type', 'image/png');
return res.send(imageBuffer);
}

@Get('/orgs/:orgId/proofs/:proofId/form')
@ApiOperation({
summary: `Get a proof form data`,
description: `Get a proof form data`
})
@Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER)
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
@ApiBearerAuth()
@ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto })
@ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto })
@ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto })
Expand Down Expand Up @@ -81,6 +94,7 @@ export class VerificationController {
@ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto })
@Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER)
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
@ApiBearerAuth()
async getProofPresentationById(
@Res() res: Response,
@GetUser() user: IUserRequest,
Expand Down Expand Up @@ -113,6 +127,7 @@ export class VerificationController {
@ApiQuery(
{ name: 'threadId', required: false }
)
@ApiBearerAuth()
@Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER)
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
async getProofPresentations(
Expand Down Expand Up @@ -145,6 +160,7 @@ export class VerificationController {
@ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto })
@ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto })
@ApiBody({ type: RequestProof })
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
@Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.VERIFIER)
async sendPresentationRequest(
Expand Down Expand Up @@ -184,6 +200,7 @@ export class VerificationController {
@ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto })
@ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto })
@Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.VERIFIER)
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
async verifyPresentation(
@Res() res: Response,
Expand Down Expand Up @@ -216,6 +233,7 @@ export class VerificationController {
@ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto })
@ApiBody({ type: OutOfBandRequestProof })
@Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.VERIFIER)
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
async sendOutOfBandPresentationRequest(
@Res() res: Response,
Expand Down
2 changes: 1 addition & 1 deletion apps/issuance/templates/out-of-band-issuance.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class OutOfBandIssuance {
</ul>
Should you require any assistance or have questions, feel free to contact our dedicated support team.
</p>
<img src="${issuanceQrCode}" alt="QR Code" width="200" height="200">
<img src="${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}/issuance/oob/qr/${issuanceQrCode}" alt="QR Code" width="200" height="200">
<hr style="border-top:1px solid #e8e8e8" />
<footer style="padding-top: 20px;">
<div>
Expand Down
42 changes: 23 additions & 19 deletions apps/verification/src/verification.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import { map } from 'rxjs/operators';
import { IGetAllProofPresentations, IGetProofPresentationById, IProofRequestPayload, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, IWebhookProofPresentation, ProofFormDataPayload } from './interfaces/verification.interface';
import { VerificationRepository } from './repositories/verification.repository';
import { CommonConstants } from '@credebl/common/common.constant';
import { presentations } from '@prisma/client';
import { org_agents, organisation, presentations } from '@prisma/client';
import { OrgAgentType } from '@credebl/enum/enum';
import { ResponseMessages } from '@credebl/common/response-messages';
import * as QRCode from 'qrcode';
import { OutOfBandVerification } from '../templates/out-of-band-verification.template';
import { EmailDto } from '@credebl/common/dtos/email.dto';
import { sendEmail } from '@credebl/common/send-grid-helper-file';
import * as uuid from 'uuid';

@Injectable()
export class VerificationService {
Expand Down Expand Up @@ -338,7 +337,8 @@ export class VerificationService {
const verificationMethodLabel = 'create-request-out-of-band';
const url = await this.getAgentUrl(verificationMethodLabel, getAgentDetails?.orgAgentTypeId, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId);

const payload = {
const payload: IProofRequestPayload
= {
apiKey: '',
url,
proofRequestPayload: {
Expand Down Expand Up @@ -366,20 +366,25 @@ export class VerificationService {
}
}

async sendEmailInBatches(payload, emailIds, getAgentDetails, organizationDetails, batchSize): Promise<void> {
async sendEmailInBatches(payload: IProofRequestPayload, emailIds: string[] | string, getAgentDetails: org_agents, organizationDetails: organisation, batchSize: number): Promise<void> {
const accumulatedErrors = [];

for (let i = 0; i < emailIds.length; i += batchSize) {
const batch = emailIds.slice(i, i + batchSize);
const emailPromises = batch.map(async email => {
try {
await this.sendOutOfBandProofRequest(payload, email, getAgentDetails, organizationDetails);
} catch (error) {
accumulatedErrors.push(error);
}
});
if (Array.isArray(emailIds)) {

await Promise.all(emailPromises);
for (let i = 0; i < emailIds.length; i += batchSize) {
const batch = emailIds.slice(i, i + batchSize);
const emailPromises = batch.map(async email => {
try {
await this.sendOutOfBandProofRequest(payload, email, getAgentDetails, organizationDetails);
} catch (error) {
accumulatedErrors.push(error);
}
});

await Promise.all(emailPromises);
}
} else {
await this.sendOutOfBandProofRequest(payload, emailIds, getAgentDetails, organizationDetails);
}

if (0 < accumulatedErrors.length) {
Expand All @@ -389,7 +394,7 @@ export class VerificationService {
}


async sendOutOfBandProofRequest(payload, email, getAgentDetails, organizationDetails): Promise<boolean> {
async sendOutOfBandProofRequest(payload: IProofRequestPayload, email: string, getAgentDetails: org_agents, organizationDetails: organisation): Promise<boolean> {
const getProofPresentation = await this._sendOutOfBandProofRequest(payload);

if (!getProofPresentation) {
Expand All @@ -406,9 +411,8 @@ export class VerificationService {
? `${getAgentDetails?.agentEndPoint}/multi-tenancy/url/${getAgentDetails?.tenantId}/${invitationId}`
: `${getAgentDetails?.agentEndPoint}/url/${invitationId}`;

const uniqueCID = uuid.v4();
const qrCodeOptions: QRCode.QRCodeToDataURLOptions = { type: 'image/png' };
const outOfBandIssuanceQrCode = await QRCode.toDataURL(shortenedUrl, qrCodeOptions);
const outOfBandVerificationQrCode = await QRCode.toDataURL(shortenedUrl, qrCodeOptions);

const platformConfigData = await this.verificationRepository.getPlatformConfigDetails();

Expand All @@ -419,11 +423,11 @@ export class VerificationService {
this.emailData.emailFrom = platformConfigData.emailFrom;
this.emailData.emailTo = email;
this.emailData.emailSubject = `${process.env.PLATFORM_NAME} Platform: Verification of Your Credentials Required`;
this.emailData.emailHtml = await this.outOfBandVerification.outOfBandVerification(email, uniqueCID, organizationDetails.name);
this.emailData.emailHtml = await this.outOfBandVerification.outOfBandVerification(email, organizationDetails.name, outOfBandVerificationQrCode);
this.emailData.emailAttachments = [
{
filename: 'qrcode.png',
content: outOfBandIssuanceQrCode.split(';base64,')[1],
content: outOfBandVerificationQrCode.split(';base64,')[1],
contentType: 'image/png',
disposition: 'attachment'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export class OutOfBandVerification {

public outOfBandVerification(email: string, uniqueCID: string, orgName: string): string {
public outOfBandVerification(email: string, orgName: string, verificationQrCode: string): string {
try {
return `<!DOCTYPE html>
<html lang="en">
Expand Down Expand Up @@ -37,6 +37,7 @@ export class OutOfBandVerification {
</ul>
Should you encounter any difficulties or have inquiries, our dedicated support team is available to assist you. Feel free to reach out.
</p>
<img src="${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}/verification/oob/qr/${verificationQrCode}" alt="QR Code" width="200" height="200">
<hr style="border-top:1px solid #e8e8e8" />
<footer style="padding-top: 20px;">
<div>
Expand Down

0 comments on commit d296cac

Please sign in to comment.