blockmine 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,18 +21,25 @@ const resolvePluginPath = async (req, res, next) => {
21
21
  return res.status(400).json({ error: 'Имя плагина обязательно в пути.' });
22
22
  }
23
23
 
24
- const botPluginsDir = path.join(PLUGINS_BASE_DIR, `bot_${botId}`);
25
- const pluginPath = path.resolve(botPluginsDir, pluginName);
26
-
27
- if (!pluginPath.startsWith(botPluginsDir)) {
28
- return res.status(403).json({ error: 'Доступ запрещен: попытка доступа за пределы директории плагина.' });
24
+ const plugin = await prisma.installedPlugin.findFirst({
25
+ where: {
26
+ botId: parseInt(botId),
27
+ name: pluginName
28
+ }
29
+ });
30
+
31
+ if (!plugin) {
32
+ return res.status(404).json({ error: 'Плагин не найден в базе данных.' });
29
33
  }
30
34
 
35
+ const pluginPath = plugin.path;
36
+
31
37
  if (!await fse.pathExists(pluginPath)) {
32
- return res.status(404).json({ error: 'Директория плагина не найдена.' });
38
+ return res.status(404).json({ error: 'Директория плагина не найдена в файловой системе.' });
33
39
  }
34
40
 
35
41
  req.pluginPath = pluginPath;
42
+ req.pluginData = plugin;
36
43
  next();
37
44
  } catch (error) {
38
45
  console.error('[Plugin IDE Middleware Error]', error);
@@ -297,19 +304,48 @@ router.post('/:pluginName/file', resolvePluginPath, async (req, res) => {
297
304
  if (relativePath === 'package.json' || relativePath.endsWith('/package.json')) {
298
305
  try {
299
306
  const packageJson = JSON.parse(content);
300
- await prisma.installedPlugin.updateMany({
307
+
308
+ const existingPlugin = await prisma.installedPlugin.findFirst({
301
309
  where: {
302
310
  botId: parseInt(req.params.botId),
303
311
  path: req.pluginPath,
304
- },
305
- data: {
306
- name: packageJson.name || req.params.pluginName,
307
- version: packageJson.version || '1.0.0',
308
- description: packageJson.description || '',
309
- manifest: JSON.stringify(packageJson.botpanel || {}),
310
312
  }
311
313
  });
312
- console.log(`[Plugin IDE] Manifest обновлен для плагина ${req.params.pluginName} после сохранения package.json`);
314
+
315
+ if (existingPlugin) {
316
+ const newName = packageJson.name || req.params.pluginName;
317
+
318
+ const conflictingPlugin = await prisma.installedPlugin.findFirst({
319
+ where: {
320
+ botId: parseInt(req.params.botId),
321
+ name: newName,
322
+ id: { not: existingPlugin.id }
323
+ }
324
+ });
325
+
326
+ if (conflictingPlugin) {
327
+ console.warn(`[Plugin IDE] Конфликт имени плагина: ${newName} уже существует для бота ${req.params.botId}`);
328
+ await prisma.installedPlugin.update({
329
+ where: { id: existingPlugin.id },
330
+ data: {
331
+ version: packageJson.version || '1.0.0',
332
+ description: packageJson.description || '',
333
+ manifest: JSON.stringify(packageJson.botpanel || {}),
334
+ }
335
+ });
336
+ } else {
337
+ await prisma.installedPlugin.update({
338
+ where: { id: existingPlugin.id },
339
+ data: {
340
+ name: newName,
341
+ version: packageJson.version || '1.0.0',
342
+ description: packageJson.description || '',
343
+ manifest: JSON.stringify(packageJson.botpanel || {}),
344
+ }
345
+ });
346
+ }
347
+ console.log(`[Plugin IDE] Manifest обновлен для плагина ${req.params.pluginName} после сохранения package.json`);
348
+ }
313
349
  } catch (manifestError) {
314
350
  console.error(`[Plugin IDE] Ошибка обновления manifest для ${req.params.pluginName}:`, manifestError);
315
351
  }
@@ -412,23 +448,50 @@ router.post('/:pluginName/manifest', resolvePluginPath, async (req, res) => {
412
448
 
413
449
  await fse.writeJson(manifestPath, newManifest, { spaces: 2 });
414
450
 
415
- await prisma.installedPlugin.updateMany({
451
+ const existingPlugin = await prisma.installedPlugin.findFirst({
416
452
  where: {
417
453
  botId: parseInt(req.params.botId),
418
454
  path: req.pluginPath,
419
- },
420
- data: {
421
- name: newManifest.name,
422
- version: newManifest.version,
423
- description: newManifest.description,
424
- manifest: JSON.stringify(newManifest.botpanel || {}),
425
455
  }
426
456
  });
457
+
458
+ if (existingPlugin) {
459
+ const conflictingPlugin = await prisma.installedPlugin.findFirst({
460
+ where: {
461
+ botId: parseInt(req.params.botId),
462
+ name: newManifest.name,
463
+ id: { not: existingPlugin.id }
464
+ }
465
+ });
466
+
467
+ if (conflictingPlugin) {
468
+ console.warn(`[Plugin IDE] Конфликт имени плагина: ${newManifest.name} уже существует для бота ${req.params.botId}`);
469
+ await prisma.installedPlugin.update({
470
+ where: { id: existingPlugin.id },
471
+ data: {
472
+ version: newManifest.version,
473
+ description: newManifest.description,
474
+ manifest: JSON.stringify(newManifest.botpanel || {}),
475
+ }
476
+ });
477
+ } else {
478
+ await prisma.installedPlugin.update({
479
+ where: { id: existingPlugin.id },
480
+ data: {
481
+ name: newManifest.name,
482
+ version: newManifest.version,
483
+ description: newManifest.description,
484
+ manifest: JSON.stringify(newManifest.botpanel || {}),
485
+ }
486
+ });
487
+ }
488
+ }
427
489
 
428
490
  res.status(200).json({ message: 'package.json успешно обновлен.' });
429
491
  } catch (error) {
430
492
  console.error(`[Plugin IDE Error] /manifest POST for ${req.params.pluginName}:`, error);
431
- res.status(500).json({ error: 'Не удалось обновить package.json.' });
493
+ // Файл уже сохранен, поэтому возвращаем успех даже если есть ошибка с БД
494
+ res.status(200).json({ message: 'package.json обновлен (возможны проблемы с синхронизацией БД).' });
432
495
  }
433
496
  });
434
497
 
@@ -543,7 +606,21 @@ router.post('/:pluginName/create-pr', resolvePluginPath, async (req, res) => {
543
606
 
544
607
  process.chdir(tempDir);
545
608
 
546
- cp.execSync(`git checkout -b ${branch}`);
609
+ let branchExists = false;
610
+ try {
611
+ cp.execSync(`git ls-remote --heads origin ${branch}`, { stdio: 'pipe' });
612
+ branchExists = true;
613
+ console.log(`[Plugin IDE] Ветка ${branch} уже существует, переключаемся на неё`);
614
+ } catch (e) {
615
+ console.log(`[Plugin IDE] Ветка ${branch} не существует, создаём новую`);
616
+ }
617
+
618
+ if (branchExists) {
619
+ cp.execSync(`git checkout -b ${branch} origin/${branch}`);
620
+ cp.execSync(`git pull origin ${branch}`);
621
+ } else {
622
+ cp.execSync(`git checkout -b ${branch}`);
623
+ }
547
624
 
548
625
  const files = await fse.readdir(req.pluginPath);
549
626
  for (const file of files) {
@@ -564,11 +641,26 @@ router.post('/:pluginName/create-pr', resolvePluginPath, async (req, res) => {
564
641
  throw e;
565
642
  }
566
643
 
567
- cp.execSync(`git push -u origin ${branch}`);
644
+
645
+ if (branchExists) {
646
+ cp.execSync(`git push origin ${branch} --force`);
647
+ console.log(`[Plugin IDE] Ветка ${branch} обновлена`);
648
+ } else {
649
+ cp.execSync(`git push -u origin ${branch}`);
650
+ console.log(`[Plugin IDE] Новая ветка ${branch} создана`);
651
+ }
568
652
 
569
653
  const prUrl = `https://github.com/${repoInfo.owner}/${repoInfo.repo}/pull/new/${branch}`;
570
654
 
571
- res.json({ success: true, prUrl });
655
+ const responseData = {
656
+ success: true,
657
+ prUrl: prUrl,
658
+ isUpdate: branchExists,
659
+ message: branchExists ? 'Существующий PR обновлен' : 'Новый PR создан'
660
+ };
661
+
662
+ console.log(`[Plugin IDE] PR ${branchExists ? 'обновлен' : 'создан'} для плагина ${req.params.pluginName}:`, responseData);
663
+ res.json(responseData);
572
664
 
573
665
  } finally {
574
666
  try {
@@ -12,7 +12,7 @@ const { parseArguments } = require('./system/parseArguments');
12
12
  const GraphExecutionEngine = require('./GraphExecutionEngine');
13
13
  const NodeRegistry = require('./NodeRegistry');
14
14
 
15
- const UserService = require('./ipc/UserService.stub.js');
15
+ const UserService = require('./UserService');
16
16
  const PermissionManager = require('./ipc/PermissionManager.stub.js');
17
17
 
18
18
  let bot = null;
@@ -208,51 +208,7 @@ process.on('message', async (message) => {
208
208
  sendMessage: (type, message, username) => bot.messageQueue.enqueue(type, message, username),
209
209
  sendMessageAndWaitForReply: (command, patterns, timeout) => bot.messageQueue.enqueueAndWait(command, patterns, timeout),
210
210
  getUser: async (username) => {
211
- const userData = await UserService.getUser(username, bot.config.id, bot.config);
212
- if (!userData) return null;
213
-
214
- const permissions = userData.permissionsSet ? Array.from(userData.permissionsSet) : [];
215
-
216
- return {
217
- id: userData.id,
218
- username: userData.username,
219
- isOwner: userData.isOwner,
220
- isBlacklisted: userData.isBlacklisted,
221
- permissions: permissions,
222
- groups: userData.groups,
223
- hasPermission: (permissionName) => {
224
- if (userData.isOwner) return true;
225
- if (!permissionName) return false;
226
-
227
- if (permissions.includes(permissionName)) {
228
- return true;
229
- }
230
-
231
- const permissionParts = permissionName.split('.');
232
- if (permissionParts.length > 1) {
233
- const domain = permissionParts[0];
234
- const wildcard = `${domain}.*`;
235
- if (permissions.includes(wildcard)) {
236
- return true;
237
- }
238
- }
239
-
240
- if (permissions.includes('*')) {
241
- return true;
242
- }
243
-
244
- return false;
245
- },
246
- hasGroup: (groupName) => userData.hasGroup(groupName),
247
- addGroup: (group) => bot.api.performUserAction(username, 'addGroup', { group }),
248
- removeGroup: (group) => bot.api.performUserAction(username, 'removeGroup', { group }),
249
- addPermission: (permission) => bot.api.performUserAction(username, 'addPermission', { permission }),
250
- removePermission: (permission) => bot.api.performUserAction(username, 'removePermission', { permission }),
251
- getGroups: () => bot.api.performUserAction(username, 'getGroups'),
252
- getPermissions: () => bot.api.performUserAction(username, 'getPermissions'),
253
- isBlacklisted: () => bot.api.performUserAction(username, 'isBlacklisted'),
254
- setBlacklisted: (value) => bot.api.performUserAction(username, 'setBlacklisted', { value }),
255
- };
211
+ return await UserService.getUser(username, bot.config.id, bot.config);
256
212
  },
257
213
  registerPermissions: (permissions) => PermissionManager.registerPermissions(bot.config.id, permissions),
258
214
  registerGroup: (groupConfig) => PermissionManager.registerGroup(bot.config.id, groupConfig),