From 3726417eb848937bf4aefd3e67e7d9df98e89cb3 Mon Sep 17 00:00:00 2001 From: Heiko Burkhardt Date: Thu, 2 Nov 2023 11:49:31 +0100 Subject: [PATCH 1/2] build: billboard deploy --- .github/workflows/deploy-billboard.yml | 1 + docker/Dockerfile | 2 +- docker/billboard/docker-compose.yml | 26 +++++++++++++------ docker/nginx.conf | 12 +++++++++ .../ws/getDeliveryServiceWSConnections.ts | 2 +- packages/cli/profile/index.ts | 17 ++++++++++-- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/.github/workflows/deploy-billboard.yml b/.github/workflows/deploy-billboard.yml index 240b555e8..433b1004f 100644 --- a/.github/workflows/deploy-billboard.yml +++ b/.github/workflows/deploy-billboard.yml @@ -41,6 +41,7 @@ jobs: echo "REACT_APP_BRANCH=${{ env.branch }}" >> ./.env.react echo "REACT_APP_BUILD_TIME=${{ env.now }}" >> ./.env.react cat ./.env.react >> ./.env + echo "BILLBOARD_SIGNER_PRIVATE_KEY=${{ secrets.BILLBOARD_SIGNER_PRIVATE_KEY }}" >> ./.env echo "RESOLVER_ADDR=0xae6646c22D8eE6479eE0a39Bf63B9bD9e57bAD9d" >> ./.env echo "SIGNING_PUBLIC_KEY=${{ secrets.SIGNING_PUBLIC_KEY }}" >> ./.env echo "SIGNING_PRIVATE_KEY=${{ secrets.SIGNING_PRIVATE_KEY }}" >> ./.env diff --git a/docker/Dockerfile b/docker/Dockerfile index 193168926..03ee858a6 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,7 +1,7 @@ FROM --platform=linux/amd64 node:18-alpine WORKDIR /app COPY . . -RUN apk add --update python3 make g++\ +RUN apk add --update python3 make g++ curl\ && rm -rf /var/cache/apk/* RUN yarn install RUN yarn build diff --git a/docker/billboard/docker-compose.yml b/docker/billboard/docker-compose.yml index 259542604..bac4f3fc2 100644 --- a/docker/billboard/docker-compose.yml +++ b/docker/billboard/docker-compose.yml @@ -6,8 +6,8 @@ services: image: nginx:latest restart: always depends_on: - - offchain-resolver - billboard-client + - ccip-resolver volumes: - ./nginx.conf:/etc/nginx/nginx.conf ports: @@ -33,13 +33,17 @@ services: image: dm3-backend command: yarn workspace dm3-billboard-client start depends_on: - - db - - ccip-resolver + db: + condition: service_started + ccip-resolver: + condition: service_started + offchain-resolver: + condition: service_healthy environment: - PORT: 8082 + PORT: 8083 time: 0 privateKey: ${BILLBOARD_PRIVATE_KEY} - ensNames: '["billboard1.eth"]' + ensNames: '["billboard1.bb-user.dm3.eth"]' mediators: '[]' REDIS_URL: redis://db:6379 RPC: ${RPC} @@ -65,6 +69,11 @@ services: DATABASE_URL: postgresql://postgres:example@offchain-resolver-db:5432 PORT: 8082 LOG_LEVEL: 'debug' + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8082/0x26139b2349282de5ee2bd9c7a53171a28d6a6c84/0xf8c30f63000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000001c0a62696c6c626f617264310762622d7573657203646d3303657468000000000000000000000000000000000000000000000000000000000000000000000000243b3b57de8d7fcfd6548aae2cdb5851741139459856caadb3b9ad3d27872ae921b2348a7d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014bcd6de065fd7e889e3ec86aa2d2780d7553ab3cc000000000000000000000000"] + interval: 30s + timeout: 10s + retries: 5 # web: # image: dm3-backend @@ -85,13 +94,14 @@ services: image: dm3org/ccip-resolver:v0.2.7 restart: always depends_on: - - offchain-resolver + offchain-resolver: + condition: service_healthy environment: - SIGNER_PRIVATE_KEY: ${SIGNER_PRIVATE_KEY} + SIGNER_PRIVATE_KEY: ${BILLBOARD_SIGNER_PRIVATE_KEY} LOG_LEVEL: debug CONFIG: | { - "0xae6646c22d8ee6479ee0a39bf63b9bd9e57bad9d": { + "0x26139b2349282de5ee2bd9c7a53171a28d6a6c84": { "type": "signing", "handlerUrl": "http://offchain-resolver:8082" } diff --git a/docker/nginx.conf b/docker/nginx.conf index 73754b0a5..43aa949a5 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -58,6 +58,18 @@ http { proxy_redirect off; } + location /bb-client { + rewrite ^/bb-client(.*)$ $1 break; + limit_req zone=standardlimit burst=50; + proxy_pass http://billboard-client:8083; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_redirect off; + } + location /socket.io { proxy_pass http://backend:8081/socket.io; proxy_http_version 1.1; diff --git a/packages/billboard-client/src/api/internal/ws/getDeliveryServiceWSConnections.ts b/packages/billboard-client/src/api/internal/ws/getDeliveryServiceWSConnections.ts index ee7d07e7f..b54ab30b5 100644 --- a/packages/billboard-client/src/api/internal/ws/getDeliveryServiceWSConnections.ts +++ b/packages/billboard-client/src/api/internal/ws/getDeliveryServiceWSConnections.ts @@ -14,7 +14,7 @@ export const getDeliveryServiceWSClient = ( return Promise.all( deliveryServices.map(async (ds) => { const client = await new Promise((res, rej) => { - const c = io(ds.url, { + const c = io(ds.url.replace('/api', ''), { auth: { account: { ensName }, token: ds.token, diff --git a/packages/cli/profile/index.ts b/packages/cli/profile/index.ts index a9cb4ee2d..df931b6ad 100644 --- a/packages/cli/profile/index.ts +++ b/packages/cli/profile/index.ts @@ -1,9 +1,15 @@ /* eslint-disable no-console */ import { Command, program } from 'commander'; import { getStorageKeyCreationMessage, createStorageKey } from 'dm3-lib-crypto'; -import { createProfileKeys, UserProfile } from 'dm3-lib-profile'; +import { + createProfileKeys, + getProfileCreationMessage, + SignedUserProfile, + UserProfile, +} from 'dm3-lib-profile'; import { ethers } from 'ethers'; import { getSanitizedWallet } from '../sanitizer/getSanitizedWallet'; +import { stringify } from 'dm3-lib-shared'; const newProfile = async (program: Command) => { const { profilePk, deliveryService } = program.opts(); @@ -47,7 +53,14 @@ const newProfile = async (program: Command) => { ); } - console.log(profile); + const profileCreationMessage = getProfileCreationMessage( + stringify(profile), + ); + + const profileSig = await profileWallet.signMessage(profileCreationMessage); + const signedProfile: SignedUserProfile = { profile, signature: profileSig }; + + console.log(signedProfile); }; export { newProfile }; From 6c6b728ce4c9ce5df352d148a0dae0fb6070db60 Mon Sep 17 00:00:00 2001 From: Heiko Burkhardt Date: Wed, 8 Nov 2023 09:09:10 +0100 Subject: [PATCH 2/2] fix: disable session check for billboard --- .github/workflows/deploy-billboard.yml | 3 +- docker/billboard/docker-compose.yml | 4 ++- packages/backend/src/index.ts | 1 + packages/backend/src/profile.ts | 6 ++++ packages/lib/delivery/src/UserProfile.ts | 10 ++++-- .../offchain-resolver/src/http/profile.ts | 16 +++++++--- .../src/persistance/IDatabase.ts | 1 + .../src/persistance/getDatabase.ts | 1 + .../profile/getProfileContainer.ts | 9 ++++-- .../src/persistance/profile/index.ts | 1 + .../src/persistance/profile/removeAlias.ts | 32 +++++++++++++++++++ .../src/persistance/profile/setUserProfile.ts | 23 +++++++------ 12 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 packages/offchain-resolver/src/persistance/profile/removeAlias.ts diff --git a/.github/workflows/deploy-billboard.yml b/.github/workflows/deploy-billboard.yml index 433b1004f..cc6a68913 100644 --- a/.github/workflows/deploy-billboard.yml +++ b/.github/workflows/deploy-billboard.yml @@ -28,7 +28,7 @@ jobs: env: TARGET_HOST: ${{ secrets.STAGING_HOST_BILLBOARD }} run: | - echo "REACT_APP_ADDR_ENS_SUBDOMAIN=.beta-addr.dm3.eth" >> ./.env.react + echo "REACT_APP_ADDR_ENS_SUBDOMAIN=.bb-addr.dm3.eth" >> ./.env.react echo "REACT_APP_BACKEND=http://${{ secrets.STAGING_HOST_BILLBOARD }}/api" >> ./.env.react echo "REACT_APP_DEFAULT_DELIVERY_SERVICE=beta-ds.dm3.eth" >> ./.env.react echo "REACT_APP_DEFAULT_SERVICE=http://${{ secrets.STAGING_HOST_BILLBOARD }}/api" >> ./.env.react @@ -52,6 +52,7 @@ jobs: echo "RPC=${{ secrets.STAGING_RPC }}" >> ./.env echo "BILLBOARD_PRIVATE_KEY=${{ secrets.BILLBOARD_PRIVATE_KEY}}" >> ./.env echo "interceptor=${{ secrets.INTERCEPTOR}}" >> ./.env + echo "DISABLE_SESSION_CHECK='true'" >> ./.env envsubst '${SSL_CERTIFICATE_BASE_LOC} ${TLS_CERTIFICATE_LOCATION} ${TARGET_HOST}' < ./docker/nginx.conf > ./nginx.conf cat ./.env - name: Build docker image diff --git a/docker/billboard/docker-compose.yml b/docker/billboard/docker-compose.yml index bac4f3fc2..d3e9b0b12 100644 --- a/docker/billboard/docker-compose.yml +++ b/docker/billboard/docker-compose.yml @@ -7,6 +7,7 @@ services: restart: always depends_on: - billboard-client + - backend - ccip-resolver volumes: - ./nginx.conf:/etc/nginx/nginx.conf @@ -25,6 +26,7 @@ services: SIGNING_PRIVATE_KEY: ${SIGNING_PRIVATE_KEY} ENCRYPTION_PUBLIC_KEY: ${ENCRYPTION_PUBLIC_KEY} ENCRYPTION_PRIVATE_KEY: ${ENCRYPTION_PRIVATE_KEY} + DISABLE_SESSION_CHECK: ${DISABLE_SESSION_CHECK} RPC: ${RPC} PORT: 8081 LOG_LEVEL: 'debug' @@ -43,7 +45,7 @@ services: PORT: 8083 time: 0 privateKey: ${BILLBOARD_PRIVATE_KEY} - ensNames: '["billboard1.bb-user.dm3.eth"]' + ensNames: '["billboard1.bb.dm3.eth"]' mediators: '[]' REDIS_URL: redis://db:6379 RPC: ${RPC} diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 63c04ae80..568cfdaa4 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -16,6 +16,7 @@ import Profile from './profile'; import RpcProxy from './rpc/rpc-proxy'; import Storage from './storage'; import { logInfo } from 'dm3-lib-shared'; +import 'dotenv/config'; import { errorHandler, diff --git a/packages/backend/src/profile.ts b/packages/backend/src/profile.ts index c22baf2ec..00faee919 100644 --- a/packages/backend/src/profile.ts +++ b/packages/backend/src/profile.ts @@ -49,6 +49,8 @@ export default () => { method: 'POST', url: req.url, ensName, + disableSessionCheck: + process.env.DISABLE_SESSION_CHECK === 'true', }); const data = await submitUserProfile( @@ -69,6 +71,10 @@ export default () => { res.json(data); } catch (e) { + global.logger.warn({ + message: 'POST profile', + error: JSON.stringify(e), + }); res.status(400).send({ message: `Couldn't store profile`, error: JSON.stringify(e), diff --git a/packages/lib/delivery/src/UserProfile.ts b/packages/lib/delivery/src/UserProfile.ts index 3ffee5aea..71e4bd579 100644 --- a/packages/lib/delivery/src/UserProfile.ts +++ b/packages/lib/delivery/src/UserProfile.ts @@ -38,11 +38,13 @@ export async function submitUserProfile( send: (socketId: string) => void, ): Promise { const account = normalizeEnsName(ensName); + console.log('1', account, signedUserProfile); if (!(await checkUserProfile(provider, signedUserProfile, account))) { throw Error('Signature invalid.'); } - //TODO: remvoe DISABLE_SESSION_CHECK + console.log('2', process.env.DISABLE_SESSION_CHECK); + //TODO: remvoe DISABLE_SESSION_CHECK // DISABLE_SESSION_CHECK is a special solution for ETH Prague if ( process.env.DISABLE_SESSION_CHECK !== 'true' && @@ -50,6 +52,7 @@ export async function submitUserProfile( ) { throw Error('Profile exists already'); } + console.log('3'); const session: Session = { account, signedUserProfile, @@ -57,16 +60,17 @@ export async function submitUserProfile( createdAt: new Date().getTime(), profileExtension: getDefaultProfileExtension(), }; + console.log('4', session); await setSession(account.toLocaleLowerCase(), session); - + console.log('5'); await handlePendingConversations( account, getSession, getPendingConversations, send, ); - + console.log('6'); return session.token; } diff --git a/packages/offchain-resolver/src/http/profile.ts b/packages/offchain-resolver/src/http/profile.ts index ec022e4e3..f2f8a23bd 100644 --- a/packages/offchain-resolver/src/http/profile.ts +++ b/packages/offchain-resolver/src/http/profile.ts @@ -85,11 +85,19 @@ export function profile(web3Provider: ethers.providers.BaseProvider) { error: 'address has already claimed a subdomain', }); } + global.logger.debug({ + message: 'nameP setAlias', + hotAddr: hotAddr + '.bb-addr.dm3.eth', + alias: `${address}.bb-user.dm3.eth`, + }); + + await req.app.locals.db.removeAlias( + `${address}.bb-user.dm3.eth`, + ); - await req.app.locals.db.setUserProfile( - `${address}.user.ethprague.dm3.eth`, - signedUserProfile, - hotAddr, + await req.app.locals.db.setAlias( + hotAddr + '.bb-addr.dm3.eth', + `${address}.bb-user.dm3.eth`, ); return res.sendStatus(200); diff --git a/packages/offchain-resolver/src/persistance/IDatabase.ts b/packages/offchain-resolver/src/persistance/IDatabase.ts index b89274e2e..fb8563c0d 100644 --- a/packages/offchain-resolver/src/persistance/IDatabase.ts +++ b/packages/offchain-resolver/src/persistance/IDatabase.ts @@ -13,6 +13,7 @@ export interface IDatabase { address: string, ): Promise; removeUserProfile(ensName: string): Promise; + removeAlias(alias: string): Promise; setAlias(name: string, alias: string): Promise; getProfileContainerForAlias( alias: string, diff --git a/packages/offchain-resolver/src/persistance/getDatabase.ts b/packages/offchain-resolver/src/persistance/getDatabase.ts index 6834e1df6..71e7045f7 100644 --- a/packages/offchain-resolver/src/persistance/getDatabase.ts +++ b/packages/offchain-resolver/src/persistance/getDatabase.ts @@ -20,6 +20,7 @@ export async function getDatabase( Profile.getProfileContainerForAlias(prismaClient), getProfileAliasByAddress: Profile.getProfileAliasByAddress(prismaClient), + removeAlias: Profile.removeAlias(prismaClient), }; } diff --git a/packages/offchain-resolver/src/persistance/profile/getProfileContainer.ts b/packages/offchain-resolver/src/persistance/profile/getProfileContainer.ts index 6eefcb4bc..3689c0e7b 100644 --- a/packages/offchain-resolver/src/persistance/profile/getProfileContainer.ts +++ b/packages/offchain-resolver/src/persistance/profile/getProfileContainer.ts @@ -14,6 +14,11 @@ export type ProfileContainer = { export function getProfileContainer(db: PrismaClient) { return async (name: string) => { + global.logger.debug({ + message: 'getProfileContainer call', + nameHash: ethers.utils.namehash(name), + name, + }); const profileContainer = await db.profileContainer.findUnique({ where: { nameHash: ethers.utils.namehash(name), @@ -31,7 +36,7 @@ export function getProfileContainer(db: PrismaClient) { } : null; global.logger.debug({ - message: 'getProfileContainer', + message: 'getProfileContainer found', nameHash: ethers.utils.namehash(name), profileContainerResult, }); @@ -39,7 +44,7 @@ export function getProfileContainer(db: PrismaClient) { return profileContainerResult; } else { global.logger.debug({ - message: 'getProfileContainer', + message: 'getProfileContainer not found', nameHash: ethers.utils.namehash(name), }); // try to find an alias which equlas name diff --git a/packages/offchain-resolver/src/persistance/profile/index.ts b/packages/offchain-resolver/src/persistance/profile/index.ts index c0b092362..9707560a2 100644 --- a/packages/offchain-resolver/src/persistance/profile/index.ts +++ b/packages/offchain-resolver/src/persistance/profile/index.ts @@ -10,3 +10,4 @@ export { setAlias } from './setAlias'; export { getProfileContainerForAlias } from './getProfileContainerForAlias'; export { setUserProfile } from './setUserProfile'; export { getProfileAliasByAddress } from './getProfileAliasByAddress'; +export { removeAlias } from './removeAlias'; diff --git a/packages/offchain-resolver/src/persistance/profile/removeAlias.ts b/packages/offchain-resolver/src/persistance/profile/removeAlias.ts new file mode 100644 index 000000000..a744d04ed --- /dev/null +++ b/packages/offchain-resolver/src/persistance/profile/removeAlias.ts @@ -0,0 +1,32 @@ +import { PrismaClient } from '@prisma/client'; +import { normalizeEnsName } from 'dm3-lib-profile'; + +/** + * + * @param {Redis} redis - Redis client + * @param {string} alias - ENS alias name + * @returns {Promise} - A promise that resolves to true if the profile is removed, false otherwise + */ +export function removeAlias(db: PrismaClient) { + return async (alias: string) => { + try { + const normalizedAlias = normalizeEnsName(alias); + + await db.alias.delete({ + where: { + alias: normalizedAlias, + }, + }); + + global.logger.debug({ + message: 'removeAlias', + + alias: normalizedAlias, + }); + + return true; + } catch (e) { + return false; + } + }; +} diff --git a/packages/offchain-resolver/src/persistance/profile/setUserProfile.ts b/packages/offchain-resolver/src/persistance/profile/setUserProfile.ts index 5b1cc1e78..c77d8f22f 100644 --- a/packages/offchain-resolver/src/persistance/profile/setUserProfile.ts +++ b/packages/offchain-resolver/src/persistance/profile/setUserProfile.ts @@ -35,26 +35,31 @@ export function setUserProfile(db: PrismaClient) { const nameHash = ethers.utils.namehash(name); try { + const id = uuidv4(); + global.logger.debug({ + message: 'pre setUserProfile', + id, + nameHash, + profile: JSON.stringify(profile), + address: formatAddress(address), + ensName: normalizeEnsName(name), + }); await db.profileContainer.create({ data: { - id: uuidv4(), + id, nameHash, profile: JSON.stringify(profile), address: formatAddress(address), ensName: normalizeEnsName(name), }, }); - global.logger.debug({ - message: 'setUserProfile', - id: uuidv4(), - nameHash, - profile: JSON.stringify(profile), - address: formatAddress(address), - ensName: normalizeEnsName(name), - }); return true; } catch (e) { + global.logger.warn({ + message: `setUserProfile error`, + error: JSON.stringify(e), + }); return false; } };