From da49e47bf9aad6fc95a5ce300f2821ddccfe33d3 Mon Sep 17 00:00:00 2001 From: Kurtis Assad Date: Wed, 7 Feb 2024 09:14:32 -0800 Subject: [PATCH] Fixed communityStakes so that they are non-modifiable (#6541) --- .../api/communityStake/editCommunityStake.ts | 2 +- .../server_communities_controller.ts | 23 ++++---- ...ity_stake.ts => create_community_stake.ts} | 23 +++++--- ....ts => create_community_stakes_handler.ts} | 6 +- .../commonwealth/server/routing/router.ts | 6 +- .../integration/api/communityStake.spec.ts | 55 +++++++++---------- 6 files changed, 61 insertions(+), 54 deletions(-) rename packages/commonwealth/server/controllers/server_communities_methods/{put_community_stake.ts => create_community_stake.ts} (63%) rename packages/commonwealth/server/routes/communities/{put_community_stakes_handler.ts => create_community_stakes_handler.ts} (91%) diff --git a/packages/commonwealth/client/scripts/state/api/communityStake/editCommunityStake.ts b/packages/commonwealth/client/scripts/state/api/communityStake/editCommunityStake.ts index 53a41c1b1d3..b0dce318265 100644 --- a/packages/commonwealth/client/scripts/state/api/communityStake/editCommunityStake.ts +++ b/packages/commonwealth/client/scripts/state/api/communityStake/editCommunityStake.ts @@ -11,7 +11,7 @@ const editCommunityStake = async ({ communityId, stakeId, }: EditCommunityStakeProps) => { - return await axios.put( + return await axios.post( `${app.serverUrl()}/communityStakes/${communityId}/${stakeId}`, { jwt: app.user.jwt, diff --git a/packages/commonwealth/server/controllers/server_communities_controller.ts b/packages/commonwealth/server/controllers/server_communities_controller.ts index a4e432edb04..56bcda4d918 100644 --- a/packages/commonwealth/server/controllers/server_communities_controller.ts +++ b/packages/commonwealth/server/controllers/server_communities_controller.ts @@ -1,4 +1,8 @@ -import { DB, TokenBalanceCache } from '@hicommonwealth/model'; +import { + CommunityStakeAttributes, + DB, + TokenBalanceCache, +} from '@hicommonwealth/model'; import BanCache from '../util/banCheckCache'; import { CreateChainNodeOptions, @@ -10,6 +14,10 @@ import { CreateCommunityResult, __createCommunity, } from './server_communities_methods/create_community'; +import { + PostCommunityStakeOptions, + __createCommunityStake, +} from './server_communities_methods/create_community_stake'; import { DeleteCommunityOptions, DeleteCommunityResult, @@ -35,11 +43,6 @@ import { GetRelatedCommunitiesResult, __getRelatedCommunities, } from './server_communities_methods/get_related_communities'; -import { - PutCommunityStakeOptions, - PutCommunityStakeResult, - __putCommunityStake, -} from './server_communities_methods/put_community_stake'; import { SearchCommunitiesOptions, SearchCommunitiesResult, @@ -109,10 +112,10 @@ export class ServerCommunitiesController { return __getRelatedCommunities.call(this, options); } - async putCommunityStake( - options: PutCommunityStakeOptions, - ): Promise { - return __putCommunityStake.call(this, options); + async createCommunityStake( + options: PostCommunityStakeOptions, + ): Promise { + return __createCommunityStake.call(this, options); } async getCommunityStake( diff --git a/packages/commonwealth/server/controllers/server_communities_methods/put_community_stake.ts b/packages/commonwealth/server/controllers/server_communities_methods/create_community_stake.ts similarity index 63% rename from packages/commonwealth/server/controllers/server_communities_methods/put_community_stake.ts rename to packages/commonwealth/server/controllers/server_communities_methods/create_community_stake.ts index afd619c1a7a..ca040428dec 100644 --- a/packages/commonwealth/server/controllers/server_communities_methods/put_community_stake.ts +++ b/packages/commonwealth/server/controllers/server_communities_methods/create_community_stake.ts @@ -1,3 +1,4 @@ +import { AppError } from '@hicommonwealth/core'; import { CommunityStakeAttributes, UserInstance } from '@hicommonwealth/model'; import { z } from 'zod'; import { ServerCommunitiesController } from '../server_communities_controller'; @@ -19,20 +20,26 @@ export const SetCommunityStakeBodySchema = z.object({ export type SetCommunityStakeBody = z.infer; -export type PutCommunityStakeOptions = { +export type PostCommunityStakeOptions = { user: UserInstance; communityStake: SetCommunityStakeParams & SetCommunityStakeBody; }; -export type PutCommunityStakeResult = CommunityStakeAttributes; - -export async function __putCommunityStake( +export async function __createCommunityStake( this: ServerCommunitiesController, - { communityStake }: PutCommunityStakeOptions, + { communityStake }: PostCommunityStakeOptions, ): Promise { - const [newCommunityStake] = await this.models.CommunityStake.upsert( - communityStake, - ); + const { community_id, stake_id } = communityStake; + + const [newCommunityStake, created] = + await this.models.CommunityStake.findOrCreate({ + where: { community_id, stake_id }, + defaults: { ...communityStake }, + }); + + if (!created) { + throw new AppError('Community stake already exists'); + } return newCommunityStake; } diff --git a/packages/commonwealth/server/routes/communities/put_community_stakes_handler.ts b/packages/commonwealth/server/routes/communities/create_community_stakes_handler.ts similarity index 91% rename from packages/commonwealth/server/routes/communities/put_community_stakes_handler.ts rename to packages/commonwealth/server/routes/communities/create_community_stakes_handler.ts index 9eed9e87785..91b60240292 100644 --- a/packages/commonwealth/server/routes/communities/put_community_stakes_handler.ts +++ b/packages/commonwealth/server/routes/communities/create_community_stakes_handler.ts @@ -8,7 +8,7 @@ import { SetCommunityStakeBodySchema, SetCommunityStakeParams, SetCommunityStakeParamsSchema, -} from 'server/controllers/server_communities_methods/put_community_stake'; +} from 'server/controllers/server_communities_methods/create_community_stake'; import { z } from 'zod'; import { ServerControllers } from '../../routing/router'; import { TypedRequest, TypedResponse, success } from '../../types'; @@ -20,7 +20,7 @@ type PutCommunityStakesParams = SetCommunityStakeParams; type PutCommunityStakesBody = SetCommunityStakeBody; type PutCommunityStakesResponse = CommunityStakeAttributes; -export const putCommunityStakeHandler = async ( +export const createCommunityStakeHandler = async ( models: DB, controllers: ServerControllers, req: TypedRequest, @@ -76,7 +76,7 @@ export const putCommunityStakeHandler = async ( throw new AppError(formatErrorPretty(bodyValidationResult)); } - const results = await controllers.communities.putCommunityStake({ + const results = await controllers.communities.createCommunityStake({ user, communityStake: { ...paramsValidationResult.data, diff --git a/packages/commonwealth/server/routing/router.ts b/packages/commonwealth/server/routing/router.ts index 5a587a9a16b..f05c213b658 100644 --- a/packages/commonwealth/server/routing/router.ts +++ b/packages/commonwealth/server/routing/router.ts @@ -2,8 +2,8 @@ import type { Express } from 'express'; import express from 'express'; import useragent from 'express-useragent'; import passport from 'passport'; +import { createCommunityStakeHandler } from '../routes/communities/create_community_stakes_handler'; import { getCommunityStakeHandler } from '../routes/communities/get_community_stakes_handler'; -import { putCommunityStakeHandler } from '../routes/communities/put_community_stakes_handler'; import ddd from '../routes/ddd'; import { TokenBalanceCache } from '@hicommonwealth/model'; @@ -382,10 +382,10 @@ function setupRouter( registerRoute( router, - 'put', + 'post', '/communityStakes/:community_id/:stake_id', passport.authenticate('jwt', { session: false }), - putCommunityStakeHandler.bind(this, models, serverControllers), + createCommunityStakeHandler.bind(this, models, serverControllers), ); // ---- diff --git a/packages/commonwealth/test/integration/api/communityStake.spec.ts b/packages/commonwealth/test/integration/api/communityStake.spec.ts index 249349f6802..ef932ef05d1 100644 --- a/packages/commonwealth/test/integration/api/communityStake.spec.ts +++ b/packages/commonwealth/test/integration/api/communityStake.spec.ts @@ -11,7 +11,7 @@ import app from '../../../server-test'; import { JWT_SECRET } from '../../../server/config'; import { ServerCommunitiesController } from '../../../server/controllers/server_communities_controller'; import { buildUser } from '../../unit/unitHelpers'; -import { get, put } from './external/appHook.spec'; +import { get, post } from './external/appHook.spec'; import { testUsers } from './external/dbEntityHooks.spec'; chai.use(chaiHttp); @@ -33,7 +33,7 @@ const expectedCreateResp = { stake_enabled: baseRequest.stake_enabled, }; -describe('PUT communityStakes Tests', () => { +describe('POST communityStakes Tests', () => { beforeEach(async () => { await tester.seedDb(); }); @@ -45,10 +45,11 @@ describe('PUT communityStakes Tests', () => { userAttributes: { email: '', id: 1, isAdmin: true }, }) as UserInstance; - const createResponse = await controller.putCommunityStake({ + const createResponse = await controller.createCommunityStake({ communityStake: baseRequest, user: user, }); + assert.equal(createResponse.community_id, expectedCreateResp.community_id); assert.equal(createResponse.stake_id, expectedCreateResp.stake_id); assert.equal(createResponse.stake_token, expectedCreateResp.stake_token); @@ -58,43 +59,39 @@ describe('PUT communityStakes Tests', () => { expectedCreateResp.stake_enabled, ); - const updateResp = await controller.putCommunityStake({ - communityStake: { ...baseRequest, stake_token: 'temp' }, - user: user, - }); + let error; + try { + // try to change vote weight + await controller.createCommunityStake({ + communityStake: { ...baseRequest, vote_weight: 20 }, + user: user, + }); + } catch (e) { + error = e; + } - const expectedUpdateResp = { - community_id: baseRequest.community_id, - stake_id: baseRequest.stake_id, - stake_token: 'temp', - vote_weight: baseRequest.vote_weight, - stake_enabled: baseRequest.stake_enabled, - }; - - assert.equal(updateResp.community_id, expectedUpdateResp.community_id); - assert.equal(updateResp.stake_id, expectedUpdateResp.stake_id); - assert.equal(updateResp.stake_token, expectedUpdateResp.stake_token); - assert.equal(updateResp.vote_weight, expectedUpdateResp.vote_weight); - assert.equal(updateResp.stake_enabled, expectedUpdateResp.stake_enabled); - - const getResp = await controller.getCommunityStake({ + assert.equal(error.message, 'Community stake already exists'); + + await controller.getCommunityStake({ community_id: baseRequest.community_id, stake_id: baseRequest.stake_id, }); - assert.equal(getResp.community_id, expectedUpdateResp.community_id); - assert.equal(getResp.stake_id, expectedUpdateResp.stake_id); - assert.equal(getResp.stake_token, expectedUpdateResp.stake_token); - assert.equal(getResp.vote_weight, expectedUpdateResp.vote_weight); - assert.equal(getResp.stake_enabled, expectedUpdateResp.stake_enabled); - assert.equal(getResp.Chain.namespace, 'IanSpace'); + assert.equal(createResponse.community_id, expectedCreateResp.community_id); + assert.equal(createResponse.stake_id, expectedCreateResp.stake_id); + assert.equal(createResponse.stake_token, expectedCreateResp.stake_token); + assert.equal(createResponse.vote_weight, expectedCreateResp.vote_weight); + assert.equal( + createResponse.stake_enabled, + expectedCreateResp.stake_enabled, + ); }); it('The community stake routes work correctly', async () => { const jwtToken = jwt.sign({ id: 2, email: testUsers[0].email }, JWT_SECRET); const actualPutResponse = ( - await put( + await post( `/api/communityStakes/${baseRequest.community_id}/${baseRequest.stake_id}`, { ...baseRequest, jwt: jwtToken }, true,