From bd5255218469474b3b9de7ae6d038a7beb6a1f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Urban=20Kova=C4=8D?= Date: Fri, 16 Feb 2024 11:42:43 +0100 Subject: [PATCH 1/4] MENT (new copy) --- frontend/components/parts/Table/Users.vue | 2 +- frontend/components/parts/form/Upload.vue | 2 +- frontend/pages/claim.vue | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/components/parts/Table/Users.vue b/frontend/components/parts/Table/Users.vue index d70ce7d..3844eed 100644 --- a/frontend/components/parts/Table/Users.vue +++ b/frontend/components/parts/Table/Users.vue @@ -109,7 +109,7 @@ const columns = createColumns(); function addItem(user: UserInterface) { if (!validateEmail(newUser.value.email)) { - message.warning('Please enter a valid email address'); + message.warning('Please enter a valid email address.'); return; } diff --git a/frontend/components/parts/form/Upload.vue b/frontend/components/parts/form/Upload.vue index 5fe47ba..a60c120 100644 --- a/frontend/components/parts/form/Upload.vue +++ b/frontend/components/parts/form/Upload.vue @@ -63,7 +63,7 @@ const hasRequiredColumns = computed(() => function uploadFileRequest({ file, onError, onFinish }: UploadCustomRequestOptions) { if (file.type !== 'text/csv' && file.type !== 'application/vnd.ms-excel') { console.warn(file.type); - message.warning('File must be of type CSV'); + message.warning('File must be of CSV type.'); /** Mark file as failed */ onError(); diff --git a/frontend/pages/claim.vue b/frontend/pages/claim.vue index 0b82aae..b74244b 100644 --- a/frontend/pages/claim.vue +++ b/frontend/pages/claim.vue @@ -40,7 +40,7 @@ async function claimAirdrop() { await connect({ connector: connectors.value[0] }); if (!walletClient.value) { - message.error('Could not connect with wallet'); + message.error('Could not connect with your wallet.'); loading.value = false; return; } @@ -57,11 +57,11 @@ async function claimAirdrop() { txWait.hash.value = res.data.transactionHash as Address; console.debug('Transaction', txWait.hash.value); - message.info('Minting of your NFT has begun.'); + message.info('Minting of your MENT token has begun.'); const receipt = await txWait.wait(); console.debug(receipt); - message.success('You successfully claimed NFT'); + message.success("You've successfully claimed your MENT token."); if (receipt.data?.to && receipt.data?.logs[0].topics[3]) { const nftId = Number(receipt.data?.logs[0].topics[3]); From 931626c13a18e13b799a99df4a466dc7c6e37e10 Mon Sep 17 00:00:00 2001 From: Tine Mlakar Date: Fri, 16 Feb 2024 12:28:31 +0100 Subject: [PATCH 2/4] cron fix --- backend/src/cron.ts | 62 +++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/backend/src/cron.ts b/backend/src/cron.ts index 1dc8077..c19d99f 100644 --- a/backend/src/cron.ts +++ b/backend/src/cron.ts @@ -1,21 +1,21 @@ -import { CronJob } from "cron"; -import { AirdropStatus } from "./models/user"; -import { dateToSqlString } from "./lib/sql-utils"; -import { SqlModelStatus } from "./models/base-sql-model"; -import { MysqlConnectionManager } from "./lib/mysql-connection-manager"; -import { SmtpSendTemplate } from "./lib/node-mailer"; -import { env } from "./config/env"; -import { generateEmailAirdropToken } from "./lib/jwt"; -import { LogType, writeLog } from "./lib/logger"; +import { CronJob } from 'cron'; +import { AirdropStatus } from './models/user'; +import { dateToSqlString } from './lib/sql-utils'; +import { SqlModelStatus } from './models/base-sql-model'; +import { MysqlConnectionManager } from './lib/mysql-connection-manager'; +import { SmtpSendTemplate } from './lib/node-mailer'; +import { env } from './config/env'; +import { generateEmailAirdropToken } from './lib/jwt'; +import { LogType, writeLog } from './lib/logger'; export class Cron { private cronJobs: CronJob[] = []; constructor() { - this.cronJobs.push(new CronJob("* * * * *", this.sendEmail, null, false)); + this.cronJobs.push(new CronJob('* * * * *', this.sendEmail, null, false)); if (env.MAX_SUPPLY > 0) { this.cronJobs.push( - new CronJob("* * * * *", this.processExpiredClaims, null, false) + new CronJob('* * * * *', this.processExpiredClaims, null, false) ); } } @@ -78,8 +78,8 @@ export class Cron { const token = await generateEmailAirdropToken(users[i].email); await SmtpSendTemplate( [users[i].email], - "Claim your NFT", - "en-airdrop-claim", + 'Claim your NFT', + 'en-airdrop-claim', { appUrl: env.APP_URL, link: `${env.APP_URL}/claim?token=${token}`, @@ -95,8 +95,8 @@ export class Cron { //Currently, waiting line for airdrop is full.Send info email and set appropriate status await SmtpSendTemplate( [users[i].email], - "You are in waiting line for NFT claim", - "en-airdrop-waiting-line", + 'You are in waiting line for NFT claim', + 'en-airdrop-waiting-line', { appUrl: env.APP_URL, } @@ -108,7 +108,7 @@ export class Cron { ); } } catch (e) { - writeLog(LogType.ERROR, e, "cron.ts", "sendEmail"); + writeLog(LogType.ERROR, e, 'cron.ts', 'sendEmail'); updates.push( `(${users[i].id}, '${users[i].email}', ${ AirdropStatus.EMAIL_ERROR @@ -120,7 +120,7 @@ export class Cron { if (updates.length > 0) { const sql = ` INSERT INTO user (id, email, airdrop_status, email_sent_time) - VALUES ${updates.join(",")} + VALUES ${updates.join(',')} ON DUPLICATE KEY UPDATE airdrop_status = VALUES(airdrop_status), email_sent_time = VALUES(email_sent_time)`; @@ -130,7 +130,7 @@ export class Cron { await mysql.commit(conn); } catch (e) { - writeLog(LogType.ERROR, e, "cron.ts", "sendEmail"); + writeLog(LogType.ERROR, e, 'cron.ts', 'sendEmail'); await mysql.rollback(conn); } } @@ -159,7 +159,7 @@ export class Cron { await mysql.paramExecute( `UPDATE user SET airdrop_status = ${AirdropStatus.AIRDROP_CLAIM_EXPIRED} - WHERE id IN (${usersWithExpiredClaim.join(",")}) + WHERE id IN (${usersWithExpiredClaim.join(',')}) ; `, null, @@ -167,7 +167,7 @@ export class Cron { ); console.info( usersWithExpiredClaim.length + - " users updated to AIRDROP_CLAIM_EXPIRED" + ' users updated to AIRDROP_CLAIM_EXPIRED' ); //Get users in waiting line and set their airdrop status to PENDING, so that they will recieve email for claim @@ -187,24 +187,24 @@ export class Cron { )[0] as Array; console.info( - "Num of users in waiting line: " + usersInWaitingLine.length + 'Num of users in waiting line: ' + usersInWaitingLine.length ); if (usersInWaitingLine.length) { - await conn.execute( + await mysql.paramExecute( `UPDATE user SET airdrop_status = ${AirdropStatus.EMAIL_SENT}, email_sent_time = NOW() - WHERE id IN (${usersInWaitingLine.map((x) => x.id).join(",")}) + WHERE id IN (${usersInWaitingLine.map((x) => x.id).join(',')}) ; `, null, conn ); console.info( - usersInWaitingLine.map((x) => x.id).join(",") + - " should me moved from waiting line. Sending emails...." + usersInWaitingLine.map((x) => x.id).join(',') + + ' should me moved from waiting line. Sending emails....' ); for (const user of usersInWaitingLine) { @@ -212,19 +212,21 @@ export class Cron { const token = await generateEmailAirdropToken(user.email); await SmtpSendTemplate( [user.email], - "Claim your NFT", - "en-airdrop-claim", + 'Claim your NFT', + 'en-airdrop-claim', { link: `${env.APP_URL}/claim?token=${token}`, } ); } catch (err) { - await conn.execute( + await mysql.paramExecute( `UPDATE user SET airdrop_status = ${AirdropStatus.EMAIL_ERROR}, WHERE id = ${user.id}) ; - ` + `, + null, + conn ); } } @@ -233,7 +235,7 @@ export class Cron { await mysql.commit(conn); } catch (e) { - writeLog(LogType.ERROR, e, "cron.ts", "processExpiredClaims"); + writeLog(LogType.ERROR, e, 'cron.ts', 'processExpiredClaims'); await mysql.rollback(conn); } } From 02892451da0d8e5a441dc0bc6e07e9e75c58f706 Mon Sep 17 00:00:00 2001 From: ZanJereb Date: Fri, 16 Feb 2024 13:01:22 +0100 Subject: [PATCH 3/4] Changed texts --- frontend/components/parts/ConnectWallet.vue | 2 +- frontend/pages/claim.vue | 4 ++-- frontend/pages/index.vue | 2 +- frontend/pages/success.vue | 9 +++++++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/frontend/components/parts/ConnectWallet.vue b/frontend/components/parts/ConnectWallet.vue index 24b6346..01a32c1 100644 --- a/frontend/components/parts/ConnectWallet.vue +++ b/frontend/components/parts/ConnectWallet.vue @@ -32,7 +32,7 @@ :loading="loading || isLoading" @click="modalWalletVisible = true" > - Connect wallet + Connect your wallet diff --git a/frontend/pages/claim.vue b/frontend/pages/claim.vue index b74244b..d0fc9e3 100644 --- a/frontend/pages/claim.vue +++ b/frontend/pages/claim.vue @@ -100,8 +100,8 @@ async function loadNft(contract: Address, id: number, transactionHash: string) {

Almost there!

- But first, connect compatible digital wallet. This step is crucial for securely receiving - and managing the MENT token you’ll about to receive. + But first, connect a compatible digital wallet. This step is crucial + for securely receiving and managing the MENT token you’re about to receive.

diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue index 2998a50..7624fe5 100644 --- a/frontend/pages/index.vue +++ b/frontend/pages/index.vue @@ -12,7 +12,7 @@ useHead({ The Shape of MENT to Come -

Sign up and win your MENT token

+

Sign up and win one of 200 MENT tokens

By signing up, you’ll be in the game for the hottest perks in the form of MENT token diff --git a/frontend/pages/success.vue b/frontend/pages/success.vue index f90b747..cc9cf6b 100644 --- a/frontend/pages/success.vue +++ b/frontend/pages/success.vue @@ -1,8 +1,13 @@ From 2c959df5de12b4a95b09161c5e01fe0eb89ffc06 Mon Sep 17 00:00:00 2001 From: Tadej Vengust Date: Fri, 16 Feb 2024 13:47:55 +0100 Subject: [PATCH 4/4] update connect message --- backend/src/routes/admin-login.ts | 16 ++++---- backend/src/routes/claim-airdrop.ts | 39 ++++++++------------ backend/src/tests/routes/admin-login.test.ts | 18 ++++----- frontend/components/parts/ConnectWallet.vue | 2 +- frontend/pages/claim.vue | 2 +- 5 files changed, 34 insertions(+), 43 deletions(-) diff --git a/backend/src/routes/admin-login.ts b/backend/src/routes/admin-login.ts index 86bb0b6..6863e68 100644 --- a/backend/src/routes/admin-login.ts +++ b/backend/src/routes/admin-login.ts @@ -1,16 +1,16 @@ -import { Application } from "express"; -import { NextFunction, Request, Response } from "../http"; -import { RouteErrorCode } from "../config/values"; -import { ResourceError } from "../lib/errors"; -import { Identity } from "@apillon/sdk"; -import { generateAdminAuthToken } from "../lib/jwt"; +import { Application } from 'express'; +import { NextFunction, Request, Response } from '../http'; +import { RouteErrorCode } from '../config/values'; +import { ResourceError } from '../lib/errors'; +import { Identity } from '@apillon/sdk'; +import { generateAdminAuthToken } from '../lib/jwt'; /** * Installs new route on the provided application. * @param app ExpressJS application. */ export function inject(app: Application) { - app.post("/login", (req: Request, res: Response, next: NextFunction) => { + app.post('/login', (req: Request, res: Response, next: NextFunction) => { resolve(req, res).catch(next); }); } @@ -28,7 +28,7 @@ export async function resolve(req: Request, res: Response): Promise { walletAddress: context.env.ADMIN_WALLET, signature: body.signature, signatureValidityMinutes: 10, - message: `test\n${body.timestamp}`, + message: `Sign to verify and mint your free Ment NFT!\n${body.timestamp}`, timestamp: body.timestamp, }); diff --git a/backend/src/routes/claim-airdrop.ts b/backend/src/routes/claim-airdrop.ts index b7b2896..eb5cd84 100644 --- a/backend/src/routes/claim-airdrop.ts +++ b/backend/src/routes/claim-airdrop.ts @@ -1,24 +1,21 @@ -import { Application } from "express"; -import { NextFunction, Request, Response } from "../http"; -import { RouteErrorCode, ValidatorErrorCode } from "../config/values"; -import { ResourceError } from "../lib/errors"; -import { readEmailAirdropToken } from "../lib/jwt"; -import { AirdropStatus, User } from "../models/user"; -import { Identity, LogLevel, Nft } from "@apillon/sdk"; -import { LogType, writeLog } from "../lib/logger"; -import { env } from "../config/env"; +import { Application } from 'express'; +import { NextFunction, Request, Response } from '../http'; +import { RouteErrorCode, ValidatorErrorCode } from '../config/values'; +import { ResourceError } from '../lib/errors'; +import { readEmailAirdropToken } from '../lib/jwt'; +import { AirdropStatus, User } from '../models/user'; +import { Identity, LogLevel, Nft } from '@apillon/sdk'; +import { LogType, writeLog } from '../lib/logger'; +import { env } from '../config/env'; /**∂ * Installs new route on the provided application. * @param app ExpressJS application. */ export function inject(app: Application) { - app.post( - "/users/claim", - (req: Request, res: Response, next: NextFunction) => { - resolve(req, res).catch(next); - } - ); + app.post('/users/claim', (req: Request, res: Response, next: NextFunction) => { + resolve(req, res).catch(next); + }); } export async function resolve(req: Request, res: Response): Promise { @@ -33,7 +30,7 @@ export async function resolve(req: Request, res: Response): Promise { walletAddress: body.address, signature: body.signature, signatureValidityMinutes: 10, - message: `test\n${body.timestamp}`, + message: `Sign to verify and mint your free Ment NFT!\n${body.timestamp}`, timestamp: body.timestamp, }); @@ -86,20 +83,14 @@ export async function resolve(req: Request, res: Response): Promise { ? AirdropStatus.AIRDROP_COMPLETED : AirdropStatus.AIRDROP_ERROR; } catch (e) { - writeLog( - LogType.ERROR, - "Error creating airdrop", - "claim-airdrop.ts", - "resolve", - e - ); + writeLog(LogType.ERROR, 'Error creating airdrop', 'claim-airdrop.ts', 'resolve', e); user.airdrop_status = AirdropStatus.AIRDROP_ERROR; } await user.update(); if (response && response.success) { return res.respond(200, { - success: "ok", + success: 'ok', transactionHash: response.transactionHash, }); } else { diff --git a/backend/src/tests/routes/admin-login.test.ts b/backend/src/tests/routes/admin-login.test.ts index 2d9158f..78f36d7 100644 --- a/backend/src/tests/routes/admin-login.test.ts +++ b/backend/src/tests/routes/admin-login.test.ts @@ -2,15 +2,15 @@ import { createContextAndStartServer, Stage, stopServerAndCloseMySqlContext, -} from "../helpers/context"; -import * as request from "supertest"; -import { setupTestDatabase, clearTestDatabase } from "../helpers/migrations"; -import { HDNodeWallet, Wallet } from "ethers"; -import { Identity } from "@apillon/sdk"; +} from '../helpers/context'; +import * as request from 'supertest'; +import { setupTestDatabase, clearTestDatabase } from '../helpers/migrations'; +import { HDNodeWallet, Wallet } from 'ethers'; +import { Identity } from '@apillon/sdk'; let stage: Stage; let adminWallet: HDNodeWallet; -describe("admin login", () => { +describe('admin login', () => { beforeAll(async () => { adminWallet = Wallet.createRandom(); stage = await createContextAndStartServer({ @@ -24,16 +24,16 @@ describe("admin login", () => { await stopServerAndCloseMySqlContext(stage); }); - test("login", async () => { + test('login', async () => { const timestamp = new Date().getTime(); - const message = `test\n${timestamp}`; + const message = `Sign to verify and mint your free Ment NFT!\n${timestamp}`; const identity = new Identity(); const signature = await adminWallet.signMessage(message); const data = { signature, timestamp }; - const res = await request(stage.app).post("/login").send(data); + const res = await request(stage.app).post('/login').send(data); expect(res.status).toBe(200); }); diff --git a/frontend/components/parts/ConnectWallet.vue b/frontend/components/parts/ConnectWallet.vue index 1388a33..7245254 100644 --- a/frontend/components/parts/ConnectWallet.vue +++ b/frontend/components/parts/ConnectWallet.vue @@ -98,7 +98,7 @@ async function login() { } const timestamp = new Date().getTime(); - const message = 'test'; + const message = 'Sign to verify and mint your free Ment NFT!'; const signature = await walletClient.value.signMessage({ message: `${message}\n${timestamp}`, diff --git a/frontend/pages/claim.vue b/frontend/pages/claim.vue index 236af2d..8a29f37 100644 --- a/frontend/pages/claim.vue +++ b/frontend/pages/claim.vue @@ -47,7 +47,7 @@ async function claimAirdrop() { } } - const signature = await walletClient.value.signMessage({ message: `test\n${timestamp}` }); + const signature = await walletClient.value.signMessage({ message: `Sign to verify and mint your free Ment NFT!\n${timestamp}` }); const res = await $api.post('/users/claim', { jwt: query.token?.toString() || '', signature,