@omnizap-system/omnizap 2.6.1 → 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.
- package/.env.example +78 -9
- package/.github/workflows/ci.yml +3 -3
- package/.github/workflows/security-runner-hardening.yml +1 -1
- package/.github/workflows/security-zap-full-scan.yml +1 -0
- package/app/config/index.js +6 -0
- package/app/configParts/adminIdentity.js +36 -7
- package/app/configParts/baileysConfig.js +343 -56
- package/app/configParts/groupUtils.js +226 -0
- package/app/configParts/loggerConfig.js +185 -0
- package/app/configParts/messagePersistenceService.js +307 -5
- package/app/configParts/sessionConfig.js +242 -0
- package/app/connection/baileysCompatibility.test.js +10 -1
- package/app/connection/baileysDbAuthState.js +205 -9
- package/app/connection/baileysLibsignalPatch.js +210 -0
- package/app/connection/groupOwnerWriteStateResolver.js +141 -0
- package/app/connection/socketController.js +694 -123
- package/app/connection/socketController.multiSession.test.js +128 -0
- package/app/controllers/messageController.js +1 -1
- package/app/controllers/messagePipeline/commandMiddleware.js +12 -10
- package/app/controllers/messagePipeline/conversationMiddleware.js +2 -1
- package/app/controllers/messagePipeline/messagePipelineMiddlewares.test.js +104 -0
- package/app/controllers/messagePipeline/preProcessingMiddlewares.js +96 -4
- package/app/controllers/messageProcessingPipeline.js +90 -9
- package/app/controllers/messageProcessingPipeline.test.js +202 -0
- package/app/modules/adminModule/AGENT.md +1 -1
- package/app/modules/adminModule/commandConfig.json +3318 -1347
- package/app/modules/adminModule/groupCommandHandlers.js +856 -14
- package/app/modules/adminModule/groupCommandHandlers.test.js +375 -9
- package/app/modules/adminModule/groupWarningRepository.js +152 -0
- package/app/modules/aiModule/AGENT.md +47 -30
- package/app/modules/aiModule/aiConfigRuntime.js +1 -0
- package/app/modules/aiModule/catCommand.js +132 -25
- package/app/modules/aiModule/commandConfig.json +114 -28
- package/app/modules/analyticsModule/messageAnalysisEventRepository.js +54 -6
- package/app/modules/gameModule/AGENT.md +1 -1
- package/app/modules/gameModule/commandConfig.json +29 -0
- package/app/modules/menuModule/AGENT.md +1 -1
- package/app/modules/menuModule/commandConfig.json +45 -10
- package/app/modules/menuModule/menuCatalogService.js +190 -0
- package/app/modules/menuModule/menuCommandUsageRepository.js +109 -0
- package/app/modules/menuModule/menuDynamicService.js +511 -0
- package/app/modules/menuModule/menuDynamicService.test.js +141 -0
- package/app/modules/menuModule/menus.js +36 -5
- package/app/modules/playModule/AGENT.md +10 -5
- package/app/modules/playModule/commandConfig.json +74 -16
- package/app/modules/playModule/playCommandConstants.js +13 -7
- package/app/modules/playModule/playCommandCore.js +4 -6
- package/app/modules/playModule/{playCommandYtDlpClient.js → playCommandMediaClient.js} +684 -332
- package/app/modules/playModule/playConfigRuntime.js +5 -6
- package/app/modules/playModule/playModuleCriticalFlows.test.js +44 -59
- package/app/modules/quoteModule/AGENT.md +1 -1
- package/app/modules/quoteModule/commandConfig.json +29 -0
- package/app/modules/rpgPokemonModule/AGENT.md +1 -1
- package/app/modules/rpgPokemonModule/commandConfig.json +29 -0
- package/app/modules/statsModule/AGENT.md +1 -1
- package/app/modules/statsModule/commandConfig.json +58 -0
- package/app/modules/stickerModule/AGENT.md +1 -1
- package/app/modules/stickerModule/commandConfig.json +145 -0
- package/app/modules/stickerPackModule/AGENT.md +1 -1
- package/app/modules/stickerPackModule/autoPackCollectorService.js +5 -1
- package/app/modules/stickerPackModule/commandConfig.json +29 -0
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +1 -1
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +78 -57
- package/app/modules/stickerPackModule/stickerPackService.js +13 -6
- package/app/modules/systemMetricsModule/AGENT.md +1 -1
- package/app/modules/systemMetricsModule/commandConfig.json +29 -0
- package/app/modules/tiktokModule/AGENT.md +1 -1
- package/app/modules/tiktokModule/commandConfig.json +29 -0
- package/app/modules/userModule/AGENT.md +1 -1
- package/app/modules/userModule/commandConfig.json +29 -0
- package/app/modules/waifuPicsModule/AGENT.md +57 -27
- package/app/modules/waifuPicsModule/commandConfig.json +87 -0
- package/app/observability/metrics.js +136 -0
- package/app/services/ai/commandConfigEnrichmentService.js +229 -47
- package/app/services/ai/geminiService.js +131 -7
- package/app/services/ai/geminiService.test.js +59 -2
- package/app/services/ai/moduleAiHelpCoreService.js +33 -4
- package/app/services/group/groupMetadataService.js +24 -1
- package/app/services/infra/dbWriteQueue.js +51 -21
- package/app/services/messaging/newsBroadcastService.js +843 -27
- package/app/services/multiSession/assignmentBalancerService.js +452 -0
- package/app/services/multiSession/groupOwnershipRepository.js +346 -0
- package/app/services/multiSession/groupOwnershipService.js +809 -0
- package/app/services/multiSession/groupOwnershipService.test.js +317 -0
- package/app/services/multiSession/sessionRegistryService.js +239 -0
- package/app/store/aiPromptStore.js +36 -19
- package/app/store/groupConfigStore.js +41 -5
- package/app/store/premiumUserStore.js +21 -7
- package/app/utils/antiLink/antiLinkModule.js +391 -25
- package/app/workers/aiHelperContinuousLearningWorker.js +512 -0
- package/database/index.js +6 -0
- package/database/migrations/20260307_d0_hardening_down.sql +1 -1
- package/database/migrations/20260314_d7_canonical_sender_down.sql +1 -1
- package/database/migrations/20260406_d30_security_analytics_down.sql +1 -1
- package/database/migrations/20260411_d35_group_community_metadata_down.sql +59 -0
- package/database/migrations/20260411_d35_group_community_metadata_up.sql +62 -0
- package/database/migrations/20260412_d36_system_config_tables_down.sql +32 -0
- package/database/migrations/20260412_d36_system_config_tables_up.sql +66 -0
- package/database/migrations/20260413_d37_group_user_warnings_down.sql +11 -0
- package/database/migrations/20260413_d37_group_user_warnings_up.sql +24 -0
- package/database/migrations/20260414_d38_multi_session_foundation_down.sql +72 -0
- package/database/migrations/20260414_d38_multi_session_foundation_up.sql +125 -0
- package/database/migrations/20260414_d39_multi_session_cutover_down.sql +103 -0
- package/database/migrations/20260414_d39_multi_session_cutover_up.sql +83 -0
- package/database/schema.sql +102 -1
- package/docker-compose.yml +4 -1
- package/docs/compliance/acceptable-use-policy-2026-03-07.md +1 -1
- package/docs/compliance/privacy-policy-2026-03-07.md +2 -2
- package/docs/security/dsar-lgpd-runbook-2026-03-07.md +1 -1
- package/docs/security/network-hardening-runbook-2026-03-07.md +53 -0
- package/docs/security/omnizap-static-security-headers.conf +25 -0
- package/ecosystem.prod.config.cjs +31 -11
- package/index.js +52 -18
- package/observability/alert-rules.yml +20 -0
- package/observability/grafana/dashboards/omnizap-system-admin.json +229 -0
- package/observability/mysql-setup.sql +4 -4
- package/observability/system-admin-observability.md +26 -0
- package/package.json +14 -6
- package/public/comandos/commands-catalog.json +2253 -78
- package/public/css/payments-react.css +478 -0
- package/public/js/apps/commandsReactApp.js +267 -87
- package/public/js/apps/createPackApp.js +3 -3
- package/public/js/apps/homeReactApp.js +2 -2
- package/public/js/apps/paymentsCancelReactApp.js +45 -0
- package/public/js/apps/paymentsReactApp.js +399 -0
- package/public/js/apps/paymentsSuccessReactApp.js +148 -0
- package/public/js/apps/stickersApp.js +255 -103
- package/public/js/apps/termsReactApp.js +57 -8
- package/public/js/apps/userPasswordResetReactApp.js +406 -0
- package/public/js/apps/userReactApp.js +96 -47
- package/public/js/apps/userSystemAdmReactApp.js +1506 -0
- package/public/pages/pagamentos-cancelado.html +21 -0
- package/public/pages/pagamentos-sucesso.html +21 -0
- package/public/pages/pagamentos.html +30 -0
- package/public/pages/politica-de-privacidade.html +1 -1
- package/public/pages/stickers.html +5 -5
- package/public/pages/termos-de-uso-texto-integral.html +1 -1
- package/public/pages/termos-de-uso.html +1 -1
- package/public/pages/user-password-reset.html +3 -4
- package/public/pages/user-systemadm.html +8 -462
- package/public/pages/user.html +1 -1
- package/scripts/clear-whatsapp-session.sh +123 -0
- package/scripts/core-ai-mode.mjs +163 -0
- package/scripts/deploy.sh +13 -0
- package/scripts/enrich-command-config-ux-openai.mjs +492 -0
- package/scripts/generate-commands-catalog.mjs +155 -0
- package/scripts/new-whatsapp-session.sh +564 -0
- package/scripts/security-web-surface-check.mjs +218 -0
- package/server/controllers/admin/adminPanelHandlers.js +253 -3
- package/server/controllers/admin/systemAdminController.js +254 -0
- package/server/controllers/payments/paymentsController.js +731 -0
- package/server/controllers/sticker/stickerCatalogController.js +9 -23
- package/server/controllers/system/contactController.js +9 -17
- package/server/controllers/system/stickerCatalogSystemContext.js +27 -6
- package/server/controllers/system/systemController.js +228 -1
- package/server/controllers/userController.js +6 -0
- package/server/email/emailAutomationRuntime.js +36 -1
- package/server/email/emailAutomationService.js +42 -1
- package/server/email/emailTemplateService.js +140 -33
- package/server/http/httpRequestUtils.js +18 -14
- package/server/http/httpServer.js +8 -4
- package/server/middleware/securityHeaders.js +35 -3
- package/server/routes/admin/systemAdminRouter.js +6 -0
- package/server/routes/indexRouter.js +50 -6
- package/server/routes/observability/grafanaProxyRouter.js +254 -0
- package/server/routes/payments/paymentsRouter.js +47 -0
- package/server/routes/static/staticPageRouter.js +30 -1
- package/server/utils/publicContact.js +31 -0
- package/utils/whatsapp/contactEnv.js +39 -0
- package/vite.config.mjs +5 -1
- package/app/modules/playModule/local/installYtDlp.js +0 -25
- package/app/modules/playModule/local/ytDlpInstaller.js +0 -28
|
@@ -8,7 +8,10 @@ const html = htm.bind(React.createElement);
|
|
|
8
8
|
|
|
9
9
|
const DEFAULT_API_BASE_PATH = '/api';
|
|
10
10
|
const DEFAULT_LOGIN_PATH = '/login';
|
|
11
|
+
const DEFAULT_PASSWORD_RESET_WEB_PATH = '/user/password-reset';
|
|
11
12
|
const DEFAULT_FALLBACK_AVATAR = '/assets/images/brand-logo-128.webp';
|
|
13
|
+
const DEFAULT_SUPPORT_WHATSAPP_NUMBER = '';
|
|
14
|
+
const DEFAULT_SUPPORT_WHATSAPP_URL = '/termos-de-uso/';
|
|
12
15
|
|
|
13
16
|
const TABS = [
|
|
14
17
|
{ key: 'summary', label: 'Estatísticas', icon: '📊' },
|
|
@@ -23,6 +26,31 @@ const shortNum = (value) =>
|
|
|
23
26
|
maximumFractionDigits: 1,
|
|
24
27
|
}).format(Math.max(0, Number(value) || 0));
|
|
25
28
|
|
|
29
|
+
const normalizeRoutePath = (value, fallback) => {
|
|
30
|
+
const raw = String(value || '').trim();
|
|
31
|
+
if (!raw) return fallback;
|
|
32
|
+
if (!raw.startsWith('/')) return fallback;
|
|
33
|
+
if (/^\/\//.test(raw)) return fallback;
|
|
34
|
+
return raw;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const normalizePhoneDigits = (value) =>
|
|
38
|
+
String(value || '')
|
|
39
|
+
.replace(/\D+/g, '')
|
|
40
|
+
.slice(0, 15);
|
|
41
|
+
|
|
42
|
+
const buildWhatsappUrl = (value) => {
|
|
43
|
+
const digits = normalizePhoneDigits(value);
|
|
44
|
+
if (!digits) return '';
|
|
45
|
+
return `https://wa.me/${digits}`;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const resolveSupportWhatsappUrl = (config) => {
|
|
49
|
+
const explicitUrl = String(config?.supportWhatsappUrl || '').trim();
|
|
50
|
+
if (/^https?:\/\/wa\.me\/\d{8,15}(?:\?.*)?$/i.test(explicitUrl)) return explicitUrl;
|
|
51
|
+
return buildWhatsappUrl(config?.supportWhatsappNumber) || DEFAULT_SUPPORT_WHATSAPP_URL;
|
|
52
|
+
};
|
|
53
|
+
|
|
26
54
|
const UserApp = ({ config }) => {
|
|
27
55
|
const [activeTab, setActiveTab] = useState('summary');
|
|
28
56
|
const [isLoading, setLoading] = useState(true);
|
|
@@ -30,6 +58,9 @@ const UserApp = ({ config }) => {
|
|
|
30
58
|
const [session, setSession] = useState(null);
|
|
31
59
|
const [isSidebarCollapsed, setSidebarCollapsed] = useState(false);
|
|
32
60
|
const [isMobileMenuOpen, setMobileMenuOpen] = useState(false);
|
|
61
|
+
const [passwordResetBusy, setPasswordResetBusy] = useState(false);
|
|
62
|
+
const [passwordResetError, setPasswordResetError] = useState('');
|
|
63
|
+
const [passwordResetInfo, setPasswordResetInfo] = useState('');
|
|
33
64
|
|
|
34
65
|
// Lock scroll when mobile menu is open
|
|
35
66
|
useEffect(() => {
|
|
@@ -102,6 +133,7 @@ const UserApp = ({ config }) => {
|
|
|
102
133
|
|
|
103
134
|
const rpgInfo = useMemo(() => summary?.rpg || { level: 1, xp: 0, gold: 0, karma: { score: 0, positive: 0, negative: 0 }, pvp: { matches: 0, wins: 0, losses: 0 }, inventory_count: 0, total_pokemons: 0 }, [summary]);
|
|
104
135
|
const usageInfo = useMemo(() => summary?.usage || { messages: 0, packs: 0, stickers: 0, activity_chart: [], insights: {}, first_message_at: null, last_message_at: null }, [summary]);
|
|
136
|
+
const supportWhatsappUrl = useMemo(() => resolveSupportWhatsappUrl(config), [config.supportWhatsappNumber, config.supportWhatsappUrl]);
|
|
105
137
|
|
|
106
138
|
const daysMember = useMemo(() => {
|
|
107
139
|
if (!rpgInfo.member_since) return 0;
|
|
@@ -122,6 +154,54 @@ const UserApp = ({ config }) => {
|
|
|
122
154
|
}
|
|
123
155
|
};
|
|
124
156
|
|
|
157
|
+
const startPasswordResetFlow = async () => {
|
|
158
|
+
if (passwordResetBusy) return;
|
|
159
|
+
setPasswordResetError('');
|
|
160
|
+
setPasswordResetInfo('');
|
|
161
|
+
setPasswordResetBusy(true);
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const response = await fetch(`${config.apiBasePath}/auth/password/recovery/session`, {
|
|
165
|
+
method: 'POST',
|
|
166
|
+
credentials: 'include',
|
|
167
|
+
headers: {
|
|
168
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
169
|
+
},
|
|
170
|
+
body: JSON.stringify({}),
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
let payload = null;
|
|
174
|
+
try {
|
|
175
|
+
payload = await response.json();
|
|
176
|
+
} catch {
|
|
177
|
+
payload = null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (!response.ok) {
|
|
181
|
+
throw new Error(payload?.error || `Falha HTTP ${response.status}`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const data = payload?.data || {};
|
|
185
|
+
const sessionToken = String(data?.session_token || '')
|
|
186
|
+
.trim()
|
|
187
|
+
.slice(0, 4096);
|
|
188
|
+
const sessionPath = normalizeRoutePath(data?.session_path, config.passwordResetWebPath || DEFAULT_PASSWORD_RESET_WEB_PATH);
|
|
189
|
+
const targetUrl = new URL(sessionPath, window.location.origin);
|
|
190
|
+
if (sessionToken) {
|
|
191
|
+
targetUrl.searchParams.set('session_token', sessionToken);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
setPasswordResetInfo('Sessão de redefinição criada. Redirecionando...');
|
|
195
|
+
window.setTimeout(() => {
|
|
196
|
+
window.location.assign(`${targetUrl.pathname}${targetUrl.search}`);
|
|
197
|
+
}, 120);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
setPasswordResetError(error?.message || 'Não foi possível iniciar a redefinição de senha.');
|
|
200
|
+
} finally {
|
|
201
|
+
setPasswordResetBusy(false);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
125
205
|
return html`
|
|
126
206
|
<style>
|
|
127
207
|
.sidebar-transition {
|
|
@@ -130,7 +210,7 @@ const UserApp = ({ config }) => {
|
|
|
130
210
|
transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
131
211
|
}
|
|
132
212
|
.content-transition {
|
|
133
|
-
transition:
|
|
213
|
+
transition: margin-left 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
134
214
|
}
|
|
135
215
|
</style>
|
|
136
216
|
|
|
@@ -145,7 +225,7 @@ const UserApp = ({ config }) => {
|
|
|
145
225
|
<div onClick=${() => setMobileMenuOpen(false)} className=${`fixed inset-0 z-[50] bg-[#020617]/80 lg:hidden transition-opacity duration-300 ${isMobileMenuOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}></div>
|
|
146
226
|
|
|
147
227
|
<!-- Navbar -->
|
|
148
|
-
<header className="
|
|
228
|
+
<header className="fixed inset-x-0 top-0 z-[40] border-b border-white/5 bg-[#020617]/80 backdrop-blur-xl">
|
|
149
229
|
<div className="px-4 lg:px-8">
|
|
150
230
|
<div className="flex h-16 items-center justify-between gap-4">
|
|
151
231
|
<div className="flex items-center gap-4">
|
|
@@ -171,9 +251,9 @@ const UserApp = ({ config }) => {
|
|
|
171
251
|
</div>
|
|
172
252
|
</header>
|
|
173
253
|
|
|
174
|
-
<div className="flex relative">
|
|
254
|
+
<div className="flex relative pt-16">
|
|
175
255
|
<!-- Sidebar -->
|
|
176
|
-
<aside className=${`fixed lg:
|
|
256
|
+
<aside className=${`fixed lg:fixed top-0 lg:top-[65px] lg:left-0 h-full lg:h-[calc(100vh-65px)] z-[60] lg:z-30 bg-[#020617] border-r border-white/5 sidebar-transition overflow-y-auto no-scrollbar ${isMobileMenuOpen ? 'translate-x-0 w-[280px]' : '-translate-x-full lg:translate-x-0'} ${isSidebarCollapsed ? 'lg:w-[85px]' : 'lg:w-[280px]'}`}>
|
|
177
257
|
<div className="p-4 flex flex-col h-full">
|
|
178
258
|
<!-- Mobile Header inside Sidebar -->
|
|
179
259
|
<div className="lg:hidden flex items-center justify-between mb-6 px-2">
|
|
@@ -240,7 +320,7 @@ const UserApp = ({ config }) => {
|
|
|
240
320
|
</aside>
|
|
241
321
|
|
|
242
322
|
<!-- Main Content -->
|
|
243
|
-
<main className=${`flex-1 min-w-0 content-transition px-4 lg:px-10 py-8 lg:py-12`}>
|
|
323
|
+
<main className=${`flex-1 min-w-0 content-transition px-4 lg:px-10 py-8 lg:py-12 ${isSidebarCollapsed ? 'lg:ml-[85px]' : 'lg:ml-[280px]'}`}>
|
|
244
324
|
<div className="max-w-5xl mx-auto space-y-10">
|
|
245
325
|
<div data-reveal="fade-up" className="flex flex-col md:flex-row md:items-end justify-between gap-6">
|
|
246
326
|
<div className="space-y-2">
|
|
@@ -361,37 +441,6 @@ const UserApp = ({ config }) => {
|
|
|
361
441
|
</div>
|
|
362
442
|
</div>
|
|
363
443
|
|
|
364
|
-
<!-- Activity Chart Section -->
|
|
365
|
-
${usageInfo.activity_chart && usageInfo.activity_chart.length > 0
|
|
366
|
-
? html`
|
|
367
|
-
<div className="p-8 lg:p-10 rounded-[3.5rem] bg-white/[0.02] border border-white/5 space-y-8 relative overflow-hidden">
|
|
368
|
-
<div className="flex items-center justify-between">
|
|
369
|
-
<h3 className="font-black text-xl flex items-center gap-3">
|
|
370
|
-
<span className="w-2 h-2 rounded-full bg-primary shadow-[0_0_10px_rgba(34,197,94,0.5)]"></span>
|
|
371
|
-
Fluxo de Atividade (7 dias)
|
|
372
|
-
</h3>
|
|
373
|
-
<span className="text-[9px] font-black uppercase text-white/20 tracking-widest">Update Realtime</span>
|
|
374
|
-
</div>
|
|
375
|
-
<div className="flex items-end justify-between gap-2 h-48 pt-4 px-2">
|
|
376
|
-
${usageInfo.activity_chart.map((data) => {
|
|
377
|
-
const maxCount = Math.max(...usageInfo.activity_chart.map((d) => d.count), 1);
|
|
378
|
-
const heightPercent = Math.max((data.count / maxCount) * 100, 5);
|
|
379
|
-
return html`
|
|
380
|
-
<div key=${data.day} className="flex flex-col items-center gap-3 flex-1 group min-w-0">
|
|
381
|
-
<div className="w-full relative flex justify-center h-full items-end">
|
|
382
|
-
<div className="w-full max-w-[2.5rem] bg-primary/10 hover:bg-primary transition-all rounded-t-xl group-hover:shadow-[0_0_30px_rgba(34,197,94,0.3)] relative" style=${{ height: heightPercent + '%' }}>
|
|
383
|
-
<div className="absolute -top-10 left-1/2 -translate-x-1/2 opacity-0 group-hover:opacity-100 transition-all bg-white text-[#020617] text-[10px] font-black px-2.5 py-1.5 rounded-xl pointer-events-none whitespace-nowrap z-20 shadow-xl translate-y-2 group-hover:translate-y-0">${data.count} msgs</div>
|
|
384
|
-
</div>
|
|
385
|
-
</div>
|
|
386
|
-
<span className="text-[8px] font-black text-white/20 uppercase tracking-tighter truncate w-full text-center">${data.day.split('-').reverse().slice(0, 2).join('/')}</span>
|
|
387
|
-
</div>
|
|
388
|
-
`;
|
|
389
|
-
})}
|
|
390
|
-
</div>
|
|
391
|
-
</div>
|
|
392
|
-
`
|
|
393
|
-
: null}
|
|
394
|
-
|
|
395
444
|
<!-- Details Card -->
|
|
396
445
|
<div className="p-8 lg:p-12 rounded-[3.5rem] bg-white/[0.03] border border-white/5 relative overflow-hidden">
|
|
397
446
|
<div className="absolute top-0 right-0 w-64 h-64 bg-primary/5 blur-[80px] rounded-full -translate-y-1/2 translate-x-1/2"></div>
|
|
@@ -407,7 +456,7 @@ const UserApp = ({ config }) => {
|
|
|
407
456
|
</div>
|
|
408
457
|
<div className="space-y-1.5">
|
|
409
458
|
<p className="text-[10px] font-black uppercase text-white/20 tracking-widest">WhatsApp Vinculado</p>
|
|
410
|
-
<p className="text-lg font-bold text-primary">${summary?.owner_phone ?
|
|
459
|
+
<p className="text-lg font-bold text-primary">${summary?.owner_phone ? formatPhone(summary.owner_phone) : 'Vincular Conta'}</p>
|
|
411
460
|
</div>
|
|
412
461
|
<div className="space-y-1.5">
|
|
413
462
|
<p className="text-[10px] font-black uppercase text-white/20 tracking-widest">Última Conexão</p>
|
|
@@ -518,16 +567,13 @@ const UserApp = ({ config }) => {
|
|
|
518
567
|
</div>
|
|
519
568
|
<div className="p-8 rounded-[3rem] bg-white/[0.03] border border-white/5 space-y-8">
|
|
520
569
|
<div className="space-y-4">
|
|
521
|
-
<
|
|
522
|
-
|
|
523
|
-
<input type="password" placeholder="Sua nova senha forte" className="w-full h-14 bg-[#020617] border border-white/10 rounded-2xl px-6 focus:border-primary outline-none transition-all font-mono text-sm" />
|
|
524
|
-
</div>
|
|
525
|
-
<div className="space-y-2">
|
|
526
|
-
<label className="text-[10px] font-black uppercase tracking-widest text-white/30 ml-4">Confirmar Senha</label>
|
|
527
|
-
<input type="password" placeholder="Repita a nova senha" className="w-full h-14 bg-[#020617] border border-white/10 rounded-2xl px-6 focus:border-primary outline-none transition-all font-mono text-sm" />
|
|
528
|
-
</div>
|
|
570
|
+
<p className="text-sm text-white/60 leading-relaxed">Para alterar sua senha com segurança, o OmniZap envia um código de verificação para o e-mail vinculado à sua conta.</p>
|
|
571
|
+
<div className="rounded-2xl border border-white/10 bg-white/[0.02] px-4 py-3 text-xs text-white/50">Fluxo: criar sessão de redefinição → receber código por e-mail → confirmar nova senha.</div>
|
|
529
572
|
</div>
|
|
530
|
-
|
|
573
|
+
|
|
574
|
+
<button type="button" className="btn btn-primary btn-block h-14 rounded-2xl font-black uppercase text-[10px] tracking-[0.2em] shadow-xl shadow-primary/20" disabled=${passwordResetBusy} onClick=${startPasswordResetFlow}>${passwordResetBusy ? 'Preparando redefinição...' : 'Alterar Senha com Verificação'}</button>
|
|
575
|
+
|
|
576
|
+
${passwordResetInfo ? html` <div className="rounded-2xl border border-emerald-400/30 bg-emerald-500/10 px-4 py-3 text-xs font-semibold text-emerald-300">${passwordResetInfo}</div> ` : null} ${passwordResetError ? html` <div className="rounded-2xl border border-red-400/30 bg-red-500/10 px-4 py-3 text-xs font-semibold text-red-300">${passwordResetError}</div> ` : null}
|
|
531
577
|
</div>
|
|
532
578
|
</div>
|
|
533
579
|
</div>
|
|
@@ -541,7 +587,7 @@ const UserApp = ({ config }) => {
|
|
|
541
587
|
</div>
|
|
542
588
|
<h3 className="text-3xl font-black tracking-tighter mb-4">Central de Atendimento</h3>
|
|
543
589
|
<p className="text-white/40 font-medium leading-relaxed mb-10 text-lg">Dúvidas sobre o sistema, planos ou bugs? Fale diretamente com nossa equipe técnica.</p>
|
|
544
|
-
<a href
|
|
590
|
+
<a href=${supportWhatsappUrl} target="_blank" className="btn btn-primary btn-lg btn-block rounded-[2rem] font-black uppercase text-xs tracking-widest h-16 shadow-2xl shadow-primary/20 hover:scale-[1.02] active:scale-95 transition-all">Iniciar Chat Suporte</a>
|
|
545
591
|
</div>
|
|
546
592
|
`}
|
|
547
593
|
</div>
|
|
@@ -567,7 +613,10 @@ if (rootElement) {
|
|
|
567
613
|
const config = {
|
|
568
614
|
apiBasePath: rootElement.dataset.apiBasePath || DEFAULT_API_BASE_PATH,
|
|
569
615
|
loginPath: rootElement.dataset.loginPath || DEFAULT_LOGIN_PATH,
|
|
616
|
+
passwordResetWebPath: normalizeRoutePath(rootElement.dataset.passwordResetWebPath, DEFAULT_PASSWORD_RESET_WEB_PATH),
|
|
570
617
|
fallbackAvatar: DEFAULT_FALLBACK_AVATAR,
|
|
618
|
+
supportWhatsappNumber: rootElement.dataset.supportWhatsappNumber || DEFAULT_SUPPORT_WHATSAPP_NUMBER,
|
|
619
|
+
supportWhatsappUrl: rootElement.dataset.supportWhatsappUrl || DEFAULT_SUPPORT_WHATSAPP_URL,
|
|
571
620
|
};
|
|
572
621
|
createRoot(rootElement).render(html`<${UserApp} config=${config} />`);
|
|
573
622
|
}
|