Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(prisma-transaction): remove Promise.all in Prisma transaction #21

Merged
merged 2 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ DATABASE_URL="postgres://postgres.[YOUR_SUPABASE_PROJECT_ID]:[YOUR_DB_PASSWORD]@
REDIS_PASSWORD="authpassword"
REDIS_HOST=redis
REDIS_PORT=6379
INFURA_API_KEY=
WALLETCONNECT_PROJECT_ID=
4 changes: 2 additions & 2 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
TF_VAR_redis_host: ${{ secrets.REDIS_HOST }}
TF_VAR_redis_port: ${{ secrets.REDIS_PORT }}
TF_VAR_redis_password: ${{ secrets.REDIS_PASSWORD }}
TF_VAR_infura_api_key: ${{ secrets.INFURA_API_KEY }}
TF_VAR_walletconnect_project_id: ${{ secrets.WALLETCONNECT_PROJECT_ID }}
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
TF_VAR_redis_host: ${{ secrets.REDIS_HOST }}
TF_VAR_redis_port: ${{ secrets.REDIS_PORT }}
TF_VAR_redis_password: ${{ secrets.REDIS_PASSWORD }}
TF_VAR_infura_api_key: ${{ secrets.INFURA_API_KEY }}
TF_VAR_walletconnect_project_id: ${{ secrets.WALLETCONNECT_PROJECT_ID }}
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "3"
version: '3'
services:
api:
build: .
Expand All @@ -18,7 +18,7 @@ services:
REDIS_PASSWORD: ${REDIS_PASSWORD}
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
INFURA_API_KEY: ${INFURA_API_KEY}
WALLETCONNECT_PROJECT_ID: ${WALLETCONNECT_PROJECT_ID}
depends_on:
redis:
condition: service_healthy
Expand All @@ -28,6 +28,6 @@ services:
image: redis:6.2.12
command: redis-server --requirepass ${REDIS_PASSWORD}
healthcheck:
test: ["CMD", "redis-cli", "ping"]
test: ['CMD', 'redis-cli', 'ping']
ports:
- "6379:6379"
- '6379:6379'
464 changes: 294 additions & 170 deletions package-lock.json

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,29 @@
"author": "",
"license": "ISC",
"dependencies": {
"@prisma/client": "^5.3.1",
"connect-redis": "^7.1.0",
"@prisma/client": "^5.9.1",
"connect-redis": "^7.1.1",
"cookie": "^0.5.0",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"ethers": "^6.7.1",
"dotenv": "^16.4.1",
"ethers": "^6.10.0",
"express": "^4.18.2",
"express-rate-limit": "^7.0.2",
"express-session": "^1.17.3",
"express-rate-limit": "^7.1.5",
"express-session": "^1.18.0",
"ioredis": "^5.3.2",
"jsonwebtoken": "^9.0.2",
"siwe": "^2.1.4"
},
"devDependencies": {
"@types/cookie": "^0.5.2",
"@types/cors": "^2.8.14",
"@types/express": "^4.17.18",
"@types/express-session": "^1.17.8",
"@types/jsonwebtoken": "^9.0.3",
"@types/node": "^18.14.4",
"@types/cookie": "^0.5.4",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/express-session": "^1.17.10",
"@types/jsonwebtoken": "^9.0.5",
"@types/node": "^18.19.14",
"concurrently": "^7.6.0",
"nodemon": "^3.0.1",
"prisma": "^5.3.1",
"nodemon": "^3.0.3",
"prisma": "^5.9.1",
"typescript": "^4.9.5"
}
}
29 changes: 28 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ model mfa_challenges {
ip_address String @db.Inet
mfa_factors mfa_factors @relation(fields: [factor_id], references: [id], onDelete: Cascade, onUpdate: NoAction, map: "mfa_challenges_auth_factor_id_fkey")

@@index([created_at(sort: Desc)], map: "mfa_challenge_created_at_idx")
@@schema("auth")
}

Expand All @@ -85,6 +86,7 @@ model mfa_factors {
users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction)

@@index([user_id, created_at], map: "factor_id_created_at_idx")
@@index([user_id])
@@schema("auth")
}

Expand All @@ -104,7 +106,8 @@ model refresh_tokens {
@@index([instance_id, user_id])
@@index([parent])
@@index([session_id, revoked])
@@index([token])
@@index([session_id], map: "refresh_token_session_id")
@@index([updated_at(sort: Desc)])
@@schema("auth")
}

