@omnizap-system/omnizap 2.6.2 → 2.6.3

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 (48) hide show
  1. package/.env.example +24 -0
  2. package/app/config/index.js +4 -0
  3. package/app/configParts/adminIdentity.js +29 -0
  4. package/app/configParts/baileysConfig.js +116 -0
  5. package/app/configParts/groupUtils.js +221 -0
  6. package/app/configParts/loggerConfig.js +185 -0
  7. package/app/configParts/messagePersistenceService.js +169 -7
  8. package/app/configParts/sessionConfig.js +85 -0
  9. package/app/connection/baileysCompatibility.test.js +9 -0
  10. package/app/connection/baileysDbAuthState.js +205 -9
  11. package/app/connection/baileysLibsignalPatch.js +210 -0
  12. package/app/connection/groupOwnerWriteStateResolver.js +53 -21
  13. package/app/connection/socketController.js +95 -25
  14. package/app/connection/socketController.multiSession.test.js +20 -0
  15. package/app/controllers/messagePipeline/preProcessingMiddlewares.js +17 -3
  16. package/app/controllers/messageProcessingPipeline.js +2 -0
  17. package/app/controllers/messageProcessingPipeline.test.js +15 -13
  18. package/app/services/multiSession/assignmentBalancerService.js +1 -6
  19. package/app/services/multiSession/groupOwnershipRepository.js +9 -44
  20. package/app/services/multiSession/groupOwnershipService.js +9 -90
  21. package/app/services/multiSession/groupOwnershipService.test.js +12 -4
  22. package/app/services/multiSession/sessionRegistryService.js +6 -60
  23. package/app/utils/antiLink/antiLinkModule.js +54 -24
  24. package/docs/security/omnizap-static-security-headers.conf +3 -3
  25. package/package.json +3 -2
  26. package/public/comandos/commands-catalog.json +1 -1
  27. package/public/css/payments-react.css +478 -0
  28. package/public/js/apps/homeReactApp.js +2 -2
  29. package/public/js/apps/paymentsCancelReactApp.js +45 -0
  30. package/public/js/apps/paymentsReactApp.js +399 -0
  31. package/public/js/apps/paymentsSuccessReactApp.js +148 -0
  32. package/public/pages/pagamentos-cancelado.html +21 -0
  33. package/public/pages/pagamentos-sucesso.html +21 -0
  34. package/public/pages/pagamentos.html +30 -0
  35. package/scripts/deploy.sh +3 -0
  36. package/scripts/new-whatsapp-session.sh +247 -0
  37. package/server/controllers/admin/systemAdminController.js +4 -17
  38. package/server/controllers/payments/paymentsController.js +731 -0
  39. package/server/controllers/system/systemController.js +4 -30
  40. package/server/email/emailAutomationRuntime.js +36 -1
  41. package/server/email/emailAutomationService.js +42 -1
  42. package/server/email/emailTemplateService.js +137 -31
  43. package/server/http/httpRequestUtils.js +18 -14
  44. package/server/middleware/securityHeaders.js +15 -2
  45. package/server/routes/indexRouter.js +27 -7
  46. package/server/routes/payments/paymentsRouter.js +47 -0
  47. package/server/routes/static/staticPageRouter.js +3 -0
  48. package/vite.config.mjs +3 -0
