@omnizap-system/omnizap 2.6.1 → 2.6.2

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.
Files changed (156) hide show
  1. package/.env.example +54 -9
  2. package/.github/workflows/ci.yml +3 -3
  3. package/.github/workflows/security-runner-hardening.yml +1 -1
  4. package/.github/workflows/security-zap-full-scan.yml +1 -0
  5. package/app/config/index.js +2 -0
  6. package/app/configParts/adminIdentity.js +5 -5
  7. package/app/configParts/baileysConfig.js +226 -55
  8. package/app/configParts/groupUtils.js +5 -0
  9. package/app/configParts/messagePersistenceService.js +143 -3
  10. package/app/configParts/sessionConfig.js +157 -0
  11. package/app/connection/baileysCompatibility.test.js +1 -1
  12. package/app/connection/groupOwnerWriteStateResolver.js +109 -0
  13. package/app/connection/socketController.js +625 -124
  14. package/app/connection/socketController.multiSession.test.js +108 -0
  15. package/app/controllers/messageController.js +1 -1
  16. package/app/controllers/messagePipeline/commandMiddleware.js +12 -10
  17. package/app/controllers/messagePipeline/conversationMiddleware.js +2 -1
  18. package/app/controllers/messagePipeline/messagePipelineMiddlewares.test.js +104 -0
  19. package/app/controllers/messagePipeline/preProcessingMiddlewares.js +80 -2
  20. package/app/controllers/messageProcessingPipeline.js +88 -9
  21. package/app/controllers/messageProcessingPipeline.test.js +200 -0
  22. package/app/modules/adminModule/AGENT.md +1 -1
  23. package/app/modules/adminModule/commandConfig.json +3318 -1347
  24. package/app/modules/adminModule/groupCommandHandlers.js +856 -14
  25. package/app/modules/adminModule/groupCommandHandlers.test.js +375 -9
  26. package/app/modules/adminModule/groupWarningRepository.js +152 -0
  27. package/app/modules/aiModule/AGENT.md +47 -30
  28. package/app/modules/aiModule/aiConfigRuntime.js +1 -0
  29. package/app/modules/aiModule/catCommand.js +132 -25
  30. package/app/modules/aiModule/commandConfig.json +114 -28
  31. package/app/modules/analyticsModule/messageAnalysisEventRepository.js +54 -6
  32. package/app/modules/gameModule/AGENT.md +1 -1
  33. package/app/modules/gameModule/commandConfig.json +29 -0
  34. package/app/modules/menuModule/AGENT.md +1 -1
  35. package/app/modules/menuModule/commandConfig.json +45 -10
  36. package/app/modules/menuModule/menuCatalogService.js +190 -0
  37. package/app/modules/menuModule/menuCommandUsageRepository.js +109 -0
  38. package/app/modules/menuModule/menuDynamicService.js +511 -0
  39. package/app/modules/menuModule/menuDynamicService.test.js +141 -0
  40. package/app/modules/menuModule/menus.js +36 -5
  41. package/app/modules/playModule/AGENT.md +10 -5
  42. package/app/modules/playModule/commandConfig.json +74 -16
  43. package/app/modules/playModule/playCommandConstants.js +13 -7
  44. package/app/modules/playModule/playCommandCore.js +4 -6
  45. package/app/modules/playModule/{playCommandYtDlpClient.js → playCommandMediaClient.js} +684 -332
  46. package/app/modules/playModule/playConfigRuntime.js +5 -6
  47. package/app/modules/playModule/playModuleCriticalFlows.test.js +44 -59
  48. package/app/modules/quoteModule/AGENT.md +1 -1
  49. package/app/modules/quoteModule/commandConfig.json +29 -0
  50. package/app/modules/rpgPokemonModule/AGENT.md +1 -1
  51. package/app/modules/rpgPokemonModule/commandConfig.json +29 -0
  52. package/app/modules/statsModule/AGENT.md +1 -1
  53. package/app/modules/statsModule/commandConfig.json +58 -0
  54. package/app/modules/stickerModule/AGENT.md +1 -1
  55. package/app/modules/stickerModule/commandConfig.json +145 -0
  56. package/app/modules/stickerPackModule/AGENT.md +1 -1
  57. package/app/modules/stickerPackModule/autoPackCollectorService.js +5 -1
  58. package/app/modules/stickerPackModule/commandConfig.json +29 -0
  59. package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +1 -1
  60. package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +78 -57
  61. package/app/modules/stickerPackModule/stickerPackService.js +13 -6
  62. package/app/modules/systemMetricsModule/AGENT.md +1 -1
  63. package/app/modules/systemMetricsModule/commandConfig.json +29 -0
  64. package/app/modules/tiktokModule/AGENT.md +1 -1
  65. package/app/modules/tiktokModule/commandConfig.json +29 -0
  66. package/app/modules/userModule/AGENT.md +1 -1
  67. package/app/modules/userModule/commandConfig.json +29 -0
  68. package/app/modules/waifuPicsModule/AGENT.md +57 -27
  69. package/app/modules/waifuPicsModule/commandConfig.json +87 -0
  70. package/app/observability/metrics.js +136 -0
  71. package/app/services/ai/commandConfigEnrichmentService.js +229 -47
  72. package/app/services/ai/geminiService.js +131 -7
  73. package/app/services/ai/geminiService.test.js +59 -2
  74. package/app/services/ai/moduleAiHelpCoreService.js +33 -4
  75. package/app/services/group/groupMetadataService.js +24 -1
  76. package/app/services/infra/dbWriteQueue.js +51 -21
  77. package/app/services/messaging/newsBroadcastService.js +843 -27
  78. package/app/services/multiSession/assignmentBalancerService.js +457 -0
  79. package/app/services/multiSession/groupOwnershipRepository.js +381 -0
  80. package/app/services/multiSession/groupOwnershipService.js +890 -0
  81. package/app/services/multiSession/groupOwnershipService.test.js +309 -0
  82. package/app/services/multiSession/sessionRegistryService.js +293 -0
  83. package/app/store/aiPromptStore.js +36 -19
  84. package/app/store/groupConfigStore.js +41 -5
  85. package/app/store/premiumUserStore.js +21 -7
  86. package/app/utils/antiLink/antiLinkModule.js +352 -16
  87. package/app/workers/aiHelperContinuousLearningWorker.js +512 -0
  88. package/database/index.js +6 -0
  89. package/database/migrations/20260307_d0_hardening_down.sql +1 -1
  90. package/database/migrations/20260314_d7_canonical_sender_down.sql +1 -1
  91. package/database/migrations/20260406_d30_security_analytics_down.sql +1 -1
  92. package/database/migrations/20260411_d35_group_community_metadata_down.sql +59 -0
  93. package/database/migrations/20260411_d35_group_community_metadata_up.sql +62 -0
  94. package/database/migrations/20260412_d36_system_config_tables_down.sql +32 -0
  95. package/database/migrations/20260412_d36_system_config_tables_up.sql +66 -0
  96. package/database/migrations/20260413_d37_group_user_warnings_down.sql +11 -0
  97. package/database/migrations/20260413_d37_group_user_warnings_up.sql +24 -0
  98. package/database/migrations/20260414_d38_multi_session_foundation_down.sql +72 -0
  99. package/database/migrations/20260414_d38_multi_session_foundation_up.sql +125 -0
  100. package/database/migrations/20260414_d39_multi_session_cutover_down.sql +103 -0
  101. package/database/migrations/20260414_d39_multi_session_cutover_up.sql +83 -0
  102. package/database/schema.sql +102 -1
  103. package/docker-compose.yml +4 -1
  104. package/docs/compliance/acceptable-use-policy-2026-03-07.md +1 -1
  105. package/docs/compliance/privacy-policy-2026-03-07.md +2 -2
  106. package/docs/security/dsar-lgpd-runbook-2026-03-07.md +1 -1
  107. package/docs/security/network-hardening-runbook-2026-03-07.md +53 -0
  108. package/docs/security/omnizap-static-security-headers.conf +25 -0
  109. package/ecosystem.prod.config.cjs +31 -11
  110. package/index.js +52 -18
  111. package/observability/alert-rules.yml +20 -0
  112. package/observability/grafana/dashboards/omnizap-system-admin.json +229 -0
  113. package/observability/mysql-setup.sql +4 -4
  114. package/observability/system-admin-observability.md +26 -0
  115. package/package.json +12 -5
  116. package/public/comandos/commands-catalog.json +2253 -78
  117. package/public/js/apps/commandsReactApp.js +267 -87
  118. package/public/js/apps/createPackApp.js +3 -3
  119. package/public/js/apps/stickersApp.js +255 -103
  120. package/public/js/apps/termsReactApp.js +57 -8
  121. package/public/js/apps/userPasswordResetReactApp.js +406 -0
  122. package/public/js/apps/userReactApp.js +96 -47
  123. package/public/js/apps/userSystemAdmReactApp.js +1506 -0
  124. package/public/pages/politica-de-privacidade.html +1 -1
  125. package/public/pages/stickers.html +5 -5
  126. package/public/pages/termos-de-uso-texto-integral.html +1 -1
  127. package/public/pages/termos-de-uso.html +1 -1
  128. package/public/pages/user-password-reset.html +3 -4
  129. package/public/pages/user-systemadm.html +8 -462
  130. package/public/pages/user.html +1 -1
  131. package/scripts/clear-whatsapp-session.sh +123 -0
  132. package/scripts/core-ai-mode.mjs +163 -0
  133. package/scripts/deploy.sh +10 -0
  134. package/scripts/enrich-command-config-ux-openai.mjs +492 -0
  135. package/scripts/generate-commands-catalog.mjs +155 -0
  136. package/scripts/new-whatsapp-session.sh +317 -0
  137. package/scripts/security-web-surface-check.mjs +218 -0
  138. package/server/controllers/admin/adminPanelHandlers.js +253 -3
  139. package/server/controllers/admin/systemAdminController.js +267 -0
  140. package/server/controllers/sticker/stickerCatalogController.js +9 -23
  141. package/server/controllers/system/contactController.js +9 -17
  142. package/server/controllers/system/stickerCatalogSystemContext.js +27 -6
  143. package/server/controllers/system/systemController.js +254 -1
  144. package/server/controllers/userController.js +6 -0
  145. package/server/email/emailTemplateService.js +3 -2
  146. package/server/http/httpServer.js +8 -4
  147. package/server/middleware/securityHeaders.js +20 -1
  148. package/server/routes/admin/systemAdminRouter.js +6 -0
  149. package/server/routes/indexRouter.js +30 -6
  150. package/server/routes/observability/grafanaProxyRouter.js +254 -0
  151. package/server/routes/static/staticPageRouter.js +27 -1
  152. package/server/utils/publicContact.js +31 -0
  153. package/utils/whatsapp/contactEnv.js +39 -0
  154. package/vite.config.mjs +2 -1
  155. package/app/modules/playModule/local/installYtDlp.js +0 -25
  156. package/app/modules/playModule/local/ytDlpInstaller.js +0 -28
