diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index a4ff3a898..764580a9e 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -310,12 +310,16 @@ export class UserController { async shareUserCertificate( @Body() shareUserCredentials: CreateUserCertificateDto, @Res() res: Response - ): Promise { - const imageBuffer = await this.userService.shareUserCertificate(shareUserCredentials); + ): Promise { + const schemaIdParts = shareUserCredentials.schemaId.split(':'); + // eslint-disable-next-line prefer-destructuring + const title = schemaIdParts[2]; + const imageBuffer = await this.userService.shareUserCertificate(shareUserCredentials); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: 'Certificate url generated successfully', + label: title, data: imageBuffer.response }; return res.status(HttpStatus.CREATED).json(finalResponse); diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index dd4dd3bdc..6385ae49c 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -50,6 +50,7 @@ import validator from 'validator'; import { DISALLOWED_EMAIL_DOMAIN } from '@credebl/common/common.constant'; import { AwsService } from '@credebl/aws'; import puppeteer from 'puppeteer'; +import { WorldRecordTemplate } from '../templates/world-record-template'; @Injectable() export class UserService { @@ -578,6 +579,11 @@ export class UserService { const userArbiterTemplate = new ArbiterTemplate(); template = await userArbiterTemplate.getArbiterTemplate(attributeArray); break; + case UserCertificateId.WORLD_RECORD: + // eslint-disable-next-line no-case-declarations + const userWorldRecordTemplate = new WorldRecordTemplate(); + template = await userWorldRecordTemplate.getWorldRecordTemplate(attributeArray); + break; default: throw new NotFoundException('error in get attributes'); } @@ -588,7 +594,7 @@ export class UserService { const imageUrl = await this.awsService.uploadUserCertificate( imageBuffer, - 'jpeg', + 'png', verifyCode, 'certificates', 'base64' @@ -606,6 +612,7 @@ export class UserService { } return `${process.env.FRONT_END_URL}/certificates/${shareUserCertificate.credentialId}`; + } async saveCertificateUrl(imageUrl: string, credentialId: string): Promise { @@ -619,7 +626,7 @@ export class UserService { headless: true }); const page = await browser.newPage(); - await page.setViewport({ width: 1920, height: 1080 }); + await page.setViewport({ width: 800, height: 1020, deviceScaleFactor: 6}); await page.setContent(template); const screenshot = await page.screenshot(); await browser.close(); diff --git a/apps/user/templates/arbiter-template.ts b/apps/user/templates/arbiter-template.ts index b2be9e502..d2bfd4c73 100644 --- a/apps/user/templates/arbiter-template.ts +++ b/apps/user/templates/arbiter-template.ts @@ -1,27 +1,88 @@ -import { Attribute } from "../interfaces/user.interface"; +import { Attribute } from '../interfaces/user.interface'; export class ArbiterTemplate { - public getArbiterTemplate(attributes: Attribute[]): string { - const name = 0 < attributes.length ? attributes[0].name : ''; + findAttributeByName(attributes: Attribute[], name: string): Attribute { + return attributes.find((attr) => name in attr); + } - try { - return ` - - - - - Arbiter Template - - -
-
👩‍⚖️
-

Thank You, ${name}!

-

Your role as ${attributes} is essential in our contest.

-
- - `; - } catch (error) { + async getArbiterTemplate(attributes: Attribute[]): Promise { + try { + const [name, country, issuedBy] = await Promise.all(attributes).then((attributes) => { + const name = this.findAttributeByName(attributes, 'full_name')?.full_name ?? ''; + const country = this.findAttributeByName(attributes, 'country')?.country ?? ''; + const issuedBy = this.findAttributeByName(attributes, 'issued_by')?.issued_by ?? ''; + return [name, country, issuedBy]; + }); + return ` + + + + + + + + + + +
+ background +
+
+

CERTIFICATE

+

OF RECOGNITION

+
- } - } +

IS PROUDLY PRESENTED TO

+

${name}

+ + +

has served as an Arbiter at the + ${issuedBy} World Memory Championship 2023. +

+

+

+

Your dedication, professionalism, and impartiality as an Arbiter

+

have significantly contributed to the fair and smooth conduct

+

of the championship. Your commitment to upholding the

+

highest standards of integrity and sportsmanship has

+

played a crucial role in maintaining the credibility of the competition.

+ +