@@ -0,0 +1,478 @@
1
+ :root {
2
+ --payments-main-bg-start: #071024;
3
+ --payments-main-bg-end: #11172f;
4
+ --payments-main-panel: rgba(13, 26, 52, 0.84);
5
+ --payments-main-panel-line: rgba(148, 187, 255, 0.2);
6
+ --payments-main-text: #e7f0ff;
7
+ --payments-main-muted: #9eb6da;
8
+ --payments-main-primary: #4ade80;
9
+ --payments-main-primary-strong: #22c55e;
10
+ --payments-main-danger: #fb7185;
11
+
12
+ --payments-success-panel: rgba(10, 34, 30, 0.86);
13
+ --payments-success-line: rgba(98, 228, 182, 0.24);
14
+ --payments-success-text: #eafff6;
15
+ --payments-success-muted: #b1ddce;
16
+
17
+ --payments-cancel-text: #ffe8ee;
18
+ --payments-cancel-muted: #f2b8c8;
19
+ }
20
+
21
+ * {
22
+ box-sizing: border-box;
23
+ }
24
+
25
+ body.payments-body {
26
+ margin: 0;
27
+ min-height: 100vh;
28
+ font-family: 'Manrope', system-ui, sans-serif;
29
+ }
30
+
31
+ body.payments-body-main {
32
+ color: var(--payments-main-text);
33
+ background: radial-gradient(52rem 30rem at -4% -8%, rgba(30, 143, 255, 0.18), transparent 62%), radial-gradient(44rem 24rem at 104% 2%, rgba(53, 255, 181, 0.14), transparent 58%), linear-gradient(160deg, var(--payments-main-bg-start), var(--payments-main-bg-end));
34
+ }
35
+
36
+ body.payments-body-main::before {
37
+ content: '';
38
+ position: fixed;
39
+ inset: 0;
40
+ pointer-events: none;
41
+ background: linear-gradient(rgba(173, 216, 255, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(173, 216, 255, 0.05) 1px, transparent 1px);
42
+ background-size: 34px 34px;
43
+ mask-image: radial-gradient(circle at center, black 38%, transparent 100%);
44
+ opacity: 0.25;
45
+ }
46
+
47
+ #payments-react-root {
48
+ min-height: 100vh;
49
+ }
50
+
51
+ .payments-page {
52
+ position: relative;
53
+ z-index: 1;
54
+ width: min(980px, 92vw);
55
+ margin: 40px auto;
56
+ }
57
+
58
+ .payments-hero {
59
+ margin-bottom: 22px;
60
+ }
61
+
62
+ .payments-eyebrow {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: 8px;
66
+ border: 1px solid rgba(93, 138, 219, 0.36);
67
+ border-radius: 999px;
68
+ padding: 8px 14px;
69
+ font-size: 12px;
70
+ letter-spacing: 0.08em;
71
+ text-transform: uppercase;
72
+ color: #bcdaff;
73
+ background: rgba(20, 38, 74, 0.56);
74
+ }
75
+
76
+ .payments-eyebrow::before {
77
+ content: '';
78
+ width: 8px;
79
+ height: 8px;
80
+ border-radius: 50%;
81
+ background: var(--payments-main-primary);
82
+ box-shadow: 0 0 0 6px rgba(74, 222, 128, 0.2);
83
+ }
84
+
85
+ .payments-hero h1 {
86
+ margin: 14px 0 10px;
87
+ font-family: 'Sora', sans-serif;
88
+ font-size: clamp(30px, 5vw, 48px);
89
+ line-height: 1.04;
90
+ }
91
+
92
+ .payments-hero p {
93
+ margin: 0;
94
+ max-width: 780px;
95
+ color: var(--payments-main-muted);
96
+ font-size: clamp(15px, 2vw, 18px);
97
+ }
98
+
99
+ .payments-layout {
100
+ display: grid;
101
+ gap: 18px;
102
+ grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.9fr);
103
+ }
104
+
105
+ .payments-card {
106
+ border: 1px solid var(--payments-main-panel-line);
107
+ border-radius: 20px;
108
+ background: var(--payments-main-panel);
109
+ box-shadow:
110
+ 0 24px 60px rgba(5, 10, 22, 0.5),
111
+ inset 0 1px 0 rgba(192, 217, 255, 0.08);
112
+ }
113
+
114
+ .payments-checkout,
115
+ .payments-aside {
116
+ padding: 24px;
117
+ }
118
+
119
+ .payments-row {
120
+ margin-bottom: 14px;
121
+ }
122
+
123
+ .payments-row:last-of-type {
124
+ margin-bottom: 0;
125
+ }
126
+
127
+ .payments-row label {
128
+ display: block;
129
+ margin-bottom: 8px;
130
+ font-size: 13px;
131
+ color: #d1e2ff;
132
+ }
133
+
134
+ .payments-row input {
135
+ width: 100%;
136
+ border: 1px solid rgba(120, 160, 231, 0.34);
137
+ border-radius: 12px;
138
+ background: rgba(9, 18, 38, 0.8);
139
+ color: var(--payments-main-text);
140
+ min-height: 48px;
141
+ padding: 0 14px;
142
+ font: inherit;
143
+ }
144
+
145
+ .payments-row input:focus {
146
+ outline: none;
147
+ border-color: rgba(132, 185, 255, 0.9);
148
+ box-shadow: 0 0 0 3px rgba(102, 170, 255, 0.18);
149
+ }
150
+
151
+ .payments-row input[readonly] {
152
+ opacity: 0.9;
153
+ background: rgba(14, 28, 54, 0.9);
154
+ border-color: rgba(110, 146, 212, 0.5);
155
+ }
156
+
157
+ .payments-hint {
158
+ margin-top: 6px;
159
+ font-size: 12px;
160
+ color: var(--payments-main-muted);
161
+ }
162
+
163
+ .payments-hint code {
164
+ font-family: 'Sora', monospace;
165
+ }
166
+
167
+ .payments-actions {
168
+ margin-top: 20px;
169
+ display: flex;
170
+ gap: 10px;
171
+ flex-wrap: wrap;
172
+ }
173
+
174
+ .payments-button {
175
+ display: inline-flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ appearance: none;
179
+ border: 0;
180
+ border-radius: 12px;
181
+ min-height: 48px;
182
+ padding: 0 18px;
183
+ font-family: 'Sora', sans-serif;
184
+ font-size: 13px;
185
+ letter-spacing: 0.03em;
186
+ text-transform: uppercase;
187
+ text-decoration: none;
188
+ cursor: pointer;
189
+ transition:
190
+ transform 150ms ease,
191
+ filter 150ms ease;
192
+ }
193
+
194
+ .payments-button:disabled {
195
+ opacity: 0.65;
196
+ cursor: not-allowed;
197
+ }
198
+
199
+ .payments-button-primary {
200
+ color: #052312;
201
+ background: linear-gradient(120deg, var(--payments-main-primary), var(--payments-main-primary-strong));
202
+ box-shadow: 0 10px 26px rgba(34, 197, 94, 0.3);
203
+ }
204
+
205
+ .payments-button-secondary {
206
+ color: #d5e8ff;
207
+ background: rgba(26, 50, 91, 0.9);
208
+ border: 1px solid rgba(129, 175, 255, 0.4);
209
+ }
210
+
211
+ .payments-button:hover:not(:disabled) {
212
+ transform: translateY(-1px);
213
+ filter: brightness(1.03);
214
+ }
215
+
216
+ .payments-status {
217
+ margin-top: 14px;
218
+ min-height: 22px;
219
+ font-size: 14px;
220
+ }
221
+
222
+ .payments-status.error {
223
+ color: var(--payments-main-danger);
224
+ }
225
+
226
+ .payments-status.success {
227
+ color: var(--payments-main-primary);
228
+ }
229
+
230
+ .payments-plan-badge {
231
+ display: inline-flex;
232
+ align-items: center;
233
+ gap: 8px;
234
+ margin-bottom: 14px;
235
+ border: 1px solid rgba(141, 176, 246, 0.28);
236
+ border-radius: 999px;
237
+ padding: 7px 12px;
238
+ background: rgba(17, 33, 66, 0.7);
239
+ font-size: 12px;
240
+ }
241
+
242
+ .payments-plan-title {
243
+ margin: 0;
244
+ font-family: 'Sora', sans-serif;
245
+ font-size: 24px;
246
+ line-height: 1.2;
247
+ }
248
+
249
+ .payments-plan-price {
250
+ margin: 8px 0 16px;
251
+ color: #9fd5ff;
252
+ font-size: 15px;
253
+ }
254
+
255
+ .payments-feature-list {
256
+ margin: 0;
257
+ padding: 0;
258
+ list-style: none;
259
+ }
260
+
261
+ .payments-feature-list li {
262
+ position: relative;
263
+ padding-left: 18px;
264
+ margin-bottom: 10px;
265
+ color: #cde2ff;
266
+ font-size: 14px;
267
+ }
268
+
269
+ .payments-feature-list li::before {
270
+ content: '';
271
+ position: absolute;
272
+ left: 0;
273
+ top: 8px;
274
+ width: 8px;
275
+ height: 8px;
276
+ border-radius: 50%;
277
+ background: linear-gradient(120deg, #93c5fd, #4ade80);
278
+ }
279
+
280
+ .payments-feature-list li:last-child {
281
+ margin-bottom: 0;
282
+ }
283
+
284
+ .payments-small {
285
+ margin-top: 16px;
286
+ color: var(--payments-main-muted);
287
+ font-size: 13px;
288
+ line-height: 1.5;
289
+ }
290
+
291
+ .payments-small a {
292
+ color: #cde6ff;
293
+ }
294
+
295
+ body.payments-body-success {
296
+ color: var(--payments-success-text);
297
+ background: radial-gradient(50rem 22rem at 10% -15%, rgba(74, 222, 128, 0.22), transparent 62%), radial-gradient(42rem 20rem at 100% 110%, rgba(59, 130, 246, 0.2), transparent 62%), linear-gradient(170deg, #051714, #081320);
298
+ }
299
+
300
+ body.payments-body-cancel {
301
+ color: var(--payments-cancel-text);
302
+ background: radial-gradient(36rem 18rem at 12% -8%, rgba(251, 113, 133, 0.3), transparent 62%), radial-gradient(36rem 18rem at 100% 100%, rgba(239, 68, 68, 0.26), transparent 62%), linear-gradient(160deg, #2b1218, #1e0b10);
303
+ }
304
+
305
+ #payments-success-react-root,
306
+ #payments-cancel-react-root {
307
+ min-height: 100vh;
308
+ display: grid;
309
+ place-items: center;
310
+ padding: 24px;
311
+ }
312
+
313
+ .payments-result-card {
314
+ width: min(680px, 100%);
315
+ border: 1px solid var(--payments-success-line);
316
+ border-radius: 20px;
317
+ background: var(--payments-success-panel);
318
+ box-shadow:
319
+ 0 24px 60px rgba(0, 0, 0, 0.45),
320
+ inset 0 1px 0 rgba(183, 255, 233, 0.09);
321
+ padding: 28px;
322
+ }
323
+
324
+ .payments-result-title {
325
+ margin: 0;
326
+ font-family: 'Sora', sans-serif;
327
+ font-size: clamp(28px, 5vw, 40px);
328
+ line-height: 1.1;
329
+ }
330
+
331
+ .payments-result-subtitle {
332
+ margin: 10px 0 20px;
333
+ color: var(--payments-success-muted);
334
+ font-size: 16px;
335
+ }
336
+
337
+ .payments-result-status {
338
+ border: 1px solid rgba(118, 255, 196, 0.24);
339
+ border-radius: 14px;
340
+ background: rgba(12, 48, 41, 0.7);
341
+ padding: 14px;
342
+ font-size: 15px;
343
+ }
344
+
345
+ .payments-result-status.pending {
346
+ border-color: rgba(245, 158, 11, 0.4);
347
+ background: rgba(59, 39, 7, 0.7);
348
+ color: #ffe5b0;
349
+ }
350
+
351
+ .payments-result-status.error {
352
+ border-color: rgba(251, 113, 133, 0.5);
353
+ background: rgba(72, 14, 32, 0.72);
354
+ color: #ffd5df;
355
+ }
356
+
357
+ .payments-result-meta {
358
+ margin-top: 16px;
359
+ font-size: 13px;
360
+ color: #b6dacd;
361
+ }
362
+
363
+ .payments-result-actions {
364
+ margin-top: 20px;
365
+ display: flex;
366
+ gap: 10px;
367
+ flex-wrap: wrap;
368
+ }
369
+
370
+ .payments-result-button {
371
+ border: 1px solid rgba(148, 255, 216, 0.36);
372
+ border-radius: 12px;
373
+ padding: 11px 14px;
374
+ text-decoration: none;
375
+ color: var(--payments-success-text);
376
+ font-family: 'Sora', sans-serif;
377
+ font-size: 12px;
378
+ text-transform: uppercase;
379
+ letter-spacing: 0.05em;
380
+ background: rgba(20, 70, 59, 0.8);
381
+ }
382
+
383
+ .payments-result-button.primary {
384
+ border-color: transparent;
385
+ color: #042312;
386
+ background: linear-gradient(120deg, #4ade80, #22c55e);
387
+ }
388
+
389
+ .payments-cancel-card {
390
+ width: min(620px, 100%);
391
+ border: 1px solid rgba(253, 166, 180, 0.35);
392
+ border-radius: 20px;
393
+ background: rgba(52, 19, 28, 0.82);
394
+ box-shadow:
395
+ 0 24px 60px rgba(0, 0, 0, 0.44),
396
+ inset 0 1px 0 rgba(255, 214, 223, 0.1);
397
+ padding: 28px;
398
+ }
399
+
400
+ .payments-cancel-title {
401
+ margin: 0;
402
+ font-family: 'Sora', sans-serif;
403
+ font-size: clamp(30px, 5vw, 42px);
404
+ line-height: 1.1;
405
+ }
406
+
407
+ .payments-cancel-subtitle {
408
+ margin: 12px 0 0;
409
+ color: var(--payments-cancel-muted);
410
+ font-size: 16px;
411
+ }
412
+
413
+ .payments-cancel-note {
414
+ margin-top: 16px;
415
+ border: 1px solid rgba(252, 165, 165, 0.3);
416
+ border-radius: 12px;
417
+ background: rgba(74, 22, 33, 0.72);
418
+ padding: 12px;
419
+ font-size: 14px;
420
+ color: #ffd4de;
421
+ }
422
+
423
+ .payments-cancel-actions {
424
+ margin-top: 20px;
425
+ display: flex;
426
+ gap: 10px;
427
+ flex-wrap: wrap;
428
+ }
429
+
430
+ .payments-cancel-button {
431
+ display: inline-flex;
432
+ align-items: center;
433
+ justify-content: center;
434
+ min-height: 44px;
435
+ border-radius: 12px;
436
+ padding: 0 14px;
437
+ text-decoration: none;
438
+ font-family: 'Sora', sans-serif;
439
+ font-size: 12px;
440
+ text-transform: uppercase;
441
+ letter-spacing: 0.05em;
442
+ }
443
+
444
+ .payments-cancel-button.retry {
445
+ border: 0;
446
+ color: #28080f;
447
+ background: linear-gradient(120deg, #fb7185, #f43f5e);
448
+ }
449
+
450
+ .payments-cancel-button.home {
451
+ border: 1px solid rgba(253, 166, 180, 0.4);
452
+ color: var(--payments-cancel-text);
453
+ background: rgba(78, 27, 39, 0.75);
454
+ }
455
+
456
+ @media (max-width: 900px) {
457
+ .payments-layout {
458
+ grid-template-columns: 1fr;
459
+ }
460
+
461
+ .payments-page {
462
+ margin: 28px auto;
463
+ }
464
+ }
465
+
466
+ @media (max-width: 640px) {
467
+ #payments-success-react-root,
468
+ #payments-cancel-react-root {
469
+ padding: 18px;
470
+ }
471
+
472
+ .payments-result-card,
473
+ .payments-cancel-card,
474
+ .payments-checkout,
475
+ .payments-aside {
476
+ padding: 20px;
477
+ }
478
+ }
@@ -802,7 +802,7 @@ const App = () => {
802
802
  <div className="absolute top-6 right-6 px-3 py-1 rounded-full bg-primary text-[#020617] text-[10px] font-black uppercase tracking-widest group-hover:scale-110 transition-transform">Recomendado</div>
803
803
  <div className="mb-8">
804
804
  <h3 className="text-xl font-bold mb-2 text-primary">Plano Premium</h3>
805
- <div className="text-4xl font-black mb-4 text-white group-hover:scale-105 origin-left transition-transform duration-500">R$ 14,90<span className="text-sm text-white/20 font-medium italic">/mês</span></div>
805
+ <div className="text-4xl font-black mb-4 text-white group-hover:scale-105 origin-left transition-transform duration-500">R$ 19,90<span className="text-sm text-white/20 font-medium italic">/mês</span></div>
806
806
  <p className="text-sm text-white/40">Potência máxima para administradores profissionais.</p>
807
807
  </div>
808
808
  <ul className="space-y-4 mb-10 flex-1">
@@ -815,7 +815,7 @@ const App = () => {
815
815
  `,
816
816
  )}
817
817
  </ul>
818
- <a href=${botMenuUrl} className="btn btn-primary rounded-xl font-black shadow-lg shadow-primary/20 group-hover:shadow-primary/40 transition-all hover:scale-105">Quero ser Premium</a>
818
+ <a href="/pagamentos/" className="btn btn-primary rounded-xl font-black shadow-lg shadow-primary/20 group-hover:shadow-primary/40 transition-all hover:scale-105">Quero ser Premium</a>
819
819
  </div>
820
820
  </div>
821
821
  </div>
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import htm from 'htm';
4
+
5
+ const html = htm.bind(React.createElement);
6
+
7
+ const DEFAULT_PAYMENTS_PATH = '/pagamentos/';
8
+ const DEFAULT_HOME_PATH = '/';
9
+
10
+ const normalizeRoutePath = (value, fallback) => {
11
+ const raw = String(value || '').trim();
12
+ if (!raw) return fallback;
13
+ if (!raw.startsWith('/')) return fallback;
14
+ if (/^\/\//.test(raw)) return fallback;
15
+ return raw;
16
+ };
17
+
18
+ const resolveConfig = (rootElement) => {
19
+ const dataset = rootElement?.dataset || {};
20
+
21
+ return {
22
+ paymentsPath: normalizeRoutePath(dataset.paymentsPath, DEFAULT_PAYMENTS_PATH),
23
+ homePath: normalizeRoutePath(dataset.homePath, DEFAULT_HOME_PATH),
24
+ };
25
+ };
26
+
27
+ const PaymentsCancelReactApp = ({ config }) => html`
28
+ <main className="payments-cancel-card">
29
+ <h1 className="payments-cancel-title">Pagamento cancelado</h1>
30
+ <p className="payments-cancel-subtitle">Nenhuma cobranca foi finalizada. Se quiser, voce pode tentar novamente agora.</p>
31
+
32
+ <div className="payments-cancel-note">Quando o checkout for concluido, o webhook do Stripe libera seu Premium automaticamente.</div>
33
+
34
+ <div className="payments-cancel-actions">
35
+ <a className="payments-cancel-button retry" href=${config.paymentsPath}>Tentar novamente</a>
36
+ <a className="payments-cancel-button home" href=${config.homePath}>Voltar para home</a>
37
+ </div>
38
+ </main>
39
+ `;
40
+
41
+ const rootElement = document.getElementById('payments-cancel-react-root');
42
+ if (rootElement) {
43
+ const config = resolveConfig(rootElement);
44
+ createRoot(rootElement).render(html`<${PaymentsCancelReactApp} config=${config} />`);
45
+ }