package/.env.example CHANGED
@@ -10,8 +10,6 @@
10
10
  # ==============================
11
11
  # PRIORIDADE 1 - CRITICO (startup)
12
12
  # ==============================
13
- BOT_NUMBER=
14
- BOT_PHONE_NUMBER=
15
13
  COMMAND_PREFIX="#"
16
14
  COMMAND_REACT_EMOJI=🤖
17
15
  DB_HOST=localhost
@@ -35,8 +33,6 @@ NODE_ENV=development
35
33
  OPENAI_API_KEY=
36
34
  GEMINI_API_KEY=
37
35
  GEMINI_API_BASE_URL=https://generativelanguage.googleapis.com/v1beta
38
- OWNER_NUMBER=5511999999999
39
- PHONE_NUMBER=
40
36
  PM2_APP_NAME=omnizap
41
37
  SITE_ORIGIN=https://omnizap.shop
42
38
  STICKER_API_BASE_PATH=/api/sticker-packs
@@ -46,13 +42,22 @@ SYSTEM_ADMIN_API_BASE_PATH=/api/admin
46
42
  STICKER_STORAGE_DIR=./data/stickers
47
43
  STICKER_WEB_ORIGIN=https://omnizap.shop
48
44
  STICKER_WEB_PATH=/stickers