Expand Down Expand Up @@ -132,10 +135,13 @@ model saml_relay_states {
from_ip_address String? @db.Inet
created_at DateTime? @db.Timestamptz(6)
updated_at DateTime? @db.Timestamptz(6)
flow_state_id String? @db.Uuid
flow_state flow_state? @relation(fields: [flow_state_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
sso_providers sso_providers @relation(fields: [sso_provider_id], references: [id], onDelete: Cascade, onUpdate: NoAction)

@@index([for_email])
@@index([sso_provider_id])
@@index([created_at(sort: Desc)])
@@schema("auth")
}

Expand All @@ -159,6 +165,7 @@ model sessions {

@@index([user_id])
@@index([user_id, created_at], map: "user_id_created_at_idx")
@@index([not_after(sort: Desc)])
@@schema("auth")
}

Expand Down Expand Up @@ -229,6 +236,26 @@ model users {
@@schema("auth")
}

/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
model flow_state {
id String @id @db.Uuid
user_id String? @db.Uuid
auth_code String
code_challenge String
provider_type String
provider_access_token String?
provider_refresh_token String?
created_at DateTime? @db.Timestamptz(6)
updated_at DateTime? @db.Timestamptz(6)
authentication_method String
saml_relay_states saml_relay_states[]

@@index([created_at(sort: Desc)])
@@index([auth_code], map: "idx_auth_code")
@@index([user_id, authentication_method], map: "idx_user_id_auth_method")
@@schema("auth")
}

enum aal_level {
aal1
aal2
Expand Down
80 changes: 38 additions & 42 deletions src/handlers/verify.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,80 @@
import { ethers } from "ethers";
import { Request, Response } from "express";
import { SiweErrorType, SiweMessage } from "siwe";
import { createOrUpdateUser } from "../services/prisma";
import { ethers } from 'ethers'
import { Request, Response } from 'express'
import { SiweErrorType, SiweMessage } from 'siwe'
import { createOrUpdateUser } from '../services/prisma'

const provider = new ethers.InfuraProvider(
"mainnet",
process.env.INFURA_API_KEY
);
const provider = new ethers.JsonRpcProvider(
`https://rpc.walletconnect.com/v1?chainId=eip155:1&projectId=${process.env.WALLETCONNECT_PROJECT_ID}`
)

export const verifyAndSignIn = async (req: Request, res: Response) => {
try {
if (!req.body.message) {
res
.status(422)
.json({ message: "Expected prepareMessage object as body." });
return;
return res.status(422).json({ message: 'Expected prepareMessage object as body.' })
}

const message = new SiweMessage(req.body.message);
const message = new SiweMessage(req.body.message)
const fields = await message.verify(
{
signature: req.body.signature,
nonce: req.session.nonce,
nonce: req.session.nonce
},
{
provider,
provider
}
);
)

req.session.siwe = fields.data;
req.session.siwe = fields.data
if (!fields.data.expirationTime) {
return res.status(422).json({
message: "Expected expirationTime to be set.",
});
message: 'Expected expirationTime to be set.'
})
}
req.session.cookie.expires = new Date(fields.data.expirationTime);
req.session.cookie.expires = new Date(fields.data.expirationTime)

const { accessToken, refreshToken } = await createOrUpdateUser(fields.data);
const { accessToken, refreshToken } = await createOrUpdateUser(fields.data)

return req.session.save(() => {
return res.status(200).json({
accessToken: accessToken,
refreshToken: refreshToken,
});
});
refreshToken: refreshToken
})
})
} catch (e: any) {
console.error(e);
req.session.siwe = undefined;
req.session.nonce = undefined;
console.error(e)
req.session.siwe = undefined
req.session.nonce = undefined
try {
switch (e) {
case SiweErrorType.EXPIRED_MESSAGE: {
req.session.save(() => res.status(440).json({ message: e.message }));
break;
req.session.save(() => res.status(440).json({ message: e.message }))
break
}
case SiweErrorType.INVALID_SIGNATURE: {
req.session.save(() => res.status(422).json({ message: e.message }));
break;
req.session.save(() => res.status(422).json({ message: e.message }))
break
}
case SiweErrorType.INVALID_ADDRESS: {
req.session.save(() => res.status(422).json({ message: e.message }));
break;
req.session.save(() => res.status(422).json({ message: e.message }))
break
}
case SiweErrorType.NONCE_MISMATCH: {
req.session.save(() => res.status(400).json({ message: e.message }));
break;
req.session.save(() => res.status(400).json({ message: e.message }))
break
}
case SiweErrorType.DOMAIN_MISMATCH: {
req.session.save(() => res.status(400).json({ message: e.message }));
break;
req.session.save(() => res.status(400).json({ message: e.message }))
break
}
default: {
req.session.save(() => res.status(500).json({ message: e.message }));
break;
req.session.save(() => res.status(500).json({ message: e.message }))
break
}
}
} catch (sessionError) {
console.error(`Failed to save session, ${JSON.stringify(sessionError)}`);
console.error(`Failed to save session, ${JSON.stringify(sessionError)}`)
}

return;
return
}
};
}
Loading