+
Date: 24, 25, 26 November 2023 | Place: Cidco Exhibition Centre, Navi Mumbai, ${country}
+
+
+ + + `; + } catch {} + } } diff --git a/apps/user/templates/participant-template.ts b/apps/user/templates/participant-template.ts index 0b372658c..b040fbb70 100644 --- a/apps/user/templates/participant-template.ts +++ b/apps/user/templates/participant-template.ts @@ -1,54 +1,84 @@ import { Attribute } from "../interfaces/user.interface"; export class ParticipantTemplate { - public getParticipantTemplate(attributes: Attribute[]): string { - try { - const nameAttribute = attributes.find(attr => 'full_name' in attr); - const countryAttribute = attributes.find(attr => 'country' in attr); - const positionAttribute = attributes.find(attr => 'position' in attr); - const issuedByAttribute = attributes.find(attr => 'issued_by' in attr); - const categoryAttribute = attributes.find(attr => 'category' in attr); - const dateAttribute = attributes.find(attr => 'issued_date' in attr); - - const name = nameAttribute ? nameAttribute['full_name'] : ''; - const country = countryAttribute ? countryAttribute['country'] : ''; - const position = positionAttribute ? positionAttribute['position'] : ''; - const issuedBy = issuedByAttribute ? issuedByAttribute['issued_by'] : ''; - const category = categoryAttribute ? categoryAttribute['category'] : ''; - const date = dateAttribute ? dateAttribute['issued_date'] : ''; - - return ` - - - - - Certificate of Achievement - - - -
-
🏆
-

Certificate of Achievement

- -

${name}

-

has demonstrated outstanding performance and successfully completed the requirements for

- -

Participant

-

Position: ${position}

-

Issued by: ${issuedBy}

- -
- -

Country: ${country}

-

Category: ${category}

+ findAttributeByName(attributes: Attribute[], name: string): Attribute { + return attributes.find((attr) => name in attr); + } -

Issued Date: ${date}