49
- USER_ADMIN=seu_jid_de_admin@s.whatsapp.net
50
45
  WHATSAPP_BOT_NUMBER=5511999999999
46
+ WHATSAPP_SUPPORT_NUMBER=5511999999999
47
+ WHATSAPP_ADMIN_NUMBER=5511999999999
48
+ WHATSAPP_ADMIN_JID=seu_jid_de_admin@s.whatsapp.net
51
49
  WHATSAPP_LOGIN_BASE_URL=https://omnizap.shop
52
50
  WHATSAPP_LOGIN_LINK_SECRET=troque_por_um_segredo_forte
53
51
  WHATSAPP_LOGIN_PATH=/login/
54
52
  WHATSAPP_LOGIN_TRIGGER=iniciar
55
- WHATSAPP_SUPPORT_NUMBER=5511999999999
53
+
54
+ # Legado (compatibilidade): mantenha vazio quando usar as variaveis canonicas acima
55
+ BOT_NUMBER=
56
+ BOT_PHONE_NUMBER=
57
+ OWNER_NUMBER=
58
+ PHONE_NUMBER=
59
+ USER_ADMIN=
60
+ WHATSAPP_PUBLIC_CONTACT_NUMBER=
56
61
 
57
62
  # ==============================
58
63
  # PRIORIDADE 2 - OPERACAO BASE
