diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index c775eac8e..6407a65f6 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -4,7 +4,7 @@ import dotenv from 'dotenv' dotenv.config() const constants = { - DB_VERSION: '0014-drop_unused_tables_with_data', + DB_VERSION: '0015-admin_pending_creations', } const server = { diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 45bee0d77..e9c5c6c69 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -10,7 +10,6 @@ import { UpdatePendingCreation } from '../model/UpdatePendingCreation' import { RIGHTS } from '../../auth/RIGHTS' import { TransactionRepository } from '../../typeorm/repository/Transaction' import { TransactionCreationRepository } from '../../typeorm/repository/TransactionCreation' -import { LoginPendingTasksAdminRepository } from '../../typeorm/repository/LoginPendingTasksAdmin' import { UserRepository } from '../../typeorm/repository/User' import CreatePendingCreationArgs from '../arg/CreatePendingCreationArgs' import UpdatePendingCreationArgs from '../arg/UpdatePendingCreationArgs' @@ -23,7 +22,7 @@ import { UserTransactionRepository } from '../../typeorm/repository/UserTransact import { BalanceRepository } from '../../typeorm/repository/Balance' import { calculateDecay } from '../../util/decay' import { LoginUserRepository } from '../../typeorm/repository/LoginUser' -import { LoginPendingTasksAdmin } from '@entity/LoginPendingTasksAdmin' +import { AdminPendingCreation } from '@entity/AdminPendingCreation' @Resolver() export class AdminResolver { @@ -68,16 +67,15 @@ export class AdminResolver { const creations = await getUserCreations(user.id) const creationDateObj = new Date(creationDate) if (isCreationValid(creations, amount, creationDateObj)) { - const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository) - const loginPendingTaskAdmin = loginPendingTasksAdminRepository.create() - loginPendingTaskAdmin.userId = user.id - loginPendingTaskAdmin.amount = BigInt(amount * 10000) - loginPendingTaskAdmin.created = new Date() - loginPendingTaskAdmin.date = creationDateObj - loginPendingTaskAdmin.memo = memo - loginPendingTaskAdmin.moderator = moderator + const adminPendingCreation = AdminPendingCreation.create() + adminPendingCreation.userId = user.id + adminPendingCreation.amount = BigInt(amount * 10000) + adminPendingCreation.created = new Date() + adminPendingCreation.date = creationDateObj + adminPendingCreation.memo = memo + adminPendingCreation.moderator = moderator - await loginPendingTasksAdminRepository.save(loginPendingTaskAdmin) + await AdminPendingCreation.save(adminPendingCreation) } return getUserCreations(user.id) } @@ -116,8 +114,7 @@ export class AdminResolver { const userRepository = getCustomRepository(UserRepository) const user = await userRepository.findByEmail(email) - const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository) - const pendingCreationToUpdate = await loginPendingTasksAdminRepository.findOneOrFail({ id }) + const pendingCreationToUpdate = await AdminPendingCreation.findOneOrFail({ id }) if (pendingCreationToUpdate.userId !== user.id) { throw new Error('user of the pending creation and send user does not correspond') @@ -137,7 +134,7 @@ export class AdminResolver { pendingCreationToUpdate.date = new Date(creationDate) pendingCreationToUpdate.moderator = moderator - await loginPendingTasksAdminRepository.save(pendingCreationToUpdate) + await AdminPendingCreation.save(pendingCreationToUpdate) const result = new UpdatePendingCreation() result.amount = parseInt(amount.toString()) result.memo = pendingCreationToUpdate.memo @@ -151,8 +148,7 @@ export class AdminResolver { @Authorized([RIGHTS.SEARCH_PENDING_CREATION]) @Query(() => [PendingCreation]) async getPendingCreations(): Promise { - const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository) - const pendingCreations = await loginPendingTasksAdminRepository.find() + const pendingCreations = await AdminPendingCreation.find() const pendingCreationsPromise = await Promise.all( pendingCreations.map(async (pendingCreation) => { @@ -179,18 +175,15 @@ export class AdminResolver { @Authorized([RIGHTS.DELETE_PENDING_CREATION]) @Mutation(() => Boolean) async deletePendingCreation(@Arg('id') id: number): Promise { - const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository) - const entity = await loginPendingTasksAdminRepository.findOneOrFail(id) - const res = await loginPendingTasksAdminRepository.delete(entity) + const entity = await AdminPendingCreation.findOneOrFail(id) + const res = await AdminPendingCreation.delete(entity) return !!res } @Authorized([RIGHTS.CONFIRM_PENDING_CREATION]) @Mutation(() => Boolean) async confirmPendingCreation(@Arg('id') id: number, @Ctx() context: any): Promise { - const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository) - const pendingCreation = await loginPendingTasksAdminRepository.findOneOrFail(id) - + const pendingCreation = await AdminPendingCreation.findOneOrFail(id) const userRepository = getCustomRepository(UserRepository) const moderatorUser = await userRepository.findByPubkeyHex(context.pubKey) if (moderatorUser.id === pendingCreation.userId) @@ -251,7 +244,7 @@ export class AdminResolver { userBalance.modified = receivedCallDate userBalance.recordDate = receivedCallDate await balanceRepository.save(userBalance) - await loginPendingTasksAdminRepository.delete(pendingCreation) + await AdminPendingCreation.delete(pendingCreation) return true } @@ -280,12 +273,12 @@ async function getUserCreations(id: number): Promise { .orderBy('target_month', 'ASC') .getRawMany() - const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository) - const pendingAmountsQuery = await loginPendingTasksAdminRepository - .createQueryBuilder('login_pending_tasks_admin') - .select('MONTH(login_pending_tasks_admin.date)', 'target_month') - .addSelect('SUM(login_pending_tasks_admin.amount)', 'sum') - .where('login_pending_tasks_admin.userId = :id', { id }) + const pendingAmountsQuery = await AdminPendingCreation.createQueryBuilder( + 'admin_pending_creations', + ) + .select('MONTH(admin_pending_creations.date)', 'target_month') + .addSelect('SUM(admin_pending_creations.amount)', 'sum') + .where('admin_pending_creations.userId = :id', { id }) .andWhere({ date: Raw((alias) => `${alias} >= :date and ${alias} < :endDate`, { date: dateBeforeLastMonth, @@ -336,7 +329,7 @@ async function getUserCreations(id: number): Promise { ] } -function updateCreations(creations: number[], pendingCreation: LoginPendingTasksAdmin): number[] { +function updateCreations(creations: number[], pendingCreation: AdminPendingCreation): number[] { const dateMonth = moment().format('YYYY-MM') const dateLastMonth = moment().subtract(1, 'month').format('YYYY-MM') const dateBeforeLastMonth = moment().subtract(2, 'month').format('YYYY-MM') diff --git a/backend/src/typeorm/repository/LoginPendingTasksAdmin.ts b/backend/src/typeorm/repository/LoginPendingTasksAdmin.ts deleted file mode 100644 index 21c2b7a33..000000000 --- a/backend/src/typeorm/repository/LoginPendingTasksAdmin.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { EntityRepository, Repository } from '@dbTools/typeorm' -import { LoginPendingTasksAdmin } from '@entity/LoginPendingTasksAdmin' - -@EntityRepository(LoginPendingTasksAdmin) -export class LoginPendingTasksAdminRepository extends Repository {} diff --git a/database/entity/0015-admin_pending_creations/AdminPendingCreation.ts b/database/entity/0015-admin_pending_creations/AdminPendingCreation.ts new file mode 100644 index 000000000..1c3027867 --- /dev/null +++ b/database/entity/0015-admin_pending_creations/AdminPendingCreation.ts @@ -0,0 +1,25 @@ +import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm' + +@Entity('admin_pending_creations') +export class AdminPendingCreation extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ unsigned: true, nullable: false }) + userId: number + + @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + created: Date + + @Column({ type: 'datetime', nullable: false }) + date: Date + + @Column({ length: 256, nullable: true, default: null }) + memo: string + + @Column({ type: 'bigint', nullable: false }) + amount: BigInt + + @Column() + moderator: number +} diff --git a/database/entity/AdminPendingCreation.ts b/database/entity/AdminPendingCreation.ts new file mode 100644 index 000000000..03eeab883 --- /dev/null +++ b/database/entity/AdminPendingCreation.ts @@ -0,0 +1 @@ +export { AdminPendingCreation } from './0015-admin_pending_creations/AdminPendingCreation' diff --git a/database/entity/LoginPendingTasksAdmin.ts b/database/entity/LoginPendingTasksAdmin.ts deleted file mode 100644 index f766b74dd..000000000 --- a/database/entity/LoginPendingTasksAdmin.ts +++ /dev/null @@ -1 +0,0 @@ -export { LoginPendingTasksAdmin } from './0005-admin_tables/LoginPendingTasksAdmin' diff --git a/database/entity/index.ts b/database/entity/index.ts index 8ecc447cc..b1aa63daf 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -12,9 +12,10 @@ import { TransactionSendCoin } from './TransactionSendCoin' import { User } from './User' import { UserSetting } from './UserSetting' import { UserTransaction } from './UserTransaction' -import { LoginPendingTasksAdmin } from './LoginPendingTasksAdmin' +import { AdminPendingCreation } from './AdminPendingCreation' export const entities = [ + AdminPendingCreation, Balance, LoginElopageBuys, LoginEmailOptIn, @@ -29,5 +30,4 @@ export const entities = [ User, UserSetting, UserTransaction, - LoginPendingTasksAdmin, ] diff --git a/database/migrations/0015-admin_pending_creations.ts b/database/migrations/0015-admin_pending_creations.ts new file mode 100644 index 000000000..d15bd84a7 --- /dev/null +++ b/database/migrations/0015-admin_pending_creations.ts @@ -0,0 +1,35 @@ +/* MIGRATION TO PROPERLY STORE PENDING CREATIONS + * + * There were two tables for the pending tasks, + * since the login_server used some crypto to store its + * tasks there. It was easier to create a new table. + * This migration drops the old unused table and renames + * the new table to properly describe what it does + */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // drop duplicate table, it was unused + await queryFn('DROP TABLE `login_pending_tasks`;') + + // rename the new pending creations table to a proper table name + await queryFn('RENAME TABLE `login_pending_tasks_admin` TO `admin_pending_creations`;') +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('RENAME TABLE `admin_pending_creations` TO `login_pending_tasks_admin`;') + await queryFn(` + CREATE TABLE \`login_pending_tasks\` ( + \`id\` int(10) unsigned NOT NULL AUTO_INCREMENT, + \`user_id\` int(10) unsigned DEFAULT 0, + \`request\` varbinary(2048) NOT NULL, + \`created\` datetime NOT NULL, + \`finished\` datetime DEFAULT '2000-01-01 00:00:00', + \`result_json\` text DEFAULT NULL, + \`param_json\` text DEFAULT NULL, + \`task_type_id\` int(10) unsigned NOT NULL, + \`child_pending_task_id\` int(10) unsigned DEFAULT 0, + \`parent_pending_task_id\` int(10) unsigned DEFAULT 0, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB AUTO_INCREMENT=795 DEFAULT CHARSET=utf8mb4 + `) +}