From fded4d37b9ca5d7a04d06fc7b3fab084f3d99160 Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Tue, 2 Jan 2024 21:16:40 -0800 Subject: [PATCH 1/4] hotfix email verification --- .github/workflows/build-server.yaml | 2 -- desci-contracts/yarn.lock | 12 ++++++------ desci-server/src/controllers/auth/magic.ts | 5 ++++- desci-server/src/services/auth.ts | 17 ++++++++++++++--- desci-server/src/services/ipfs.ts | 2 +- desci-server/src/services/user.ts | 5 ++++- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-server.yaml b/.github/workflows/build-server.yaml index 52ccfec22..3684c076e 100644 --- a/.github/workflows/build-server.yaml +++ b/.github/workflows/build-server.yaml @@ -195,7 +195,6 @@ jobs: - name: Verify EKS Deployment (DEV) if: github.ref == 'refs/heads/develop' run: | - kubectl apply -f desci-server/kubernetes/deployment_dev.yaml kubectl rollout status deployment/desci-server-dev - name: Verify EKS Deployment (DEMO) @@ -206,5 +205,4 @@ jobs: - name: Verify EKS Deployment (PROD) if: github.ref == 'refs/heads/main' run: | - kubectl apply -f desci-server/kubernetes/deployment.yaml kubectl rollout status deployment/desci-server diff --git a/desci-contracts/yarn.lock b/desci-contracts/yarn.lock index 251ffa328..be130812b 100644 --- a/desci-contracts/yarn.lock +++ b/desci-contracts/yarn.lock @@ -3062,9 +3062,9 @@ concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2, concat-stream@ readable-stream "^2.2.2" typedarray "^0.0.6" -"concat-stream@github:maxogden/concat-stream#feat/smaller": +"concat-stream@github:max-mapper/concat-stream#feat/smaller": version "2.0.0" - resolved "https://codeload.github.com/maxogden/concat-stream/tar.gz/057bc7b5d6d8df26c8cf00a3f151b6721a0a8034" + resolved "https://codeload.github.com/max-mapper/concat-stream/tar.gz/057bc7b5d6d8df26c8cf00a3f151b6721a0a8034" dependencies: inherits "^2.0.3" readable-stream "^3.0.2" @@ -5550,7 +5550,7 @@ ipfs-http-client@34.0.0: bs58 "^4.0.1" buffer "^5.4.2" cids "~0.7.1" - concat-stream "github:maxogden/concat-stream#feat/smaller" + concat-stream "github:max-mapper/concat-stream#feat/smaller" debug "^4.1.0" detect-node "^2.0.4" end-of-stream "^1.4.1" @@ -5579,7 +5579,7 @@ ipfs-http-client@34.0.0: multibase "~0.6.0" multicodec "~0.5.1" multihashes "~0.4.14" - ndjson "github:maxogden/ndjson#feat/readable-stream3" + ndjson "github:max-mapper/ndjson#feat/readable-stream3" once "^1.4.0" peer-id "~0.12.3" peer-info "~0.15.1" @@ -7474,9 +7474,9 @@ napi-macros@~2.0.0: resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== -"ndjson@github:maxogden/ndjson#feat/readable-stream3": +"ndjson@github:max-mapper/ndjson#feat/readable-stream3": version "1.5.0" - resolved "https://codeload.github.com/maxogden/ndjson/tar.gz/4db16da6b42e5b39bf300c3a7cde62abb3fa3a11" + resolved "https://codeload.github.com/max-mapper/ndjson/tar.gz/4db16da6b42e5b39bf300c3a7cde62abb3fa3a11" dependencies: json-stringify-safe "^5.0.1" minimist "^1.2.0" diff --git a/desci-server/src/controllers/auth/magic.ts b/desci-server/src/controllers/auth/magic.ts index 2fd2c6dca..2131a760a 100644 --- a/desci-server/src/controllers/auth/magic.ts +++ b/desci-server/src/controllers/auth/magic.ts @@ -33,7 +33,10 @@ export const magic = async (req: Request, res: Response, next: NextFunction) => let user = await prismaClient.user.findFirst({ where: { - email, + email: { + equals: email, + mode: 'insensitive' + }, }, }); diff --git a/desci-server/src/services/auth.ts b/desci-server/src/services/auth.ts index d5fa5f0f3..41d974591 100644 --- a/desci-server/src/services/auth.ts +++ b/desci-server/src/services/auth.ts @@ -105,7 +105,12 @@ const sendMagicLinkEmail = async (email: string, ip?: string) => { const expiresAt = new Date('1980-01-01'); await client.magicLink.updateMany({ - where: { email }, + where: { + email: { + equals: email, + mode: 'insensitive' + } + }, data: { expiresAt, }, @@ -195,7 +200,10 @@ const sendMagicLink = async (email: string, ip?: string) => { // Check for recent magic link generation const recentMagicLink = await client.magicLink.findFirst({ where: { - email, + email: { + equals: email, + mode: 'insensitive' + }, createdAt: { gte: new Date(Date.now() - MAGIC_LINK_COOLDOWN), }, @@ -208,7 +216,10 @@ const sendMagicLink = async (email: string, ip?: string) => { const user = await client.user.findFirst({ where: { - email, + email: { + equals: email, + mode: 'insensitive' + }, }, }); diff --git a/desci-server/src/services/ipfs.ts b/desci-server/src/services/ipfs.ts index dc94d5220..3ae753539 100644 --- a/desci-server/src/services/ipfs.ts +++ b/desci-server/src/services/ipfs.ts @@ -374,7 +374,7 @@ export const getDirectoryTreeCids = async (cid: string, externalCidMap: External } }); }; - const flatCids = uniq( + const flatCids: string[] = uniq( recurse(tree) .filter(Boolean) .map((e) => e.cid || e) diff --git a/desci-server/src/services/user.ts b/desci-server/src/services/user.ts index d1089d456..98d7eecdf 100644 --- a/desci-server/src/services/user.ts +++ b/desci-server/src/services/user.ts @@ -267,7 +267,10 @@ export async function getUserByOrcId(orcid: string): Promise { export async function getUserByEmail(email: string): Promise { logger.trace({ fn: 'getUserByEmail' }, `user::getUserByEmail ${hideEmail(email)}`); - const user = await client.user.findFirst({ where: { email } }); + const user = await client.user.findFirst({ where: { email: { + equals: email, + mode: 'insensitive' + } } }); return user; } From 83899434cd922decb0e1ddee8e5128034eb96d1f Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Sun, 24 Mar 2024 20:56:15 -0400 Subject: [PATCH 2/4] additional publish logging --- desci-server/src/workers/publish.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/desci-server/src/workers/publish.ts b/desci-server/src/workers/publish.ts index 717a0f20f..92ae5f07e 100644 --- a/desci-server/src/workers/publish.ts +++ b/desci-server/src/workers/publish.ts @@ -15,7 +15,7 @@ const ETHEREUM_RPC_URL = process.env.ETHEREUM_RPC_URL || 'http://host.docker.int if (!ETHEREUM_RPC_URL) throw new Error('Env var` ETHEREUM_RPC_URL` not set'); -const logger = parentLogger.child({ module: 'PUBLISH WORKER ' }); +const logger = parentLogger.child({ module: 'publish.ts_PUBLISH_WORKER' }); const checkTransaction = async (transactionId: string, uuid: string) => { const provider = ethers.getDefaultProvider(ETHEREUM_RPC_URL); @@ -37,34 +37,40 @@ const checkTransaction = async (transactionId: string, uuid: string) => { async function processPublishQueue() { const task = await dequeueTask(); - if (!task) return ProcessOutcome.EmptyQueue; + logger.info({ task }, 'publish::processPublishQueue task info'); + + if (!task) { + logger.info('publish::processPublishQueue Empty Queue'); + return ProcessOutcome.EmptyQueue; + } try { const txStatus = await checkTransaction(task.transactionId, task.uuid); + logger.info({ txStatus }, 'publish::processPublishQueue txStatus'); if (txStatus === 1) { // todo: dispatch publish task publishHandler(task) .then((published) => { - logger.info({ task, published }, 'PUBLISH SUCCESS'); + logger.info({ task, published }, 'publish::processPublishQueue PUBLISH SUCCESS'); }) .catch((err) => { - logger.info({ task, err }, 'PUBLISH FAILED'); + logger.info({ task, err }, 'publish::processPublishQueue PUBLISH FAILED'); }); // todo: dequeue task await prisma.publishTaskQueue.delete({ where: { id: task.id } }); } else if (txStatus === 0) { await prisma.publishTaskQueue.update({ where: { id: task.id }, data: { status: PublishTaskQueueStatus.FAILED } }); - logger.info({ txStatus }, 'PUBLISH TX Receipt'); + logger.info({ txStatus }, 'publish::processPublishQueue PUBLISH TX Receipt'); } else { await prisma.publishTaskQueue.update({ where: { id: task.id }, data: { status: PublishTaskQueueStatus.PENDING }, }); - logger.info({ txStatus }, 'PUBLISH TX Might be stuck'); + logger.info({ txStatus }, 'publish::processPublishQueue PUBLISH TX Might be stuck'); } return ProcessOutcome.TaskCompleted; } catch (err) { - logger.error({ err }, 'ProcessPublishQueue::ERROR'); + logger.error({ err }, 'publish::processPublishQueue ProcessPublishQueue::ERROR'); return ProcessOutcome.Error; } } From 61fd3fabfef16d7eafda8a9bf37a54e8c2c7188d Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 6 Jun 2024 14:41:54 +0200 Subject: [PATCH 3/4] error catching publish worker --- desci-server/src/workers/publish.ts | 30 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/desci-server/src/workers/publish.ts b/desci-server/src/workers/publish.ts index a1d876b64..33fb41354 100644 --- a/desci-server/src/workers/publish.ts +++ b/desci-server/src/workers/publish.ts @@ -114,19 +114,23 @@ const delay = async (timeMs: number) => { export async function runWorkerUntilStopped() { while (true) { - const outcome = await processPublishQueue(); - if (!process.env.MUTE_PUBLISH_WORKER) logger.info({ outcome }, 'Processed Queue'); - switch (outcome) { - case ProcessOutcome.EmptyQueue: - await delay(10000); - break; - case ProcessOutcome.Error: - await delay(1000); - break; - case ProcessOutcome.TaskCompleted: - break; - default: - logger.error({ outcome }, 'UNREACHABLE CODE REACHED, CHECK IMMEDIATELY'); + try { + const outcome = await processPublishQueue(); + if (!process.env.MUTE_PUBLISH_WORKER) logger.info({ outcome }, 'Processed Queue'); + switch (outcome) { + case ProcessOutcome.EmptyQueue: + await delay(10000); + break; + case ProcessOutcome.Error: + await delay(1000); + break; + case ProcessOutcome.TaskCompleted: + break; + default: + logger.error({ outcome }, 'UNREACHABLE CODE REACHED, CHECK IMMEDIATELY'); + } + } catch (e) { + logger.error({ e }, 'PUBLISH WORKER LOOP ERROR'); } } } From 73214a1b3bbf977247bf5feed1fdfe6aa0e76e2e Mon Sep 17 00:00:00 2001 From: Sina Iman Date: Thu, 27 Jun 2024 18:40:18 +0200 Subject: [PATCH 4/4] add support to claim all optional attestations --- desci-server/src/controllers/attestations/claims.ts | 2 +- desci-server/src/routes/v1/attestations/index.ts | 4 ++-- desci-server/src/services/Attestation.ts | 6 ++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/desci-server/src/controllers/attestations/claims.ts b/desci-server/src/controllers/attestations/claims.ts index d499fc356..0a07dac16 100644 --- a/desci-server/src/controllers/attestations/claims.ts +++ b/desci-server/src/controllers/attestations/claims.ts @@ -129,7 +129,7 @@ export const claimEntryRequirements = async (req: Request, res: Response, _next: logger.info({ communityId, body: req.body }, 'claimEntryRequirements'); const uuid = ensureUuidEndsWithDot(nodeUuid); - const entryAttestations = await attestationService.getCommunityEntryAttestations(communityId); + const entryAttestations = await attestationService.getAllCommunityEntryAttestations(communityId); logger.info({ entryAttestations }); const claimables = (await asyncMap(entryAttestations, async (attestation) => { diff --git a/desci-server/src/routes/v1/attestations/index.ts b/desci-server/src/routes/v1/attestations/index.ts index cfefa0b0d..dc27c02dc 100644 --- a/desci-server/src/routes/v1/attestations/index.ts +++ b/desci-server/src/routes/v1/attestations/index.ts @@ -43,8 +43,8 @@ import { const router = Router(); -router.get('/suggestions/all', [ensureUser], asyncHander(getAllRecommendations)); -router.get('/suggestions/protected', [ensureUser], asyncHander(getValidatedRecommendations)); +router.get('/suggestions/all', [], asyncHander(getAllRecommendations)); +router.get('/suggestions/protected', [], asyncHander(getValidatedRecommendations)); router.get( '/claims/:communityId/:dpid', [ensureUser, validate(showCommunityClaimsSchema)], diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index 63c53a82c..489d45616 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -290,6 +290,12 @@ export class AttestationService { return prisma.communityEntryAttestation.findMany({ where: { desciCommunityId: communityId, required: true } }); } + async getAllCommunityEntryAttestations(communityId: number) { + const community = await communityService.findCommunityById(communityId); + if (!community) throw new CommunityNotFoundError(); + return prisma.communityEntryAttestation.findMany({ where: { desciCommunityId: communityId } }); + } + async claimAttestation({ attestationId, attestationVersion,