@@ -120,11 +125,18 @@ BAILEYS_REPLY_PRESENCE_BEFORE=composing
120
125
  BAILEYS_REPLY_PRESENCE_AFTER=paused
121
126
  BAILEYS_REPLY_PRESENCE_DELAY_MS=280
122
127
  BAILEYS_AUTH_SESSION_ID=default
128
+ BAILEYS_SESSION_IDS=default
129
+ BAILEYS_PRIMARY_SESSION_ID=default
130
+ BAILEYS_SESSION_WEIGHTS=default=1
123
131
  BAILEYS_AUTH_BOOTSTRAP_FROM_FILES=true
124
132
  BAILEYS_SINGLE_WRITER_LOCK_ENABLED=true
125
133
  BAILEYS_SINGLE_WRITER_LOCK_NAME=
126
134
  BAILEYS_SINGLE_WRITER_LOCK_TIMEOUT_SECONDS=2
127
135
  BAILEYS_SINGLE_WRITER_LOCK_RETRY_DELAY_MS=15000
136
+ GROUP_OWNER_ENFORCEMENT_MODE=off
137
+ GROUP_OWNER_LEASE_MS=120000
138
+ GROUP_OWNER_HEARTBEAT_MS=30000
139
+ GROUP_BALANCER_ENABLED=false
128
140
  BAILEYS_EVENT_BATCH_SIZE=100
129
141
  BAILEYS_EVENT_QUEUE_MAX=4000
130
142
  BAILEYS_EVENT_JOURNAL_RETENTION_DAYS=14
@@ -160,6 +172,7 @@ HOME_MARKETPLACE_STATS_CACHE_SECONDS=45
160
172
  HOSTNAME=
161
173
  IMAGE_MENU=https://example.com/assets/omnizap-banner.png
162
174
  HELMET_CONTENT_SECURITY_POLICY_ENABLED=true
175
+ HELMET_CSP_FRAME_SRC_EXTRA=
163
176
  LID_BACKFILL_BATCH=50000
164
177
  LID_BACKFILL_ON_START=true
165
178
  COMMAND_CONFIG_VALIDATE_ON_BOOT=true
@@ -171,6 +184,7 @@ MESSAGE_REPLY_PRESENCE_BEFORE=composing
171
184
  MESSAGE_REPLY_PRESENCE_AFTER=paused
172
185
  MESSAGE_REPLY_PRESENCE_DELAY_MS=280
173
186
  MESSAGE_REPLY_PRESENCE_SUBSCRIBE=true