+ async getParticipantTemplate(attributes: Attribute[]): Promise { -

Congratulations!

-
+ try { + const [name, country, issuedBy] = await Promise.all(attributes).then((attributes) => { + const name = this.findAttributeByName(attributes, 'full_name')?.full_name ?? ''; + const country = this.findAttributeByName(attributes, 'country')?.country ?? ''; + const issuedBy = this.findAttributeByName(attributes, 'issued_by')?.issued_by ?? ''; + return [name, country, issuedBy]; + }); - - `; + return ` + + + + + + + + + + +
+ background +
+
+

CERTIFICATE

+

OF ACHIEVEMENT

+
+ +

IS PROUDLY PRESENTED TO

+

${name}

+ + for successfully participating in the + ${issuedBy} World Memory Championship 2023. +

+

+

We acknowledge your dedication, hard work, and

+

exceptional memory skills demonstrated during the competition.

+

+
Date: 24, 25, 26 November 2023 | Place: Cidco Exhibition Centre, Navi Mumbai, ${country}
+
+
+ + + `; } catch (error) {} } } diff --git a/apps/user/templates/winner-template.ts b/apps/user/templates/winner-template.ts index 49791fb1d..150fe5a05 100644 --- a/apps/user/templates/winner-template.ts +++ b/apps/user/templates/winner-template.ts @@ -7,14 +7,15 @@ export class WinnerTemplate { async getWinnerTemplate(attributes: Attribute[]): Promise { try { - const [name, issuedBy, date] = await Promise.all(attributes).then((attributes) => { + const [name, country, position, discipline, issuedBy, category] = await Promise.all(attributes).then((attributes) => { const name = this.findAttributeByName(attributes, 'full_name')?.full_name ?? ''; const country = this.findAttributeByName(attributes, 'country')?.country ?? ''; const position = this.findAttributeByName(attributes, 'position')?.position ?? ''; + const discipline = this.findAttributeByName(attributes, 'discipline')?.discipline ?? ''; const issuedBy = this.findAttributeByName(attributes, 'issued_by')?.issued_by ?? ''; const category = this.findAttributeByName(attributes, 'category')?.category ?? ''; const date = this.findAttributeByName(attributes, 'issued_date')?.issued_date ?? ''; - return [name, country, position, issuedBy, category, date]; + return [name, country, position, discipline, issuedBy, category, date]; }); return ` @@ -41,7 +42,7 @@ export class WinnerTemplate { } #textOverlay { - position: absolute; + position: absolute; top: 280px; left: 50%; transform: translateX(-50%); @@ -55,31 +56,34 @@ export class WinnerTemplate {
- background -
+ background +

CERTIFICATE

-

OF ACHIEVEMENT

+

OF EXCELLENCE

IS PROUDLY PRESENTED TO

-

${name}

+

${name}

- You are the winner of our contest - ${issuedBy} World Memory Championship 2023. +

has secured ${position} position for ${discipline}

+

in ${category} category at the

+

+ ${issuedBy} World Memory Championship 2023. +

We acknowledge your dedication, hard work, and

exceptional memory skills demonstrated during the competition.

-
${date} | Place: Cidco Exhibition Centre, Navi Mumbai, India
+
Date: 24, 25, 26 November 2023 | Place: Cidco Exhibition Centre, Navi Mumbai, ${country}
- `; + + `; } catch {} } } diff --git a/apps/user/templates/world-record-template.ts b/apps/user/templates/world-record-template.ts index d07a062ad..1436b2348 100644 --- a/apps/user/templates/world-record-template.ts +++ b/apps/user/templates/world-record-template.ts @@ -1,22 +1,86 @@ +import { Attribute } from '../interfaces/user.interface'; + export class WorldRecordTemplate { - public getWorldReccordTemplate(): string { - return ` - - - - - - World Record - - -
-
- 🏆 -
-

Congratulations!

-

You're the Winner of our contest.

-
- - `; + findAttributeByName(attributes: Attribute[], name: string): Attribute { + return attributes.find((attr) => name in attr); + } + + async getWorldRecordTemplate(attributes: Attribute[]): Promise { + try { + const [name, country, discipline, issuedBy] = await Promise.all(attributes).then((attributes) => { + const name = this.findAttributeByName(attributes, 'full_name')?.full_name ?? ''; + const country = this.findAttributeByName(attributes, 'country')?.country ?? ''; + const discipline = this.findAttributeByName(attributes, 'discipline')?.discipline ?? ''; + const issuedBy = this.findAttributeByName(attributes, 'issued_by')?.issued_by ?? ''; + return [name, country, discipline, issuedBy]; + }); + return ` + + + + + + + + + + +
+ background +
+
+

CERTIFICATE

+

OF WORLD RECORD

+
+ +

IS PROUDLY PRESENTED TO

+

${name}

+ + for successfully creating the world record in the + ${discipline} +

discipline during the + ${issuedBy} World Memory Championship 2023. +

+

+

+

We acknowledge your dedication, hard work, and

+

exceptional memory skills demonstrated during the competition.

+

+
Date: 24, 25, 26 November 2023 | Place: Cidco Exhibition Centre, Navi Mumbai, ${country}
+
+
+ + + `; + } catch {} } } diff --git a/libs/aws/src/aws.service.ts b/libs/aws/src/aws.service.ts index 8e1dcbd72..619e32ebb 100644 --- a/libs/aws/src/aws.service.ts +++ b/libs/aws/src/aws.service.ts @@ -15,30 +15,31 @@ export class AwsService { region: process.env.AWS_REGION }); this.s4 = new S3({ + accessKeyId: process.env.AWS_PUBLIC_ACCESS_KEY, secretAccessKey: process.env.AWS_PUBLIC_SECRET_KEY, region: process.env.AWS_PUBLIC_REGION }); } - + async uploadUserCertificate( fileBuffer: Buffer, ext: string, verifyCode: string, pathAWS: string = '', encoding = 'base64', - filename: string = 'cerficate' + filename: string = 'certificate' ): Promise { const timestamp = Date.now(); const putObjectAsync = promisify(this.s4.putObject).bind(this.s4); - try { await putObjectAsync({ + Bucket: process.env.AWS_PUBLIC_BUCKET_NAME, Key: `${pathAWS}/${encodeURIComponent(filename)}.${timestamp}.${ext}`, Body: fileBuffer, ContentEncoding: encoding, - ContentType: `image/jpeg` + ContentType: `image/png` }); return `https://${process.env.AWS_PUBLIC_BUCKET_NAME}.s3.${process.env.AWS_PUBLIC_REGION}.amazonaws.com/${pathAWS}/${encodeURIComponent(filename)}.${timestamp}.${ext}`; } catch (err) { diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 7a7211741..52639580f 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -1,6 +1,7 @@ export default interface IResponseType { statusCode: number; message?: string; + label?: string; data?: unknown; error?: unknown; }; diff --git a/libs/enum/src/enum.ts b/libs/enum/src/enum.ts index 37bd73879..729805fbf 100644 --- a/libs/enum/src/enum.ts +++ b/libs/enum/src/enum.ts @@ -42,5 +42,5 @@ export enum UserCertificateId { WINNER = 'Winner', PARTICIPANT = 'Participant', ARBITER = 'Arbiter', - WORLD_RECORD = 'WORLD_RECORD' + WORLD_RECORD = 'WorldRecord' }