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

bot/modules/dispute: convert to TS #624

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
23 changes: 17 additions & 6 deletions bot/modules/dispute/actions.js → bot/modules/dispute/actions.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
const { User, Order, Dispute } = require('../../../models');
const messages = require('./messages');
const { validateAdmin } = require('../../validations');
import { User, Order, Dispute } from '../../../models';
import { MainContext } from '../../start';
import * as messages from './messages';
import { validateAdmin } from '../../validations';
const globalMessages = require('../../messages');

exports.takeDispute = async ctx => {
const tgId = ctx.update.callback_query.from.id;
export const takeDispute = async (ctx: MainContext) : Promise<void> => {
const tgId: string = (ctx.update as any).callback_query.from.id;
const admin = await validateAdmin(ctx, tgId);
if (!admin) return;
const orderId = ctx.match[1];
const orderId = ctx.match?.[1];
// We check if this is a solver, the order must be from the same community
const order = await Order.findOne({ _id: orderId });
if(order === null)
throw new Error("order not found");
const dispute = await Dispute.findOne({ order_id: orderId });
if(dispute === null)
throw new Error("dispute not found");
if (!admin.admin) {
if (!order.community_id)
return await globalMessages.notAuthorized(ctx, tgId);
Expand All @@ -20,11 +25,17 @@ exports.takeDispute = async ctx => {
}
ctx.deleteMessage();
const solver = await User.findOne({ tg_id: tgId });
if(solver === null)
throw new Error("solver not found");
if (dispute.status === 'RELEASED')
return await messages.sellerReleased(ctx, solver);

const buyer = await User.findOne({ _id: order.buyer_id });
if(buyer === null)
throw new Error("buyer not found");
const seller = await User.findOne({ _id: order.seller_id });
if(seller === null)
throw new Error("seller not found");
const initiator = order.buyer_dispute ? 'buyer' : 'seller';
const buyerDisputes = await Dispute.count({
$or: [{ buyer_id: buyer._id }, { seller_id: buyer._id }],
Expand Down
60 changes: 35 additions & 25 deletions bot/modules/dispute/commands.js → bot/modules/dispute/commands.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,52 @@
const { User, Dispute, Order } = require('../../../models');
const {
validateParams,
validateObjectId,
validateDisputeOrder,
} = require('../../validations');
const messages = require('./messages');
import { MainContext } from "../../start";

import { User, Dispute, Order } from '../../../models';
import { validateParams, validateObjectId, validateDisputeOrder } from '../../validations';
import * as messages from './messages';
const globalMessages = require('../../messages');
const { logger } = require('../../../logger');
const { removeAtSymbol } = require('../../../util');
import { logger } from '../../../logger';
import { removeAtSymbol } from '../../../util';

const dispute = async ctx => {
const dispute = async (ctx: MainContext) => {
try {
const { user } = ctx;

const [orderId] = await validateParams(ctx, 2, '\\<_order id_\\>');

if (!orderId) return;
const [orderId] = (await validateParams(ctx, 2, '\\<_order id_\\>'))!;

if (!(await validateObjectId(ctx, orderId))) return;
const order = await validateDisputeOrder(ctx, user, orderId);

if (!order) return;
if (order === false) return;
// Users can't initiate a dispute before this time
const secsUntilDispute = parseInt(process.env.DISPUTE_START_WINDOW);
const disputStartWindow = process.env.DISPUTE_START_WINDOW;
if(disputStartWindow === undefined)
throw new Error("DISPUTE_START_WINDOW environment variable not defined");
const secsUntilDispute = parseInt(disputStartWindow);
const time = new Date();
time.setSeconds(time.getSeconds() - secsUntilDispute);
if (order.taken_at > time) {
return await messages.disputeTooSoonMessage(ctx);
}

const buyer = await User.findOne({ _id: order.buyer_id });
if(buyer === null)
throw new Error("buyer was not found");
const seller = await User.findOne({ _id: order.seller_id });
let initiator = 'seller';
if(seller === null)
throw new Error("seller was not found");
let initiator: ('seller' | 'buyer') = 'seller';
if (user._id == order.buyer_id) initiator = 'buyer';

order[`${initiator}_dispute`] = true;
order.previous_dispute_status = order.status;
if(initiator === 'seller')
order.seller_dispute = true;
else
order.buyer_dispute = true;
order.status = 'DISPUTE';
const sellerToken = Math.floor(Math.random() * 899 + 100);
const buyerToken = Math.floor(Math.random() * 899 + 100);
order.buyer_dispute_token = buyerToken;
order.seller_dispute_token = sellerToken;
order.buyer_dispute_token = String(buyerToken);
order.seller_dispute_token = String(sellerToken);
await order.save();

// If this is a non community order, we may ban the user globally
Expand All @@ -54,11 +61,14 @@ const dispute = async ctx => {
(await Dispute.count({
$or: [{ buyer_id: seller._id }, { seller_id: seller._id }],
})) + 1;
if (buyerDisputes >= process.env.MAX_DISPUTES) {
const maxDisputes = Number(process.env.MAX_DISPUTES);
// if MAX_DISPUTES is not specified or can't be parsed as number, following
// maxDisputes will be NaN and following conditions will be false
if (buyerDisputes >= maxDisputes) {
buyer.banned = true;
await buyer.save();
}
if (sellerDisputes >= process.env.MAX_DISPUTES) {
if (sellerDisputes >= maxDisputes) {
seller.banned = true;
await seller.save();
}
Expand All @@ -83,15 +93,15 @@ const dispute = async ctx => {
}
};

const deleteDispute = async ctx => {
const deleteDispute = async (ctx: MainContext) => {
try {
const { admin } = ctx;

let [username, orderId] = await validateParams(
let [username, orderId] = (await validateParams(
ctx,
3,
'\\<_username_\\> \\<_order id_\\>'
);
))!;

if (!username) return;
if (!orderId) return;
Expand Down Expand Up @@ -140,4 +150,4 @@ const deleteDispute = async ctx => {
}
};

module.exports = { dispute, deleteDispute };
export { dispute, deleteDispute };
8 changes: 5 additions & 3 deletions bot/modules/dispute/index.js → bot/modules/dispute/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const commands = require('./commands');
const actions = require('./actions');
import * as commands from './commands';
import * as actions from './actions';
import { Telegraf } from 'telegraf';
import { MainContext } from '../../start';
const { userMiddleware, adminMiddleware } = require('../../middleware/user');

exports.configure = bot => {
export const configure = (bot: Telegraf<MainContext>) => {
bot.command('dispute', userMiddleware, commands.dispute);
bot.command('deldispute', adminMiddleware, commands.deleteDispute);
bot.action(
Expand Down
47 changes: 27 additions & 20 deletions bot/modules/dispute/messages.js → bot/modules/dispute/messages.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
const {
getDisputeChannel,
getDetailedOrder,
sanitizeMD,
} = require('../../../util');
const { logger } = require('../../../logger');
import { getDisputeChannel, getDetailedOrder, sanitizeMD } from '../../../util';
import { logger } from '../../../logger';
import { MainContext } from '../../start';
import { IOrder } from '../../../models/order';
import { UserDocument } from '../../../models/user';

exports.beginDispute = async (ctx, initiator, order, buyer, seller) => {
export const beginDispute = async (
ctx: MainContext,
initiator: ('seller' | 'buyer'),
order: IOrder,
buyer: UserDocument,
seller: UserDocument
) => {
try {
let initiatorUser = buyer;
let counterPartyUser = seller;
Expand Down Expand Up @@ -50,9 +55,11 @@ exports.beginDispute = async (ctx, initiator, order, buyer, seller) => {
}
};

exports.takeDisputeButton = async (ctx, order) => {
export const takeDisputeButton = async (ctx: MainContext, order: IOrder) => {
try {
const disputeChannel = await getDisputeChannel(order);
if(disputeChannel === undefined)
throw new Error("disputeChannel is undefined")
await ctx.telegram.sendMessage(disputeChannel, ctx.i18n.t('new_dispute'), {
reply_markup: {
inline_keyboard: [
Expand All @@ -70,15 +77,15 @@ exports.takeDisputeButton = async (ctx, order) => {
}
};

exports.disputeData = async (
ctx,
buyer,
seller,
order,
initiator,
solver,
buyerDisputes,
sellerDisputes
export const disputeData = async (
ctx: MainContext,
buyer: UserDocument,
seller: UserDocument,
order: IOrder,
initiator: ('seller' | 'buyer'),
solver: UserDocument,
buyerDisputes: any,
sellerDisputes: any
) => {
try {
const type =
Expand Down Expand Up @@ -135,15 +142,15 @@ exports.disputeData = async (
}
};

exports.notFoundDisputeMessage = async ctx => {
export const notFoundDisputeMessage = async (ctx: MainContext) => {
try {
await ctx.reply(ctx.i18n.t('not_found_dispute'));
} catch (error) {
logger.error(error);
}
};

exports.sellerReleased = async (ctx, solver) => {
export const sellerReleased = async (ctx: MainContext, solver: UserDocument) => {
try {
await ctx.telegram.sendMessage(
solver.tg_id,
Expand All @@ -154,7 +161,7 @@ exports.sellerReleased = async (ctx, solver) => {
}
};

exports.disputeTooSoonMessage = async ctx => {
export const disputeTooSoonMessage = async (ctx: MainContext) => {
try {
await ctx.reply(ctx.i18n.t('dispute_too_soon'));
} catch (error) {
Expand Down
4 changes: 2 additions & 2 deletions models/dispute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import mongoose, { Document, Schema } from 'mongoose';

export interface IDispute extends Document {
initiator: string;
seller_id: string;
buyer_id: string;
seller_id: string | null;
buyer_id: string | null;
status: string;
community_id: string;
order_id: string;
Expand Down
Loading