Skip to content

Commit

Permalink
Make lib use token, projects is array
Browse files Browse the repository at this point in the history
  • Loading branch information
Boldizsar Mezei committed Nov 7, 2023
1 parent 128a26c commit 3ca4588
Show file tree
Hide file tree
Showing 39 changed files with 149 additions and 125 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/action_deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ jobs:
credentials_json: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_SOONAVERSE }}'
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v1'
- name: Set env vars
working-directory: packages/api
run: echo "$FUNCTIONS_ENV_VARS" >> .env
env:
FUNCTIONS_ENV_VARS: ${{ secrets.FUNCTIONS_ENV_VARS_PROD }}
- name: Build image
run: |
cp packages/api/Dockerfile .
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/action_deploy-wen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ jobs:
credentials_json: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_SOONAVERSE_TEST }}'
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v1'
- name: Set env vars
working-directory: packages/api
run: echo "$FUNCTIONS_ENV_VARS" >> .env
env:
FUNCTIONS_ENV_VARS: ${{ secrets.FUNCTIONS_ENV_VARS_TEST }}
- name: Build image
run: |
cp packages/api/Dockerfile .
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/lib_lint-and-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
pull_request:
paths:
- packages/lib/**
- packages/api/**

jobs:
soon_lib:
Expand Down
6 changes: 3 additions & 3 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"private": "true",
"scripts": {
"build": "tsc",
"build": "tsc && cp .env lib/.env",
"start": "tsc && node lib/index"
},
"dependencies": {
Expand All @@ -27,14 +27,14 @@
"jsonwebtoken": "9.0.2",
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"ws": "^8.13.0"
"ws": "^8.13.0",
"dotenv": "16.3.1"
},
"devDependencies": {
"@types/cors": "2.8.14",
"@types/express": "4.17.17",
"@types/lodash": "4.14.200",
"@types/ws": "8.5.5",
"dotenv": "16.3.1",
"typescript": "4.9.5"
}
}
4 changes: 2 additions & 2 deletions packages/api/src/getMany.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ export const getMany = async (project: string, url: string) => {
.collection(baseCollectionPath as COL)
.limit(getQueryLimit(body.collection));

query = query.where(`projects.${project}`, '==', true);

if (body.fieldName && body.fieldValue != null) {
try {
const filters = getFilters(body.fieldName, body.fieldValue);
Expand All @@ -74,6 +72,8 @@ export const getMany = async (project: string, url: string) => {
query = query.where('isOrderType', '==', false);
}

query = query.where('projects', 'array-contains', project);

if (body.startAfter) {
const startAfter = getSnapshot(
body.collection,
Expand Down
4 changes: 2 additions & 2 deletions packages/api/src/getManyAdvanced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ export const getManyAdvanced = async (project: string, url: string) => {
const { collection, subCollection, uid } = body;
let query = getBaseQuery(collection, uid, subCollection).limit(getQueryLimit(body.collection));

query = query.where(`projects.${project}`, '==', true);

const { filters, operators } = getFilters(body.fieldName, body.fieldValue, body.operator);
try {
for (const [key, values] of Object.entries(filters)) {
Expand All @@ -73,6 +71,8 @@ export const getManyAdvanced = async (project: string, url: string) => {
query = query.where('hidden', '==', false);
}

query = query.where('projects', 'array-contains', project);

const typeFilters = filters['type'];
if (
body.collection === PublicCollections.TRANSACTION &&
Expand Down
3 changes: 2 additions & 1 deletion packages/api/src/getUpdatedAfter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export const getUpdatedAfter = async (project: string, url: string) => {
.collection(baseCollectionPath as COL)
.where('updatedOn', '>=', updatedAfter.toDate())
.orderBy('updatedOn')
.where(`projects.${project}`, '==', true)
.limit(getQueryLimit(body.collection));

if (body.collection === PublicCollections.NFT) {
Expand All @@ -49,6 +48,8 @@ export const getUpdatedAfter = async (project: string, url: string) => {
query = query.where('isOrderType', '==', false);
}

query = query.where('projects', 'array-contains', project);

if (body.startAfter) {
const startAfter = await getSnapshot(baseCollectionPath as COL, body.startAfter);
query = query.startAfter(startAfter);
Expand Down
99 changes: 56 additions & 43 deletions packages/api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require('dotenv').config({ path: __dirname + '/.env' });
import { ApiRoutes } from '@build-5/interfaces';
import cors from 'cors';
import express from 'express';
import http from 'http';
import jwt from 'jsonwebtoken';
import { get } from 'lodash';
import { Observable, first } from 'rxjs';
Expand All @@ -26,12 +26,17 @@ const app = express();

app.use(cors());

app.get('/*', (req, res) => onConnection(req, res));
app.get('/*', async (req, res) => {
const jwtToken = req.headers.authorization?.split(' ')[1];
const url = new URL(req.protocol + '://' + req.get('host') + req.originalUrl);
url.searchParams.append('token', jwtToken || '');
await onConnection(url, res);
});

const wsServer = new ws.Server({ noServer: true });

wsServer.on('connection', async (socket, request) => {
onConnection(request, socket);
wsServer.on('connection', async (socket, req) => {
onConnection(new URL(`ws://${req.headers.host}${req.url}`), socket);
});

const server = app.listen(port);
Expand All @@ -44,13 +49,12 @@ server.on('upgrade', (request, socket, head) => {
});
});

const onConnection = async (
req: express.Request | http.IncomingMessage,
res: express.Response | ws.WebSocket,
) => {
const onConnection = async (url: URL, res: express.Response | ws.WebSocket) => {
try {
const project = getProjectId(req);
const observable = await getObservable(project, req.url || '');
const project = getProjectId(url);
url.searchParams.delete('token');

const observable = await getObservable(project, url.href);
if (res instanceof ws.WebSocket) {
sendLiveUpdates(res, observable);
return;
Expand All @@ -69,43 +73,52 @@ const onConnection = async (
};

const getObservable = (project: string, url: string): Promise<Observable<unknown>> => {
const route = url.replace('/api', '').split('?')[0];
switch (route) {
case ApiRoutes.GET_BY_ID:
return getById(url);
case ApiRoutes.GET_MANY_BY_ID:
return getManyById(url);
case ApiRoutes.GET_MANY:
return getMany(project, url);
case ApiRoutes.GET_MANY_ADVANCED:
return getManyAdvanced(project, url);
case ApiRoutes.GET_UPDATED_AFTER:
return getUpdatedAfter(project, url);
case ApiRoutes.GET_TOKEN_PRICE:
return getTokenPrice(url);
case ApiRoutes.GET_AVG_PRICE:
return getAvgPrice(url);
case ApiRoutes.GET_PRICE_CHANGE:
return getPriceChange(url);
case ApiRoutes.GET_ADDRESSES:
return getAddresses(url);
case ApiRoutes.GET_TOP_MILESTONES:
return getTopMilestones(url);
case ApiRoutes.GET_NFT_MUTABLE_METADATA:
return getNftMutableMetadata(url);
case ApiRoutes.GET_NFT_IDS:
return getNftIds(url);
case ApiRoutes.GET_NFT_MUTABLE_METADATA_HISTORY:
return getNftMutableMetadataHistory(url);
default:
throw { code: 400, message: 'Invalid route' };
if (url.includes(ApiRoutes.GET_BY_ID)) {
return getById(url);
}
if (url.includes(ApiRoutes.GET_MANY_BY_ID)) {
return getManyById(url);
}
if (url.includes(ApiRoutes.GET_MANY)) {
return getMany(project, url);
}
if (url.includes(ApiRoutes.GET_MANY_ADVANCED)) {
return getManyAdvanced(project, url);
}
if (url.includes(ApiRoutes.GET_UPDATED_AFTER)) {
return getUpdatedAfter(project, url);
}
if (url.includes(ApiRoutes.GET_TOKEN_PRICE)) {
return getTokenPrice(url);
}
if (url.includes(ApiRoutes.GET_AVG_PRICE)) {
return getAvgPrice(url);
}
if (url.includes(ApiRoutes.GET_PRICE_CHANGE)) {
return getPriceChange(url);
}
if (url.includes(ApiRoutes.GET_ADDRESSES)) {
return getAddresses(url);
}
if (url.includes(ApiRoutes.GET_TOP_MILESTONES)) {
return getTopMilestones(url);
}
if (url.includes(ApiRoutes.GET_NFT_MUTABLE_METADATA)) {
return getNftMutableMetadata(url);
}
if (url.includes(ApiRoutes.GET_NFT_IDS)) {
return getNftIds(url);
}
if (url.includes(ApiRoutes.GET_NFT_MUTABLE_METADATA_HISTORY)) {
return getNftMutableMetadataHistory(url);
}
throw { code: 400, message: 'Invalid route' };
};

const getProjectId = (req: express.Request | http.IncomingMessage) => {
const getProjectId = (url: URL) => {
try {
const jwtToken = req.headers.authorization?.split(' ')[1];
const payload = jwt.verify(jwtToken || '', 'asdas#@#@xdas31sad');
const jwtToken = url.searchParams.get('token');
const payload = jwt.verify(jwtToken || '', process.env.JWT_SECRET!);
const project = get(payload, 'project', '');
if (!project) {
throw { code: 401, message: 'Unauthorized' };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const getAuctionData = async (db: Firestore, nft: Nft) => {
space: nft.space,
createdBy: nft.owner,
project: nft.owner || SOON_PROJECT_ID,
projects: nft.projects || { [SOON_PROJECT_ID]: true },
projects: nft.projects || [SOON_PROJECT_ID],
auctionFrom: nft.auctionFrom!,
auctionTo: nft.auctionTo!,
auctionFloorPrice: nft.auctionFloorPrice || 0,
Expand Down
6 changes: 2 additions & 4 deletions packages/functions/scripts/dbUpgrades/1.0.0/set.project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const subCollections = [
type DocType = admin.firestore.QueryDocumentSnapshot<admin.firestore.DocumentData> | undefined;
type QuerySnap = admin.firestore.QuerySnapshot<admin.firestore.DocumentData>;

const dataToSet = { project: SOON_PROJECT_ID, projects: { [SOON_PROJECT_ID]: true } };
const dataToSet = { project: SOON_PROJECT_ID, projects: [SOON_PROJECT_ID] };

export const setProjectRoll = async (app: FirebaseApp) => {
const adminApp = app.getInstance() as admin.app.App;
Expand All @@ -57,9 +57,7 @@ export const setProjectRoll = async (app: FirebaseApp) => {

snap.docs.forEach((d) => {
const data = d.data() as BaseRecord;
if (!data.project) {
batch.update(d.ref, dataToSet);
}
batch.update(d.ref, dataToSet);
});

await batch.commit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const creditHighestPayment = async (app: FirebaseApp) => {
const adminDocRef = projectDocRef.collection(SUB_COL.ADMINS).doc(ADMIN_ID);
const admin = {
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
uid: ADMIN_ID,
createdOn: dayjs().toDate(),
parentCol: COL.PROJECT,
Expand Down
2 changes: 1 addition & 1 deletion packages/functions/scripts/manualRefund.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ db.collection(COL.MEMBER)
.doc(tranId)
.set(<Transaction>{
project: '',
projects: {},
projects: [],
type: TransactionType.CREDIT,
uid: tranId,
space: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const createProjectControl = async ({ owner, params }: Context<ProjectCre
const adminDocRef = projectDocRef.collection(SUB_COL.ADMINS).doc(owner);
const admin: ProjectAdmin = {
project: projectData.uid,
projects: { [projectData.uid]: true },
projects: [projectData.uid],
uid: owner,
createdOn: dateToTimestamp(dayjs()),
parentCol: COL.PROJECT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const getClaimableDrops = async (token: string, member: string) => {
}
const drop: TokenDrop = {
project: '',
projects: {},
projects: [],
uid: getRandomEthAddress(),
member,
token,
Expand Down
6 changes: 2 additions & 4 deletions packages/functions/src/utils/common.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
SUB_COL,
WenError,
} from '@build-5/interfaces';
import { uniq } from 'lodash';
import { invalidArgument } from './error.utils';

const MAX_RERUNS = 10;
Expand Down Expand Up @@ -70,9 +71,6 @@ export const assertIsProjectAdmin = async (project: string, member: string) => {
export const getProject = (data: BaseRecord | undefined) => data?.project || SOON_PROJECT_ID;

export const getProjects = (data: (BaseRecord | undefined)[], project?: string) =>
data.reduce(
(acc, act) => ({ ...acc, ...(act?.projects || {}) }),
project ? { [project]: true } : {},
);
data.reduce((acc, act) => uniq({ ...acc, ...(act?.projects || []) }), project ? [project] : []);

export const intToU32 = (value: number) => value & 0xffffffff;
4 changes: 2 additions & 2 deletions packages/functions/test/controls/collection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ describe('Collection trigger test', () => {
const collection = {
...dummyCollection('', 0.1),
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
uid: wallet.getRandomEthAddress(),
};
await build5Db().doc(`${COL.COLLECTION}/${collection.uid}`).create(collection);
Expand All @@ -400,7 +400,7 @@ describe('Collection trigger test', () => {
batch.create(build5Db().doc(`${COL.NFT}/${id}`), {
...dummyNft(chunkIndex * 500 + index, id, collection.uid),
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
});
});
await batch.commit();
Expand Down
6 changes: 3 additions & 3 deletions packages/functions/test/controls/member.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('MemberController: ' + WEN_FUNC.updateMember, () => {
it('Should set nft as avatar, then unset', async () => {
const nft = {
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
uid: wallet.getRandomEthAddress(),
media: MEDIA,
owner: dummyAddress,
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('MemberController: ' + WEN_FUNC.updateMember, () => {
it('Should set nft as avatar, when available field is missing', async () => {
const nft = {
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
uid: wallet.getRandomEthAddress(),
media: MEDIA,
owner: dummyAddress,
Expand All @@ -132,7 +132,7 @@ describe('MemberController: ' + WEN_FUNC.updateMember, () => {

const nft = {
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
uid: wallet.getRandomEthAddress(),
media: MEDIA,
};
Expand Down
4 changes: 2 additions & 2 deletions packages/functions/test/controls/order.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ describe('Ordering flows', () => {

let badge = {
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
member,
type: TransactionType.AWARD,
uid: wallet.getRandomEthAddress(),
Expand All @@ -493,7 +493,7 @@ describe('Ordering flows', () => {

badge = {
project: SOON_PROJECT_ID,
projects: { [SOON_PROJECT_ID]: true },
projects: [SOON_PROJECT_ID],
member,
type: TransactionType.AWARD,
uid: wallet.getRandomEthAddress(),
Expand Down
Loading

0 comments on commit 3ca4588

Please sign in to comment.