187
+ CONVERSATIONAL_AUTO_REPLY_ENABLED=false
174
188
  METRICS_ENABLED=true
175
189
  METRICS_ENDPOINT=
176
190
  METRICS_HOST=127.0.0.1
@@ -320,6 +334,26 @@ FFMPEG_PATH=ffmpeg
320
334
  FFPROBE_PATH=ffprobe
321
335
  HTTP_SLO_TARGET_MS=750
322
336
  NEWS_API_URL=http://127.0.0.1:3001
337
+ NEWS_API_ARTICLES_PATH=/articles
338
+ NEWS_API_ARTICLE_BY_ID_PATH=/articles/:id
339
+ NEWS_API_ARTICLE_BY_SLUG_PATH=/articles/slug/:slug
340
+ NEWS_API_TRENDS_PATH=/trends
341
+ NEWS_API_FRANCHISES_PATH=/franchises
342
+ NEWS_API_FRANCHISE_BY_SLUG_PATH=/franchises/:slug
343
+ NEWS_API_SOURCES_PATH=/sources
344
+ NEWS_API_SOURCE_BY_ID_PATH=/sources/:sourceId
345
+ NEWS_API_SEO_ENTITIES_PATH=/seo/entities
346
+ NEWS_API_SEO_BY_TYPE_SLUG_PATH=/seo/:type/:slug
347
+ NEWS_API_LIMIT=120
348
+ NEWS_API_TIMEOUT_MS=15000
349
+ NEWS_API_DETAILS_TIMEOUT_MS=15000
350
+ NEWS_API_CONTEXT_TTL_MS=180000
351
+ NEWS_API_DETAILS_CACHE_TTL_MS=360000
352
+ NEWS_API_CONTEXT_TOP=40
353
+ NEWS_API_LEGACY_FALLBACK=true
354
+ NEWS_SMART_SELECTION_ENABLED=true
355
+ NEWS_SMART_SELECTION_WINDOW=80
356
+ NEWS_CAPTION_CONTEXT_ENABLED=true
323
357
  NEWS_SENT_IDS_LIMIT=500
324
358
  OMNIZAP_SOCIAL_METRICS=0
325
359
  OPENAI_IMAGE_MODEL=gpt-5-nano
@@ -774,23 +808,34 @@ GITHUB_REPOSITORY=Omnizap-System/omnizap
774
808
  GITHUB_TOKEN=
775
809
  GRAFANA_ADMIN_PASSWORD=admin
776
810
  GRAFANA_ADMIN_USER=admin
811
+ GRAFANA_ALLOW_EMBEDDING=true
777
812
  GRAFANA_DASHBOARDS_PATH=./observability/grafana/dashboards
778
813
  GRAFANA_IMAGE_TAG=10.4.3
779
814
  GRAFANA_BIND_HOST=127.0.0.1
780
815
  GRAFANA_PORT=3003
816
+ GRAFANA_PUBLIC_URL=https://omnizap.shop/api/grafana
781
817
  GRAFANA_PROVISIONING_PATH=./observability/grafana/provisioning
782
- GRAFANA_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/
818
+ GRAFANA_ROOT_URL=https://omnizap.shop/api/grafana
819
+ GRAFANA_SERVE_FROM_SUB_PATH=true
820
+ GRAFANA_PROXY_BASE_PATH=/api/grafana
821
+ GRAFANA_PROXY_LEGACY_BASE_PATH=/grafana
822
+ GRAFANA_PROXY_TARGET_URL=http://127.0.0.1:3003
823
+ SYSTEM_ADMIN_GRAFANA_URL=https://omnizap.shop/api/grafana
824
+ SYSTEM_ADMIN_GRAFANA_DASHBOARDS=omnizap-system-admin|System Admin,omnizap-overview|Overview,omnizap-mysql|MySQL
825
+ SYSTEM_ADMIN_GRAFANA_TIME_FROM=now-6h
826
+ SYSTEM_ADMIN_GRAFANA_TIME_TO=now
827
+ SYSTEM_ADMIN_GRAFANA_REFRESH=10s
783
828
  GRAFANA_TIMEZONE=America/Boa_Vista
