update requirements checking
This commit is contained in:
@@ -4,5 +4,6 @@ export enum Requirement {
|
|||||||
CHAT,
|
CHAT,
|
||||||
CHAT_ADMIN,
|
CHAT_ADMIN,
|
||||||
BOT_CHAT_ADMIN,
|
BOT_CHAT_ADMIN,
|
||||||
REPLY
|
REPLY,
|
||||||
|
SAME_USER
|
||||||
}
|
}
|
||||||
@@ -34,4 +34,8 @@ export class Requirements {
|
|||||||
isRequiresReply(): boolean {
|
isRequiresReply(): boolean {
|
||||||
return this.requirements.includes(Requirement.REPLY);
|
return this.requirements.includes(Requirement.REPLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isRequiresSameUser(): boolean {
|
||||||
|
return this.requirements.includes(Requirement.SAME_USER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
import {CallbackCommand} from "../base/callback-command";
|
import {CallbackCommand} from "../base/callback-command";
|
||||||
import {CallbackQuery} from "typescript-telegram-bot-api";
|
import {CallbackQuery} from "typescript-telegram-bot-api";
|
||||||
import {abortOllamaRequest, bot, getOllamaRequest} from "../index";
|
import {abortOllamaRequest, bot, getOllamaRequest} from "../index";
|
||||||
import {Environment} from "../common/environment";
|
|
||||||
import {logError} from "../util/utils";
|
import {logError} from "../util/utils";
|
||||||
import {MessageStore} from "../common/message-store";
|
import {MessageStore} from "../common/message-store";
|
||||||
import {StoredMessage} from "../model/stored-message";
|
import {StoredMessage} from "../model/stored-message";
|
||||||
|
import {Requirements} from "../base/requirements";
|
||||||
|
import {Requirement} from "../base/requirement";
|
||||||
|
import {Environment} from "../common/environment";
|
||||||
|
|
||||||
const cancelledText = "```Ollama\n❌ Отменено```";
|
const cancelledText = "```Ollama\n❌ Отменено```";
|
||||||
|
|
||||||
@@ -13,6 +15,8 @@ export class OllamaCancel extends CallbackCommand {
|
|||||||
data = "/cancel_ollama";
|
data = "/cancel_ollama";
|
||||||
text = "Cancel Ollama generation";
|
text = "Cancel Ollama generation";
|
||||||
|
|
||||||
|
requirements = Requirements.Build(Requirement.SAME_USER);
|
||||||
|
|
||||||
async execute(query: CallbackQuery): Promise<void> {
|
async execute(query: CallbackQuery): Promise<void> {
|
||||||
const chatId = query.message.chat.id;
|
const chatId = query.message.chat.id;
|
||||||
const fromId = query.from.id;
|
const fromId = query.from.id;
|
||||||
|
|||||||
+88
-37
@@ -1,7 +1,15 @@
|
|||||||
import * as si from "systeminformation";
|
import * as si from "systeminformation";
|
||||||
import {ChatCommand} from "../base/chat-command";
|
import {ChatCommand} from "../base/chat-command";
|
||||||
import {CallbackCommand} from "../base/callback-command";
|
import {CallbackCommand} from "../base/callback-command";
|
||||||
import {CallbackQuery, InlineKeyboardMarkup, Message, ParseMode, PhotoSize, User} from "typescript-telegram-bot-api";
|
import {
|
||||||
|
CallbackQuery,
|
||||||
|
ChatMember,
|
||||||
|
InlineKeyboardMarkup,
|
||||||
|
Message,
|
||||||
|
ParseMode,
|
||||||
|
PhotoSize,
|
||||||
|
User
|
||||||
|
} from "typescript-telegram-bot-api";
|
||||||
import {Environment} from "../common/environment";
|
import {Environment} from "../common/environment";
|
||||||
import {TelegramError} from "typescript-telegram-bot-api/dist/errors";
|
import {TelegramError} from "typescript-telegram-bot-api/dist/errors";
|
||||||
import {bot, botUser, messageDao, setSystemInfo} from "../index";
|
import {bot, botUser, messageDao, setSystemInfo} from "../index";
|
||||||
@@ -15,6 +23,7 @@ import * as orm from "drizzle-orm";
|
|||||||
import {sql, type SQL} from "drizzle-orm";
|
import {sql, type SQL} from "drizzle-orm";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
import {MessageStore} from "../common/message-store";
|
||||||
|
|
||||||
export const ignore = () => {
|
export const ignore = () => {
|
||||||
};
|
};
|
||||||
@@ -71,70 +80,116 @@ export function searchCallbackCommand(commands: CallbackCommand[], data: string)
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkRequirements(cmd: ChatCommand | null, msg: Message): Promise<boolean> {
|
export async function checkRequirements(cmd: ChatCommand | CallbackCommand | null, msg?: Message, cb?: CallbackQuery): Promise<boolean> {
|
||||||
if (!cmd) return false;
|
if (!cmd) return false;
|
||||||
|
if (!msg && !cb) return false;
|
||||||
|
|
||||||
if (Environment.ONLY_FOR_CREATOR_MODE && msg.from.id !== Environment.CREATOR_ID) return false;
|
const isChatCommand = "title" in cmd;
|
||||||
|
const isCallbackCommand = "data" in cmd;
|
||||||
|
let title: string;
|
||||||
|
|
||||||
const fromId = msg.from?.id || -1;
|
if (isChatCommand) {
|
||||||
|
title = cmd.title;
|
||||||
|
} else if (isCallbackCommand) {
|
||||||
|
title = cmd.data;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cbId = cb?.id;
|
||||||
|
const chatId = msg?.chat?.id || cb?.message?.chat?.id || -1;
|
||||||
|
const messageId = msg?.message_id || cb?.message?.message_id || -1;
|
||||||
|
const fromId = msg?.from?.id || cb?.from?.id || -1;
|
||||||
|
const chatType = msg?.chat?.type || cb?.message?.chat?.type || null;
|
||||||
|
|
||||||
|
if (chatId === -1 || messageId === -1 || fromId === -1 || !chatType) return false;
|
||||||
|
|
||||||
|
if (Environment.ONLY_FOR_CREATOR_MODE && fromId !== Environment.CREATOR_ID) return false;
|
||||||
|
|
||||||
if (Environment.CHAT_IDS_WHITELIST.size > 0 &&
|
if (Environment.CHAT_IDS_WHITELIST.size > 0 &&
|
||||||
!Environment.CHAT_IDS_WHITELIST.has(msg.chat.id) &&
|
!Environment.CHAT_IDS_WHITELIST.has(chatId) &&
|
||||||
!Environment.ADMIN_IDS.has(msg.chat.id) &&
|
!Environment.ADMIN_IDS.has(chatId) &&
|
||||||
!Environment.ADMIN_IDS.has(msg.from.id)) {
|
!Environment.ADMIN_IDS.has(fromId)) {
|
||||||
console.log(`${cmd.title}: chatId whitelist ignored.`);
|
console.log(`${title}: chatId whitelist ignored.`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const reqs = cmd.requirements;
|
const reqs = cmd.requirements;
|
||||||
if (!reqs) return true;
|
if (!reqs) return true;
|
||||||
|
|
||||||
|
const notifyUser = async (text: string) => {
|
||||||
|
if (msg) {
|
||||||
|
await replyToMessage({chat_id: chatId, message_id: messageId, text: text});
|
||||||
|
} else if (cb) {
|
||||||
|
await bot.answerCallbackQuery({
|
||||||
|
callback_query_id: cbId,
|
||||||
|
text: text,
|
||||||
|
cache_time: 0,
|
||||||
|
show_alert: true
|
||||||
|
}).catch(logError);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (reqs.isRequiresBotCreator() && fromId !== Environment.CREATOR_ID) {
|
if (reqs.isRequiresBotCreator() && fromId !== Environment.CREATOR_ID) {
|
||||||
console.log(`${cmd.title}: creatorId is bad`);
|
console.log(`${title}: creatorId is bad`);
|
||||||
await oldReplyToMessage(msg, "Вы не являетесь создателем бота.");
|
await notifyUser("Вы не являетесь создателем бота.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reqs.isRequiresBotAdmin() && !Environment.ADMIN_IDS.has(fromId)) {
|
if (reqs.isRequiresBotAdmin() && !Environment.ADMIN_IDS.has(fromId)) {
|
||||||
console.log(`${cmd.title}: adminId is bad`);
|
console.log(`${title}: adminId is bad`);
|
||||||
await oldReplyToMessage(msg, "Вы не являетесь администратором бота.");
|
await notifyUser("Вы не являетесь администратором бота.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reqs.isRequiresChat() && msg.chat.type === "private") {
|
if (reqs.isRequiresChat() && msg.chat.type === "private") {
|
||||||
console.log(`${cmd.title}: chatId is bad`);
|
console.log(`${title}: chatId is bad`);
|
||||||
await oldReplyToMessage(msg, "Тут Вам не чат.");
|
await notifyUser("Тут Вам не чат.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reqs.isRequiresChatAdmin()) {
|
if (reqs.isRequiresChatAdmin()) {
|
||||||
const member = await bot.getChatMember({chat_id: msg.chat.id, user_id: msg.from.id});
|
const member = await bot.getChatMember({chat_id: chatId, user_id: fromId});
|
||||||
const isAdmin = member.status === "administrator" || member.status === "creator";
|
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isMemberAdmin(member)) {
|
||||||
console.log(`${cmd.title}: chatAdminId is bad`);
|
console.log(`${title}: chatAdminId is bad`);
|
||||||
await oldReplyToMessage(msg, "Вы не являетесь администратором чата.");
|
await notifyUser("Вы не являетесь администратором чата.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reqs.isRequiresBotChatAdmin() && msg.chat.type !== "private") {
|
if (reqs.isRequiresBotChatAdmin() && chatType !== "private") {
|
||||||
const member = await bot.getChatMember({chat_id: msg.chat.id, user_id: botUser.id});
|
const member = await bot.getChatMember({chat_id: chatId, user_id: botUser.id});
|
||||||
const isAdmin = member.status === "administrator" || member.status === "creator";
|
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isMemberAdmin(member)) {
|
||||||
console.log(`${cmd.title}: botChatAdminId is bad`);
|
console.log(`${title}: botChatAdminId is bad`);
|
||||||
await oldReplyToMessage(msg, "Бот не является администратором чата.");
|
await notifyUser("Бот не является администратором чата.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reqs.isRequiresReply() && !msg.reply_to_message) {
|
if (reqs.isRequiresReply() && !msg?.reply_to_message) {
|
||||||
console.log(`${cmd.title}: replyMessage is bad`);
|
console.log(`${title}: replyMessage is bad`);
|
||||||
await oldReplyToMessage(msg, "Отсутствует ответ на сообщение.");
|
await notifyUser("Отсутствует ответ на сообщение.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reqs.isRequiresSameUser()) {
|
||||||
|
let originalFromId: number | null;
|
||||||
|
try {
|
||||||
|
originalFromId = (await MessageStore.get(chatId, messageId))?.fromId;
|
||||||
|
} catch (e) {
|
||||||
|
logError(e);
|
||||||
|
originalFromId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (originalFromId && fromId !== originalFromId && fromId !== Environment.CREATOR_ID) {
|
||||||
|
console.log(`${title}: sameUser is bad`);
|
||||||
|
await notifyUser("Только автор оригинального сообщения может выполнить это действие.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,20 +203,12 @@ export async function executeChatCommand(cmd: ChatCommand | null, msg: Message,
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function findAndExecuteCallbackCommand(commands: CallbackCommand[], query: CallbackQuery): Promise<boolean> {
|
export async function findAndExecuteCallbackCommand(commands: CallbackCommand[], query: CallbackQuery): Promise<boolean> {
|
||||||
const fromId = query.from.id;
|
|
||||||
const data = query.data || "";
|
const data = query.data || "";
|
||||||
|
|
||||||
const cmd = searchCallbackCommand(commands, data);
|
const cmd = searchCallbackCommand(commands, data);
|
||||||
if (!cmd) return false;
|
if (!cmd) return false;
|
||||||
|
|
||||||
// TODO: 15/01/2026, Danil Nikolaev: reimplement
|
if (!await checkRequirements(cmd, null, query)) return false;
|
||||||
const requirements = cmd.requirements;
|
|
||||||
if (requirements) {
|
|
||||||
if (requirements.isRequiresBotAdmin() && !Environment.ADMIN_IDS.has(fromId)) {
|
|
||||||
console.log(`${cmd.data}: adminId is bad: ${fromId}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await cmd.execute(query);
|
await cmd.execute(query);
|
||||||
await cmd.answerCallbackQuery(query);
|
await cmd.answerCallbackQuery(query);
|
||||||
@@ -312,6 +359,10 @@ export function fullName(from: User): string {
|
|||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isMemberAdmin(member: ChatMember): boolean {
|
||||||
|
return member.status === "administrator" || member.status === "creator";
|
||||||
|
}
|
||||||
|
|
||||||
export function getUptime(): string {
|
export function getUptime(): string {
|
||||||
const processUptime = Math.ceil(process.uptime());
|
const processUptime = Math.ceil(process.uptime());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user