784
829
  LOKI_CONFIG_PATH=./observability/loki-config.yml
785
830
  LOKI_IMAGE_TAG=2.9.4
786
831
  LOKI_BIND_HOST=127.0.0.1
787
832
  LOKI_PORT=3100
788
833
  MYSQL_EXPORTER_CNF_PATH=./observability/mysql-exporter.cnf
789
- MYSQL_EXPORTER_DSN=exporter:exporter@(host.docker.internal:3306)/
834
+ MYSQL_EXPORTER_DSN=exporter:exporter@unix(/run/mysqld/mysqld.sock)/
790
835
  MYSQL_EXPORTER_IMAGE_TAG=v0.15.1
791
836
  MYSQL_EXPORTER_BIND_HOST=127.0.0.1
792
837
  MYSQL_EXPORTER_PORT=9104
793
- MYSQL_LOGS_PATH=/var/lib/mysql
838
+ MYSQL_LOGS_PATH=/var/log/mysql
794
839
  NODE_AUTH_TOKEN=
795
840
  NODE_EXPORTER_IMAGE_TAG=v1.7.0
796
841
  NODE_EXPORTER_BIND_HOST=127.0.0.1
@@ -57,6 +57,9 @@ jobs:
57
57
  - name: Install dependencies
58
58
  run: npm ci
59
59
 
60
+ - name: DB bootstrap smoke test
61
+ run: npm run db:init
62
+
60
63
  - name: Check formatting
61
64
  run: npm run format:check
62
65
 
@@ -68,6 +71,3 @@ jobs:
68
71
 
69
72
  - name: Build
70
73
  run: npm run build
71
-
72
- - name: DB bootstrap smoke test
73
- run: npm run db:init
@@ -18,7 +18,7 @@ jobs:
18
18
  timeout-minutes: 10
19
19
  steps:
20
20
  - name: Harden runner
21
- uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc
21
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594
22
22
  with:
23
23
  egress-policy: audit
24
24
 
@@ -39,5 +39,6 @@ jobs:
39
39
  with:
40
40
  target: ${{ env.TARGET_URL }}
41
41
  fail_action: false
42
+ artifact_name: zap-scan-full
42
43
  env:
43
44
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -2,3 +2,5 @@ export * from '../configParts/baileysConfig.js';
2
2
  export * from '../configParts/groupUtils.js';
3
3
  export * from '../configParts/adminIdentity.js';
4
4
  export * from '../configParts/loggerConfig.js';
5
+ export * from '../configParts/sessionConfig.js';
6
+ export * from '../../utils/whatsapp/contactEnv.js';
@@ -1,11 +1,8 @@
1
1
  import { encodeJid, getJidUser, isSameJidUser, normalizeJid } from './baileysConfig.js';
2
2
  import { extractUserIdInfo, resolveUserId, resolveUserIdCached } from './baileysConfig.js';
3
+ import { normalizePhoneDigits, resolveAdminIdentityRawFromEnv, resolveAdminPhoneFromEnv } from '../../utils/whatsapp/contactEnv.js';
3
4
 
4
- const ADMIN_ENV_KEY = 'USER_ADMIN';
5
-
6
- const normalizePhoneDigits = (value) => String(value || '').replace(/\D+/g, '');
7
-
8
- export const getAdminRawValue = () => String(process.env[ADMIN_ENV_KEY] || '').trim();
5
+ export const getAdminRawValue = () => resolveAdminIdentityRawFromEnv();
9
6
 
10
7
  export const getAdminJid = () => {
11
8
  const raw = getAdminRawValue();
@@ -28,6 +25,9 @@ export const getAdminJid = () => {
28
25
  };
29
26
 
30
27
  export const getAdminPhone = () => {
28
+ const explicitAdminPhone = resolveAdminPhoneFromEnv({ fallback: '' });
29
+ if (explicitAdminPhone) return explicitAdminPhone;
30
+
31
31
  const adminJid = getAdminJid();
32
32
  if (!adminJid) return null;
33
33