@omnizap-system/omnizap 2.5.12
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/.clusterfuzzlite/Dockerfile +10 -0
- package/.env.example +907 -0
- package/.github/codeql/codeql-config.yml +10 -0
- package/.github/dependabot.yml +35 -0
- package/.github/workflows/ci.yml +73 -0
- package/.github/workflows/codeql.yml +106 -0
- package/.github/workflows/db-migration-check.yml +98 -0
- package/.github/workflows/dependency-review.yml +22 -0
- package/.github/workflows/deploy.yml +95 -0
- package/.github/workflows/release.yml +106 -0
- package/.github/workflows/security-attest-provenance.yml +51 -0
- package/.github/workflows/security-gitleaks.yml +34 -0
- package/.github/workflows/security-runner-hardening.yml +31 -0
- package/.github/workflows/security-scorecard.yml +44 -0
- package/.github/workflows/security-zap-baseline.yml +44 -0
- package/.github/workflows/security-zap-full-scan.yml +43 -0
- package/.github/workflows/security-zizmor.yml +36 -0
- package/.github/workflows/wiki-sync.yml +44 -0
- package/.gitleaks.toml +15 -0
- package/.prettierrc +34 -0
- package/CODE_OF_CONDUCT.md +114 -0
- package/LICENSE +56 -0
- package/README.md +110 -0
- package/SECURITY.md +110 -0
- package/app/config/index.js +4 -0
- package/app/configParts/adminIdentity.js +92 -0
- package/app/configParts/baileysConfig.js +1818 -0
- package/app/configParts/groupUtils.js +692 -0
- package/app/configParts/loggerConfig.js +394 -0
- package/app/configParts/messagePersistenceService.js +305 -0
- package/app/connection/baileysCompatibility.test.js +40 -0
- package/app/connection/baileysDbAuthState.js +344 -0
- package/app/connection/socketController.js +2243 -0
- package/app/controllers/messageController.js +7 -0
- package/app/controllers/messagePipeline/commandMiddleware.js +146 -0
- package/app/controllers/messagePipeline/conversationMiddleware.js +183 -0
- package/app/controllers/messagePipeline/messagePipelineMiddlewares.test.js +522 -0
- package/app/controllers/messagePipeline/postProcessingMiddleware.js +41 -0
- package/app/controllers/messagePipeline/preProcessingMiddlewares.js +166 -0
- package/app/controllers/messageProcessingPipeline.js +699 -0
- package/app/modules/adminModule/AGENT.md +4056 -0
- package/app/modules/adminModule/adminAiHelpService.js +56 -0
- package/app/modules/adminModule/adminConfigRuntime.js +177 -0
- package/app/modules/adminModule/commandConfig.json +7122 -0
- package/app/modules/adminModule/groupCommandHandlers.js +1823 -0
- package/app/modules/adminModule/groupCommandHandlers.test.js +350 -0
- package/app/modules/adminModule/groupEventHandlers.js +399 -0
- package/app/modules/aiModule/AGENT.md +547 -0
- package/app/modules/aiModule/aiAiHelpService.js +14 -0
- package/app/modules/aiModule/aiConfigRuntime.js +135 -0
- package/app/modules/aiModule/catCommand.js +967 -0
- package/app/modules/aiModule/commandConfig.json +981 -0
- package/app/modules/analyticsModule/messageAnalysisEventRepository.js +83 -0
- package/app/modules/gameModule/AGENT.md +196 -0
- package/app/modules/gameModule/commandConfig.json +366 -0
- package/app/modules/gameModule/diceCommand.js +42 -0
- package/app/modules/gameModule/gameAiHelpService.js +14 -0
- package/app/modules/gameModule/gameConfigRuntime.js +68 -0
- package/app/modules/menuModule/AGENT.md +205 -0
- package/app/modules/menuModule/commandConfig.json +366 -0
- package/app/modules/menuModule/common.js +316 -0
- package/app/modules/menuModule/menuAiHelpService.js +14 -0
- package/app/modules/menuModule/menuConfigRuntime.js +68 -0
- package/app/modules/menuModule/menus.js +66 -0
- package/app/modules/playModule/AGENT.md +321 -0
- package/app/modules/playModule/commandConfig.json +584 -0
- package/app/modules/playModule/playAiHelpService.js +14 -0
- package/app/modules/playModule/playCommand.js +1417 -0
- package/app/modules/playModule/playConfigRuntime.js +68 -0
- package/app/modules/quoteModule/AGENT.md +199 -0
- package/app/modules/quoteModule/commandConfig.json +366 -0
- package/app/modules/quoteModule/quoteAiHelpService.js +14 -0
- package/app/modules/quoteModule/quoteCommand.js +842 -0
- package/app/modules/quoteModule/quoteConfigRuntime.js +68 -0
- package/app/modules/rpgPokemonModule/AGENT.md +229 -0
- package/app/modules/rpgPokemonModule/commandConfig.json +386 -0
- package/app/modules/rpgPokemonModule/rpgBattleCanvasRenderer.js +795 -0
- package/app/modules/rpgPokemonModule/rpgBattleService.js +2110 -0
- package/app/modules/rpgPokemonModule/rpgBattleService.test.js +770 -0
- package/app/modules/rpgPokemonModule/rpgEvolutionUtils.js +22 -0
- package/app/modules/rpgPokemonModule/rpgPokemonAiHelpService.js +14 -0
- package/app/modules/rpgPokemonModule/rpgPokemonCommand.js +174 -0
- package/app/modules/rpgPokemonModule/rpgPokemonConfigRuntime.js +68 -0
- package/app/modules/rpgPokemonModule/rpgPokemonDomain.js +192 -0
- package/app/modules/rpgPokemonModule/rpgPokemonDomain.test.js +93 -0
- package/app/modules/rpgPokemonModule/rpgPokemonEvolution.test.js +46 -0
- package/app/modules/rpgPokemonModule/rpgPokemonMessages.js +746 -0
- package/app/modules/rpgPokemonModule/rpgPokemonRepository.js +1847 -0
- package/app/modules/rpgPokemonModule/rpgPokemonService.js +6839 -0
- package/app/modules/rpgPokemonModule/rpgProfileCanvasRenderer.js +354 -0
- package/app/modules/statsModule/AGENT.md +320 -0
- package/app/modules/statsModule/commandConfig.json +540 -0
- package/app/modules/statsModule/globalRankingCommand.js +64 -0
- package/app/modules/statsModule/rankingCommand.js +41 -0
- package/app/modules/statsModule/rankingCommon.js +1305 -0
- package/app/modules/statsModule/statsAiHelpService.js +14 -0
- package/app/modules/statsModule/statsConfigRuntime.js +68 -0
- package/app/modules/stickerModule/AGENT.md +692 -0
- package/app/modules/stickerModule/addStickerMetadata.js +239 -0
- package/app/modules/stickerModule/commandConfig.json +1216 -0
- package/app/modules/stickerModule/convertToWebp.js +367 -0
- package/app/modules/stickerModule/stickerAiHelpService.js +14 -0
- package/app/modules/stickerModule/stickerCommand.js +446 -0
- package/app/modules/stickerModule/stickerConfigRuntime.js +68 -0
- package/app/modules/stickerModule/stickerConvertCommand.js +159 -0
- package/app/modules/stickerModule/stickerTextCommand.js +653 -0
- package/app/modules/stickerPackModule/AGENT.md +215 -0
- package/app/modules/stickerPackModule/autoPackCollectorRuntime.js +20 -0
- package/app/modules/stickerPackModule/autoPackCollectorService.js +357 -0
- package/app/modules/stickerPackModule/commandConfig.json +387 -0
- package/app/modules/stickerPackModule/domainEventOutboxRepository.js +227 -0
- package/app/modules/stickerPackModule/domainEvents.js +52 -0
- package/app/modules/stickerPackModule/semanticReclassificationEngine.js +429 -0
- package/app/modules/stickerPackModule/semanticReclassificationEngine.test.js +75 -0
- package/app/modules/stickerPackModule/semanticThemeClusterService.js +544 -0
- package/app/modules/stickerPackModule/stickerAssetClassificationRepository.js +400 -0
- package/app/modules/stickerPackModule/stickerAssetRepository.js +400 -0
- package/app/modules/stickerPackModule/stickerAssetReprocessQueueRepository.js +175 -0
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +3702 -0
- package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +559 -0
- package/app/modules/stickerPackModule/stickerClassificationService.js +557 -0
- package/app/modules/stickerPackModule/stickerDedicatedTaskWorkerRuntime.js +249 -0
- package/app/modules/stickerPackModule/stickerDomainEventBus.js +65 -0
- package/app/modules/stickerPackModule/stickerDomainEventConsumerRuntime.js +208 -0
- package/app/modules/stickerPackModule/stickerMarketplaceDriftService.js +99 -0
- package/app/modules/stickerPackModule/stickerObjectStorageService.js +285 -0
- package/app/modules/stickerPackModule/stickerPackAiHelpService.js +14 -0
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +1148 -0
- package/app/modules/stickerPackModule/stickerPackConfigRuntime.js +68 -0
- package/app/modules/stickerPackModule/stickerPackEngagementRepository.js +152 -0
- package/app/modules/stickerPackModule/stickerPackErrors.js +30 -0
- package/app/modules/stickerPackModule/stickerPackInteractionEventRepository.js +101 -0
- package/app/modules/stickerPackModule/stickerPackItemRepository.js +432 -0
- package/app/modules/stickerPackModule/stickerPackMarketplaceService.js +313 -0
- package/app/modules/stickerPackModule/stickerPackMessageService.js +268 -0
- package/app/modules/stickerPackModule/stickerPackRepository.js +450 -0
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRepository.js +179 -0
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRuntime.js +271 -0
- package/app/modules/stickerPackModule/stickerPackService.js +733 -0
- package/app/modules/stickerPackModule/stickerPackServiceRuntime.js +32 -0
- package/app/modules/stickerPackModule/stickerPackUtils.js +107 -0
- package/app/modules/stickerPackModule/stickerStorageService.js +559 -0
- package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +242 -0
- package/app/modules/stickerPackModule/stickerWorkerTaskQueueRepository.js +242 -0
- package/app/modules/systemMetricsModule/AGENT.md +193 -0
- package/app/modules/systemMetricsModule/commandConfig.json +344 -0
- package/app/modules/systemMetricsModule/pingCommand.js +399 -0
- package/app/modules/systemMetricsModule/systemMetricsAiHelpService.js +14 -0
- package/app/modules/systemMetricsModule/systemMetricsConfigRuntime.js +68 -0
- package/app/modules/tiktokModule/AGENT.md +196 -0
- package/app/modules/tiktokModule/commandConfig.json +366 -0
- package/app/modules/tiktokModule/tiktokAiHelpService.js +14 -0
- package/app/modules/tiktokModule/tiktokCommand.js +716 -0
- package/app/modules/tiktokModule/tiktokConfigRuntime.js +68 -0
- package/app/modules/userModule/AGENT.md +200 -0
- package/app/modules/userModule/commandConfig.json +386 -0
- package/app/modules/userModule/userAiHelpService.js +14 -0
- package/app/modules/userModule/userCommand.js +1155 -0
- package/app/modules/userModule/userConfigRuntime.js +68 -0
- package/app/modules/waifuPicsModule/AGENT.md +431 -0
- package/app/modules/waifuPicsModule/commandConfig.json +780 -0
- package/app/modules/waifuPicsModule/waifuPicsAiHelpService.js +14 -0
- package/app/modules/waifuPicsModule/waifuPicsCommand.js +586 -0
- package/app/modules/waifuPicsModule/waifuPicsConfigRuntime.js +68 -0
- package/app/observability/metrics.js +766 -0
- package/app/services/ai/aiHelpResponseCacheRepository.js +280 -0
- package/app/services/ai/aiLearningRepository.js +400 -0
- package/app/services/ai/commandConfigEnrichmentRepository.js +769 -0
- package/app/services/ai/commandConfigEnrichmentService.js +452 -0
- package/app/services/ai/commandConfigValidationService.js +443 -0
- package/app/services/ai/commandToolBuilderService.js +192 -0
- package/app/services/ai/conversationRouterService.js +516 -0
- package/app/services/ai/geminiService.js +115 -0
- package/app/services/ai/geminiService.test.js +87 -0
- package/app/services/ai/globalModuleAiHelpService.js +1412 -0
- package/app/services/ai/globalToolCallingService.js +203 -0
- package/app/services/ai/messageCommandExecutionService.js +391 -0
- package/app/services/ai/moduleAiHelpCoreService.js +1099 -0
- package/app/services/ai/moduleAiHelpWrapperFactory.js +65 -0
- package/app/services/ai/moduleCommandConfigRuntimeService.js +113 -0
- package/app/services/ai/moduleToolExecutorService.js +464 -0
- package/app/services/ai/moduleToolRegistryService.js +178 -0
- package/app/services/ai/toolCandidateSelectorService.js +781 -0
- package/app/services/auth/googleWebLinkService.js +80 -0
- package/app/services/auth/whatsappLoginLinkService.js +230 -0
- package/app/services/external/pokeApiService.js +398 -0
- package/app/services/group/groupMetadataService.js +311 -0
- package/app/services/infra/dbWriteQueue.js +874 -0
- package/app/services/infra/featureFlagService.js +131 -0
- package/app/services/infra/queueUtils.js +55 -0
- package/app/services/messaging/captchaService.js +491 -0
- package/app/services/messaging/messagePersistenceService.js +1 -0
- package/app/services/messaging/newsBroadcastService.js +347 -0
- package/app/services/sticker/stickerFocusService.js +347 -0
- package/app/services/sticker/stickerFocusService.test.js +43 -0
- package/app/store/aiPromptStore.js +38 -0
- package/app/store/conversationSessionStore.js +131 -0
- package/app/store/groupConfigStore.js +58 -0
- package/app/store/premiumUserStore.js +54 -0
- package/app/utils/antiLink/antiLinkModule.js +700 -0
- package/app/utils/http/getImageBufferModule.js +18 -0
- package/app/utils/json/jsonSanitizer.js +113 -0
- package/app/utils/json/jsonSanitizer.test.js +40 -0
- package/app/utils/systemMetrics/systemMetricsModule.js +88 -0
- package/app/workers/aiLearningWorker.js +605 -0
- package/app/workers/commandConfigEnrichmentWorker.js +242 -0
- package/database/index.js +2075 -0
- package/database/init.js +151 -0
- package/database/migrations/.gitkeep +0 -0
- package/database/migrations/20260307_d0_hardening_down.sql +64 -0
- package/database/migrations/20260307_d0_hardening_up.sql +79 -0
- package/database/migrations/20260307_d1_terms_acceptance_down.sql +11 -0
- package/database/migrations/20260307_d1_terms_acceptance_up.sql +37 -0
- package/database/migrations/20260307_d2_auth_hardening_down.sql +75 -0
- package/database/migrations/20260307_d2_auth_hardening_up.sql +100 -0
- package/database/migrations/20260314_d7_canonical_sender_down.sql +53 -0
- package/database/migrations/20260314_d7_canonical_sender_up.sql +114 -0
- package/database/migrations/20260406_d30_security_analytics_down.sql +95 -0
- package/database/migrations/20260406_d30_security_analytics_up.sql +292 -0
- package/database/migrations/20260407_d31_web_google_session_token_hardening_down.sql +2 -0
- package/database/migrations/20260407_d31_web_google_session_token_hardening_up.sql +17 -0
- package/database/migrations/20260408_d32_ai_help_response_cache_down.sql +1 -0
- package/database/migrations/20260408_d32_ai_help_response_cache_up.sql +22 -0
- package/database/migrations/20260409_d33_ai_learning_tables_down.sql +4 -0
- package/database/migrations/20260409_d33_ai_learning_tables_up.sql +52 -0
- package/database/migrations/20260410_d34_command_config_enrichment_down.sql +3 -0
- package/database/migrations/20260410_d34_command_config_enrichment_up.sql +48 -0
- package/database/schema.sql +1186 -0
- package/docker-compose.yml +104 -0
- package/docs/audits/stickerCatalogController-out-of-scope.md +103 -0
- package/docs/audits/stickerCatalogController-symbols.md +58 -0
- package/docs/compliance/acceptable-use-policy-2026-03-07.md +35 -0
- package/docs/compliance/dpa-b2b-standard-2026-03-07.md +80 -0
- package/docs/compliance/monthly-compliance-checklist-2026-03-07.md +88 -0
- package/docs/compliance/notice-and-takedown-policy-2026-03-07.md +34 -0
- package/docs/compliance/privacy-policy-2026-03-07.md +75 -0
- package/docs/compliance/subprocessors-inventory-2026-03-07.md +16 -0
- package/docs/database/production-db-evolution-runbook-2026q1.md +365 -0
- package/docs/security/dsar-lgpd-runbook-2026-03-07.md +86 -0
- package/docs/security/incident-response-lgpd-anpd-runbook-2026-03-07.md +77 -0
- package/docs/security/network-hardening-runbook-2026-03-07.md +137 -0
- package/docs/seo/omnizap-seo-playbook-br-2026-02-28.md +238 -0
- package/docs/seo/satellite-page-template.md +116 -0
- package/docs/seo/satellite-pages-phase1.json +364 -0
- package/docs/wiki/Home.md +120 -0
- package/docs/wiki/pair-extraordinaire-2026-03-08.md +3 -0
- package/docs/wiki/recent-changes-2026-03-08.md +47 -0
- package/ecosystem.prod.config.cjs +135 -0
- package/eslint.config.js +89 -0
- package/index.js +488 -0
- package/ml/clip_classifier/Dockerfile +18 -0
- package/ml/clip_classifier/README.md +118 -0
- package/ml/clip_classifier/adaptive_scoring.py +40 -0
- package/ml/clip_classifier/classifier.py +654 -0
- package/ml/clip_classifier/embedding_store.py +481 -0
- package/ml/clip_classifier/env_loader.py +15 -0
- package/ml/clip_classifier/llm_label_expander.py +144 -0
- package/ml/clip_classifier/main.py +213 -0
- package/ml/clip_classifier/requirements.txt +10 -0
- package/ml/clip_classifier/similarity_engine.py +74 -0
- package/new-logo.png +0 -0
- package/observability/alert-rules.yml +60 -0
- package/observability/grafana/dashboards/omnizap-mysql.json +136 -0
- package/observability/grafana/dashboards/omnizap-overview.json +170 -0
- package/observability/grafana/provisioning/dashboards/dashboards.yml +11 -0
- package/observability/grafana/provisioning/datasources/datasources.yml +15 -0
- package/observability/loki-config.yml +38 -0
- package/observability/mysql-setup.sql +46 -0
- package/observability/prometheus.yml +35 -0
- package/observability/promtail-config.yml +84 -0
- package/observability/sticker-catalog-slo.md +83 -0
- package/observability/sticker-scale-hardening-rollout.md +128 -0
- package/package.json +144 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/assets/css/commands-react.input.css +71 -0
- package/public/assets/css/create-pack-react.input.css +31 -0
- package/public/assets/css/home-react.input.css +106 -0
- package/public/assets/css/login-react.input.css +58 -0
- package/public/assets/css/stickers-react.input.css +18 -0
- package/public/assets/css/terms-react.input.css +115 -0
- package/public/assets/css/user-react.input.css +57 -0
- package/public/assets/images/brand-icon-192.png +0 -0
- package/public/assets/images/brand-logo-128.webp +0 -0
- package/public/assets/images/hero-banner-1280.jpg +0 -0
- package/public/comandos/commands-catalog.json +4517 -0
- package/public/css/api-docs.css +161 -0
- package/public/css/stickers-admin.css +1288 -0
- package/public/css/styles.css +679 -0
- package/public/css/systemadm/admin.css +474 -0
- package/public/css/systemadm/base.css +73 -0
- package/public/css/systemadm/components.css +662 -0
- package/public/css/systemadm/layout.css +229 -0
- package/public/css/systemadm/tokens.css +56 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/js/apps/apiDocsApp.js +235 -0
- package/public/js/apps/commandsReactApp.js +528 -0
- package/public/js/apps/createPackApp.js +1646 -0
- package/public/js/apps/homeReactApp.js +942 -0
- package/public/js/apps/loginReactApp.js +496 -0
- package/public/js/apps/stickersAdminApp.js +1753 -0
- package/public/js/apps/stickersApp.js +3797 -0
- package/public/js/apps/termsReactApp.js +528 -0
- package/public/js/apps/userApp.js +2540 -0
- package/public/js/apps/userProfile/actions.js +66 -0
- package/public/js/apps/userReactApp.js +547 -0
- package/public/js/catalog.js +950 -0
- package/public/pages/api-docs.html +40 -0
- package/public/pages/aup.html +158 -0
- package/public/pages/comandos.html +41 -0
- package/public/pages/dpa.html +227 -0
- package/public/pages/home.html +45 -0
- package/public/pages/licenca.html +182 -0
- package/public/pages/login.html +40 -0
- package/public/pages/notice-and-takedown.html +234 -0
- package/public/pages/politica-de-privacidade.html +251 -0
- package/public/pages/seo-bot-whatsapp-para-grupo.html +350 -0
- package/public/pages/seo-bot-whatsapp-sem-programar.html +350 -0
- package/public/pages/seo-como-automatizar-avisos-no-whatsapp.html +350 -0
- package/public/pages/seo-como-criar-comandos-whatsapp.html +350 -0
- package/public/pages/seo-como-evitar-spam-no-whatsapp.html +350 -0
- package/public/pages/seo-como-moderar-grupo-whatsapp.html +350 -0
- package/public/pages/seo-como-organizar-comunidade-whatsapp.html +350 -0
- package/public/pages/seo-melhor-bot-whatsapp-para-grupos.html +350 -0
- package/public/pages/stickers-admin.html +31 -0
- package/public/pages/stickers-create.html +41 -0
- package/public/pages/stickers.html +45 -0
- package/public/pages/suboperadores.html +237 -0
- package/public/pages/termos-de-uso-texto-integral.html +241 -0
- package/public/pages/termos-de-uso.html +41 -0
- package/public/pages/user-password-reset.html +32 -0
- package/public/pages/user-systemadm.html +508 -0
- package/public/pages/user.html +39 -0
- package/public/robots.txt +9 -0
- package/public/site.webmanifest +24 -0
- package/public/sitemap.xml +98 -0
- package/schemas/command-config.schema.json +582 -0
- package/scripts/baileys-compat-smoke.mjs +12 -0
- package/scripts/cache-bust.mjs +142 -0
- package/scripts/deploy.sh +916 -0
- package/scripts/email-broadcast-terms-update.mjs +170 -0
- package/scripts/enrich-command-discovery-fields.mjs +286 -0
- package/scripts/generate-command-config-schema.mjs +273 -0
- package/scripts/generate-commands-catalog.mjs +308 -0
- package/scripts/generate-module-agents.mjs +631 -0
- package/scripts/generate-seo-satellite-pages.mjs +400 -0
- package/scripts/github-deploy-notify.mjs +174 -0
- package/scripts/github-release-notify.mjs +219 -0
- package/scripts/release.sh +599 -0
- package/scripts/run-codeql-local.sh +116 -0
- package/scripts/run-prettier-all.mjs +25 -0
- package/scripts/security-smoketest.mjs +581 -0
- package/scripts/sticker-catalog-loadtest.mjs +210 -0
- package/scripts/sticker-worker-task.mjs +119 -0
- package/scripts/sync-readme-snapshot.mjs +133 -0
- package/scripts/validate-command-config-schema.mjs +130 -0
- package/scripts/validate-command-configs.mjs +15 -0
- package/scripts/wiki-sync.sh +191 -0
- package/server/auth/googleWebAuth/googleWebAuthRuntime.js +62 -0
- package/server/auth/googleWebAuth/googleWebAuthService.js +807 -0
- package/server/auth/jwt/webJwtService.js +147 -0
- package/server/auth/stickerCatalogAuthContext.js +165 -0
- package/server/auth/termsAcceptance/termsAcceptanceHandler.js +189 -0
- package/server/auth/userPassword/index.js +14 -0
- package/server/auth/userPassword/userPasswordAuthService.js +422 -0
- package/server/auth/userPassword/userPasswordCrypto.js +199 -0
- package/server/auth/userPassword/userPasswordCrypto.test.js +76 -0
- package/server/auth/userPassword/userPasswordRecoveryService.js +728 -0
- package/server/auth/validation/authSchemas.js +236 -0
- package/server/auth/webAccount/webAccountHandlers.js +1434 -0
- package/server/controllers/admin/adminBanService.js +138 -0
- package/server/controllers/admin/adminPanelHandlers.js +2083 -0
- package/server/controllers/admin/stickerCatalogAdminContext.js +17 -0
- package/server/controllers/admin/systemAdminController.js +201 -0
- package/server/controllers/email/emailAutomationController.js +239 -0
- package/server/controllers/metricsController.js +21 -0
- package/server/controllers/seo/stickerCatalogSeoContext.js +514 -0
- package/server/controllers/sticker/nonCatalogHandlers.js +303 -0
- package/server/controllers/sticker/stickerCatalogController.js +4700 -0
- package/server/controllers/system/contactController.js +115 -0
- package/server/controllers/system/githubController.js +137 -0
- package/server/controllers/system/stickerCatalogSystemContext.js +758 -0
- package/server/controllers/system/storageController.js +154 -0
- package/server/controllers/system/systemController.js +135 -0
- package/server/controllers/system/systemMetricsController.js +156 -0
- package/server/controllers/system/visitController.js +90 -0
- package/server/controllers/userController.js +145 -0
- package/server/email/emailAutomationRuntime.js +225 -0
- package/server/email/emailAutomationService.js +125 -0
- package/server/email/emailOutboxRepository.js +282 -0
- package/server/email/emailTemplateService.js +480 -0
- package/server/email/emailTransportService.js +156 -0
- package/server/http/clientIp.js +95 -0
- package/server/http/httpRequestUtils.js +262 -0
- package/server/http/httpRequestUtils.test.js +80 -0
- package/server/http/httpServer.js +180 -0
- package/server/http/requestContext.js +20 -0
- package/server/http/siteRoutingUtils.js +87 -0
- package/server/index.js +1 -0
- package/server/middleware/cachePolicy.js +26 -0
- package/server/middleware/cachePolicyHelpers.js +1 -0
- package/server/middleware/endpointRateLimit.js +181 -0
- package/server/middleware/rateLimit.js +70 -0
- package/server/middleware/requireAdminAuth.js +48 -0
- package/server/middleware/securityHeaders.js +97 -0
- package/server/routes/admin/systemAdminRouter.js +64 -0
- package/server/routes/email/emailAutomationRouter.js +46 -0
- package/server/routes/health/healthRouter.js +41 -0
- package/server/routes/indexRouter.js +234 -0
- package/server/routes/metrics/metricsRouter.js +58 -0
- package/server/routes/static/staticPageRouter.js +134 -0
- package/server/routes/sticker/catalogHandlers/catalogAdminHttp.js +105 -0
- package/server/routes/sticker/catalogHandlers/catalogAuthHttp.js +77 -0
- package/server/routes/sticker/catalogHandlers/catalogPublicHttp.js +120 -0
- package/server/routes/sticker/catalogHandlers/catalogUploadHttp.js +83 -0
- package/server/routes/sticker/catalogRouter.js +77 -0
- package/server/routes/sticker/stickerApiRouter.js +84 -0
- package/server/routes/sticker/stickerDataRouter.js +145 -0
- package/server/routes/sticker/stickerSiteRouter.js +43 -0
- package/server/routes/user/userApiPaths.js +66 -0
- package/server/routes/user/userRouter.js +65 -0
- package/server/utils/safePath.js +26 -0
- package/utils/logger/loggerModule.js +35 -0
- package/vite.config.mjs +38 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } 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 GOOGLE_GSI_SCRIPT_SRC = 'https://accounts.google.com/gsi/client';
|
|
8
|
+
const DEFAULT_TERMS_URL = '/termos-de-uso/';
|
|
9
|
+
const DEFAULT_PRIVACY_URL = '/politica-de-privacidade/';
|
|
10
|
+
const DEFAULT_AUP_URL = '/aup/';
|
|
11
|
+
const DEFAULT_API_BASE_PATH = '/api';
|
|
12
|
+
const DEFAULT_PANEL_PATH = '/user/';
|
|
13
|
+
const DEFAULT_WHATSAPP_LOGIN_TRIGGER = 'iniciar';
|
|
14
|
+
const FALLBACK_THUMB_URL = '/assets/images/brand-logo-128.webp';
|
|
15
|
+
|
|
16
|
+
const LEGAL_DOCS = [
|
|
17
|
+
{ href: DEFAULT_TERMS_URL, label: 'Termos' },
|
|
18
|
+
{ href: DEFAULT_PRIVACY_URL, label: 'Privacidade' },
|
|
19
|
+
{ href: DEFAULT_AUP_URL, label: 'AUP' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const normalizeDigits = (value) => String(value || '').replace(/\D+/g, '');
|
|
23
|
+
|
|
24
|
+
const formatPhone = (digits) => {
|
|
25
|
+
const value = normalizeDigits(digits);
|
|
26
|
+
if (!value) return '';
|
|
27
|
+
if (value.length <= 4) return value;
|
|
28
|
+
return `${value.slice(0, 2)} ${value.slice(2, -4)}-${value.slice(-4)}`.trim();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const normalizeRoutePath = (value, fallback = DEFAULT_PANEL_PATH) => {
|
|
32
|
+
const raw = String(value || '').trim();
|
|
33
|
+
if (!raw) return fallback;
|
|
34
|
+
if (!raw.startsWith('/')) return fallback;
|
|
35
|
+
if (/^\/\//.test(raw)) return fallback;
|
|
36
|
+
return raw;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const readWhatsAppHintFromSearch = (search) => {
|
|
40
|
+
const params = new URLSearchParams(search || '');
|
|
41
|
+
const phone = normalizeDigits(params.get('wa') || '');
|
|
42
|
+
const ts = String(params.get('wa_ts') || '').trim();
|
|
43
|
+
const sig = String(params.get('wa_sig') || '').trim();
|
|
44
|
+
return {
|
|
45
|
+
hasPayload: Boolean(phone || ts || sig),
|
|
46
|
+
phone,
|
|
47
|
+
ts,
|
|
48
|
+
sig,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const resolveLoginConfig = (rootElement) => {
|
|
53
|
+
const apiBasePath = String(rootElement?.dataset?.apiBasePath || DEFAULT_API_BASE_PATH).trim() || DEFAULT_API_BASE_PATH;
|
|
54
|
+
const panelPath = normalizeRoutePath(rootElement?.dataset?.panelPath, DEFAULT_PANEL_PATH);
|
|
55
|
+
return { apiBasePath, panelPath };
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const buildWhatsAppLoginUrl = (phoneDigits, loginText = DEFAULT_WHATSAPP_LOGIN_TRIGGER) => {
|
|
59
|
+
const params = new URLSearchParams({
|
|
60
|
+
text: String(loginText || DEFAULT_WHATSAPP_LOGIN_TRIGGER).trim() || DEFAULT_WHATSAPP_LOGIN_TRIGGER,
|
|
61
|
+
type: 'custom_url',
|
|
62
|
+
app_absent: '0',
|
|
63
|
+
});
|
|
64
|
+
const digits = normalizeDigits(phoneDigits);
|
|
65
|
+
if (digits) {
|
|
66
|
+
params.set('phone', digits);
|
|
67
|
+
}
|
|
68
|
+
return `https://api.whatsapp.com/send/?${params.toString()}`;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const isAuthenticatedSession = (sessionData) => {
|
|
72
|
+
const authenticated =
|
|
73
|
+
sessionData?.authenticated === true ||
|
|
74
|
+
sessionData?.authenticated === 1 ||
|
|
75
|
+
String(sessionData?.authenticated || '')
|
|
76
|
+
.trim()
|
|
77
|
+
.toLowerCase() === 'true';
|
|
78
|
+
if (!authenticated) return false;
|
|
79
|
+
return Boolean(sessionData?.owner_jid || sessionData?.owner_phone || sessionData?.user?.sub);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const buildGoogleAuthPayload = (credential, hint) => {
|
|
83
|
+
const payload = {
|
|
84
|
+
google_id_token: String(credential || '').trim(),
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
if (hint.phone) payload.wa = hint.phone;
|
|
88
|
+
if (hint.ts) payload.wa_ts = hint.ts;
|
|
89
|
+
if (hint.sig) payload.wa_sig = hint.sig;
|
|
90
|
+
|
|
91
|
+
const whatsappLogin = {};
|
|
92
|
+
if (hint.phone) whatsappLogin.phone = hint.phone;
|
|
93
|
+
if (hint.ts) whatsappLogin.ts = hint.ts;
|
|
94
|
+
if (hint.sig) whatsappLogin.sig = hint.sig;
|
|
95
|
+
if (Object.keys(whatsappLogin).length > 0) {
|
|
96
|
+
payload.whatsapp_login = whatsappLogin;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return payload;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const createLoginApi = (apiBasePath) => {
|
|
103
|
+
const authSessionPath = `${apiBasePath}/auth/google/session`;
|
|
104
|
+
const createConfigPath = `${apiBasePath}/create-config`;
|
|
105
|
+
const botContactPath = `${apiBasePath}/bot-contact`;
|
|
106
|
+
|
|
107
|
+
const fetchJson = async (url, init = {}) => {
|
|
108
|
+
const response = await fetch(url, {
|
|
109
|
+
credentials: 'include',
|
|
110
|
+
...init,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
let payload = null;
|
|
114
|
+
try {
|
|
115
|
+
payload = await response.json();
|
|
116
|
+
} catch {
|
|
117
|
+
payload = null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const error = new Error(payload?.error || `Falha HTTP ${response.status}`);
|
|
122
|
+
error.statusCode = response.status;
|
|
123
|
+
error.payload = payload;
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
return payload || {};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
getSession: () => fetchJson(authSessionPath, { method: 'GET' }),
|
|
131
|
+
createSession: (body) =>
|
|
132
|
+
fetchJson(authSessionPath, {
|
|
133
|
+
method: 'POST',
|
|
134
|
+
headers: {
|
|
135
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify(body || {}),
|
|
138
|
+
}),
|
|
139
|
+
getConfig: () => fetchJson(createConfigPath, { method: 'GET' }),
|
|
140
|
+
getBotContact: () => fetchJson(botContactPath, { method: 'GET' }),
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
let googleScriptPromise = null;
|
|
145
|
+
const loadGoogleScript = () => {
|
|
146
|
+
if (globalThis.google?.accounts?.id) {
|
|
147
|
+
return Promise.resolve(globalThis.google.accounts.id);
|
|
148
|
+
}
|
|
149
|
+
if (googleScriptPromise) return googleScriptPromise;
|
|
150
|
+
|
|
151
|
+
googleScriptPromise = new Promise((resolve, reject) => {
|
|
152
|
+
const existing = document.querySelector(`script[src="${GOOGLE_GSI_SCRIPT_SRC}"]`);
|
|
153
|
+
if (existing) {
|
|
154
|
+
existing.addEventListener('load', () => resolve(globalThis.google?.accounts?.id || null), {
|
|
155
|
+
once: true,
|
|
156
|
+
});
|
|
157
|
+
existing.addEventListener('error', () => reject(new Error('Falha ao carregar SDK Google.')), {
|
|
158
|
+
once: true,
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const script = document.createElement('script');
|
|
164
|
+
script.src = GOOGLE_GSI_SCRIPT_SRC;
|
|
165
|
+
script.async = true;
|
|
166
|
+
script.defer = true;
|
|
167
|
+
script.onload = () => resolve(globalThis.google?.accounts?.id || null);
|
|
168
|
+
script.onerror = () => reject(new Error('Falha ao carregar SDK Google.'));
|
|
169
|
+
document.head.appendChild(script);
|
|
170
|
+
}).catch((error) => {
|
|
171
|
+
googleScriptPromise = null;
|
|
172
|
+
throw error;
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return googleScriptPromise;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const LoginApp = ({ config }) => {
|
|
179
|
+
const api = useMemo(() => createLoginApi(config.apiBasePath), [config.apiBasePath]);
|
|
180
|
+
const hint = useMemo(() => readWhatsAppHintFromSearch(window.location.search), []);
|
|
181
|
+
|
|
182
|
+
const [session, setSession] = useState(null);
|
|
183
|
+
const [botPhone, setBotPhone] = useState(() => normalizeDigits(hint.phone || ''));
|
|
184
|
+
const [whatsappCtaUrl, setWhatsappCtaUrl] = useState(() => buildWhatsAppLoginUrl(hint.phone || ''));
|
|
185
|
+
const [errorMessage, setErrorMessage] = useState('');
|
|
186
|
+
const [consentAccepted, setConsentAccepted] = useState(true);
|
|
187
|
+
const [googleStatusMessage, setGoogleStatusMessage] = useState(hint.hasPayload ? 'Aguardando Google...' : '');
|
|
188
|
+
const [googleReady, setGoogleReady] = useState(false);
|
|
189
|
+
const [googleClientId, setGoogleClientId] = useState('');
|
|
190
|
+
const [isSubmittingGoogle, setIsSubmittingGoogle] = useState(false);
|
|
191
|
+
|
|
192
|
+
const googleButtonRef = useRef(null);
|
|
193
|
+
|
|
194
|
+
useEffect(() => {
|
|
195
|
+
let active = true;
|
|
196
|
+
|
|
197
|
+
const loadBotContact = async () => {
|
|
198
|
+
try {
|
|
199
|
+
const payload = await api.getBotContact();
|
|
200
|
+
const data = payload?.data || {};
|
|
201
|
+
const phone = normalizeDigits(data?.phone || '');
|
|
202
|
+
const loginText = String(data?.login_text || DEFAULT_WHATSAPP_LOGIN_TRIGGER).trim() || DEFAULT_WHATSAPP_LOGIN_TRIGGER;
|
|
203
|
+
const loginUrl = String(data?.urls?.login || '').trim();
|
|
204
|
+
|
|
205
|
+
if (!active) return;
|
|
206
|
+
if (phone) setBotPhone(phone);
|
|
207
|
+
if (loginUrl) {
|
|
208
|
+
setWhatsappCtaUrl(loginUrl);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
setWhatsappCtaUrl(buildWhatsAppLoginUrl(phone, loginText));
|
|
212
|
+
} catch {
|
|
213
|
+
if (!active) return;
|
|
214
|
+
setWhatsappCtaUrl(buildWhatsAppLoginUrl(hint.phone || ''));
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
void loadBotContact();
|
|
219
|
+
return () => {
|
|
220
|
+
active = false;
|
|
221
|
+
};
|
|
222
|
+
}, [api, hint.phone]);
|
|
223
|
+
|
|
224
|
+
useEffect(() => {
|
|
225
|
+
let active = true;
|
|
226
|
+
api
|
|
227
|
+
.getSession()
|
|
228
|
+
.then((payload) => {
|
|
229
|
+
if (!active) return;
|
|
230
|
+
const sessionData = payload?.data || null;
|
|
231
|
+
if (isAuthenticatedSession(sessionData)) {
|
|
232
|
+
setSession(sessionData);
|
|
233
|
+
// Redireciona imediatamente se já estiver autenticado
|
|
234
|
+
window.location.replace(config.panelPath);
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
.catch(() => {});
|
|
238
|
+
return () => {
|
|
239
|
+
active = false;
|
|
240
|
+
};
|
|
241
|
+
}, [api]);
|
|
242
|
+
|
|
243
|
+
const finalizeGoogleCredential = useCallback(
|
|
244
|
+
async (credential) => {
|
|
245
|
+
const idToken = String(credential || '').trim();
|
|
246
|
+
if (!idToken) {
|
|
247
|
+
setErrorMessage('Nao foi possivel receber o token Google.');
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (!consentAccepted) {
|
|
251
|
+
setErrorMessage('Aceite os Termos e Privacidade para continuar.');
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
setErrorMessage('');
|
|
256
|
+
setIsSubmittingGoogle(true);
|
|
257
|
+
setGoogleStatusMessage('Validando conta Google...');
|
|
258
|
+
|
|
259
|
+
try {
|
|
260
|
+
const payload = await api.createSession(buildGoogleAuthPayload(idToken, hint));
|
|
261
|
+
const sessionData = payload?.data || null;
|
|
262
|
+
if (!isAuthenticatedSession(sessionData)) {
|
|
263
|
+
throw new Error('Nao foi possivel criar sessao Google.');
|
|
264
|
+
}
|
|
265
|
+
setSession(sessionData);
|
|
266
|
+
setGoogleStatusMessage('Login concluido. Redirecionando...');
|
|
267
|
+
window.setTimeout(() => {
|
|
268
|
+
window.location.replace(config.panelPath);
|
|
269
|
+
}, 120);
|
|
270
|
+
} catch (error) {
|
|
271
|
+
setErrorMessage(error?.message || 'Falha ao concluir login Google.');
|
|
272
|
+
setGoogleStatusMessage('Falha ao validar conta Google.');
|
|
273
|
+
} finally {
|
|
274
|
+
setIsSubmittingGoogle(false);
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
[api, config.panelPath, consentAccepted, hint],
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
let active = true;
|
|
282
|
+
if (!hint.hasPayload) return () => {};
|
|
283
|
+
|
|
284
|
+
const initGoogle = async () => {
|
|
285
|
+
try {
|
|
286
|
+
setErrorMessage('');
|
|
287
|
+
setGoogleReady(false);
|
|
288
|
+
setGoogleStatusMessage('Aguardando Google...');
|
|
289
|
+
|
|
290
|
+
const configPayload = await api.getConfig();
|
|
291
|
+
if (!active) return;
|
|
292
|
+
const googleAuth = configPayload?.data?.auth?.google || {};
|
|
293
|
+
const clientId = String(googleAuth?.client_id || '').trim();
|
|
294
|
+
const enabled = Boolean(googleAuth?.enabled);
|
|
295
|
+
|
|
296
|
+
if (!enabled || !clientId) {
|
|
297
|
+
setGoogleStatusMessage('Login Google desabilitado neste ambiente.');
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
setGoogleClientId(clientId);
|
|
302
|
+
await loadGoogleScript();
|
|
303
|
+
if (!active) return;
|
|
304
|
+
|
|
305
|
+
const googleAccounts = globalThis.google?.accounts?.id;
|
|
306
|
+
const buttonElement = googleButtonRef.current;
|
|
307
|
+
if (!googleAccounts || !buttonElement) {
|
|
308
|
+
setGoogleStatusMessage('SDK Google nao carregado.');
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
googleAccounts.initialize({
|
|
313
|
+
client_id: clientId,
|
|
314
|
+
callback: (response) => {
|
|
315
|
+
void finalizeGoogleCredential(response?.credential || '');
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const width = Math.max(220, Math.min(320, Math.floor(Number(buttonElement.clientWidth || 280))));
|
|
320
|
+
buttonElement.innerHTML = '';
|
|
321
|
+
googleAccounts.renderButton(buttonElement, {
|
|
322
|
+
type: 'standard',
|
|
323
|
+
theme: 'outline',
|
|
324
|
+
size: 'large',
|
|
325
|
+
text: 'continue_with',
|
|
326
|
+
shape: 'pill',
|
|
327
|
+
width,
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
setGoogleReady(true);
|
|
331
|
+
setGoogleStatusMessage('Selecione sua conta Google para continuar.');
|
|
332
|
+
} catch (error) {
|
|
333
|
+
if (!active) return;
|
|
334
|
+
setGoogleStatusMessage('Falha ao carregar login Google.');
|
|
335
|
+
setErrorMessage(error?.message || 'Nao foi possivel inicializar o Google.');
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
void initGoogle();
|
|
340
|
+
return () => {
|
|
341
|
+
active = false;
|
|
342
|
+
};
|
|
343
|
+
}, [api, finalizeGoogleCredential, hint.hasPayload]);
|
|
344
|
+
|
|
345
|
+
useEffect(() => {
|
|
346
|
+
const observer =
|
|
347
|
+
typeof globalThis.IntersectionObserver === 'function'
|
|
348
|
+
? new globalThis.IntersectionObserver(
|
|
349
|
+
(entries) => {
|
|
350
|
+
entries.forEach((entry) => {
|
|
351
|
+
if (entry.isIntersecting) {
|
|
352
|
+
entry.target.classList.add('is-visible');
|
|
353
|
+
observer.unobserve(entry.target);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
},
|
|
357
|
+
{ threshold: 0.1 },
|
|
358
|
+
)
|
|
359
|
+
: null;
|
|
360
|
+
|
|
361
|
+
document.querySelectorAll('[data-reveal]').forEach((el, i) => {
|
|
362
|
+
el.style.setProperty('--reveal-delay', `${i * 80}ms`);
|
|
363
|
+
if (observer) {
|
|
364
|
+
observer.observe(el);
|
|
365
|
+
} else {
|
|
366
|
+
el.classList.add('is-visible');
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
return () => {
|
|
371
|
+
if (observer) observer.disconnect();
|
|
372
|
+
};
|
|
373
|
+
}, []);
|
|
374
|
+
|
|
375
|
+
const authInfo = useMemo(() => {
|
|
376
|
+
if (!session?.authenticated) return { href: '/login/', label: 'Entrar', image: null };
|
|
377
|
+
return {
|
|
378
|
+
href: '/user/',
|
|
379
|
+
label: session.user?.name?.split(' ')[0] || 'Perfil',
|
|
380
|
+
image: session.user?.picture || FALLBACK_THUMB_URL,
|
|
381
|
+
};
|
|
382
|
+
}, [session]);
|
|
383
|
+
|
|
384
|
+
const botPhoneMeta = botPhone ? html`<p className="text-[11px] text-center text-base-content/45">Bot detectado: <b>+${formatPhone(botPhone)}</b></p>` : null;
|
|
385
|
+
|
|
386
|
+
return html`
|
|
387
|
+
<div className="min-h-screen bg-base-100 font-sans selection:bg-primary selection:text-primary-content">
|
|
388
|
+
<header className="sticky top-0 z-50 border-b border-base-200 bg-base-100/80 backdrop-blur-xl">
|
|
389
|
+
<div className="container mx-auto px-4">
|
|
390
|
+
<div className="flex h-16 items-center justify-between gap-4">
|
|
391
|
+
<div className="flex-1">
|
|
392
|
+
<a href="/" className="flex items-center gap-2.5 hover:opacity-80 transition-opacity">
|
|
393
|
+
<img src="/assets/images/brand-logo-128.webp" className="w-8 h-8 rounded-xl shadow-sm" alt="Logo" />
|
|
394
|
+
<span className="text-base sm:text-lg font-black tracking-tight">OmniZap<span className="text-primary">.</span></span>
|
|
395
|
+
</a>
|
|
396
|
+
</div>
|
|
397
|
+
|
|
398
|
+
<div className="flex items-center gap-3">
|
|
399
|
+
<a href=${authInfo.href} className="btn btn-ghost btn-sm h-9 min-h-0 gap-2 rounded-xl border border-base-300 hover:border-primary transition-all px-3">
|
|
400
|
+
${authInfo.image ? html`<img src=${authInfo.image} className="w-5 h-5 rounded-full object-cover" />` : null}
|
|
401
|
+
<span className="text-[10px] sm:text-xs font-bold uppercase tracking-wider">${authInfo.label}</span>
|
|
402
|
+
</a>
|
|
403
|
+
</div>
|
|
404
|
+
</div>
|
|
405
|
+
</div>
|
|
406
|
+
</header>
|
|
407
|
+
|
|
408
|
+
<main className="container mx-auto px-4 py-12 lg:py-20 flex flex-col items-center">
|
|
409
|
+
<div className="w-full max-w-md space-y-8">
|
|
410
|
+
<div data-reveal="fade-up" className="text-center space-y-4">
|
|
411
|
+
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-primary/10 border border-primary/20 text-primary text-[10px] font-bold uppercase tracking-widest">Acesso Restrito · Criptografado</div>
|
|
412
|
+
<h1 className="text-4xl font-black tracking-tight text-balance">Entrar no <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary">OmniZap</span></h1>
|
|
413
|
+
<p className="text-base-content/60 leading-relaxed">Conecte sua conta de forma segura para gerenciar suas comunidades e automacoes.</p>
|
|
414
|
+
</div>
|
|
415
|
+
|
|
416
|
+
<div data-reveal="fade-up" className="glass-card rounded-[2.5rem] p-8 space-y-8 relative overflow-hidden">
|
|
417
|
+
<div className="absolute top-0 right-0 w-32 h-32 bg-primary/5 rounded-full blur-3xl -mr-16 -mt-16"></div>
|
|
418
|
+
|
|
419
|
+
<div className="space-y-6 relative z-10">
|
|
420
|
+
${!hint.hasPayload
|
|
421
|
+
? html`
|
|
422
|
+
<div className="space-y-4">
|
|
423
|
+
<div className="p-4 rounded-2xl bg-base-200/50 border border-base-300">
|
|
424
|
+
<p className="text-xs font-bold text-base-content/40 uppercase tracking-widest mb-2 text-center">Recomendado</p>
|
|
425
|
+
<a href=${whatsappCtaUrl} target="_blank" className="btn btn-primary btn-block rounded-2xl h-14 font-black shadow-lg shadow-primary/20 gap-3 group" rel="noreferrer noopener">
|
|
426
|
+
Entrar via WhatsApp
|
|
427
|
+
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 group-hover:scale-110 transition-transform" fill="currentColor" viewBox="0 0 24 24"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.347-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.136 1.36.117 1.871.05.57-.075 1.758-.463 2.005-1.114.248-.651.248-1.212.173-1.327-.075-.115-.272-.19-.57-.339z" /></svg>
|
|
428
|
+
</a>
|
|
429
|
+
</div>
|
|
430
|
+
${botPhoneMeta}
|
|
431
|
+
<p className="text-[11px] text-center text-base-content/40 leading-relaxed px-4">Abra o bot no WhatsApp e envie <b>"iniciar"</b> para receber seu link seguro de acesso.</p>
|
|
432
|
+
</div>
|
|
433
|
+
`
|
|
434
|
+
: html`
|
|
435
|
+
<div className="space-y-6">
|
|
436
|
+
<div className="flex items-center gap-4 p-4 rounded-2xl bg-success/10 border border-success/20">
|
|
437
|
+
<div className="w-10 h-10 rounded-full bg-success flex items-center justify-center text-success-content">
|
|
438
|
+
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="3" d="M5 13l4 4L19 7" /></svg>
|
|
439
|
+
</div>
|
|
440
|
+
<div>
|
|
441
|
+
<p className="text-xs font-black uppercase tracking-widest text-success">Vinculo Detectado</p>
|
|
442
|
+
<p className="text-sm font-bold text-success/80">+${formatPhone(hint.phone)}</p>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
|
|
446
|
+
<div className="space-y-4">
|
|
447
|
+
<p className="text-xs font-bold text-base-content/40 uppercase tracking-[0.2em] text-center">Concluir com Google</p>
|
|
448
|
+
<div id="google-login-btn" ref=${googleButtonRef} className="w-full flex justify-center py-2 bg-white rounded-2xl overflow-hidden shadow-sm min-h-14"></div>
|
|
449
|
+
<p className="text-[11px] text-center text-base-content/45">${isSubmittingGoogle ? 'Finalizando login...' : googleStatusMessage}</p>
|
|
450
|
+
${googleClientId ? html`<p className="text-[10px] text-center text-base-content/30">Google Client configurado.</p>` : null} ${!googleReady && !isSubmittingGoogle ? html`<p className="text-[10px] text-center text-base-content/35">Se o botao nao aparecer, recarregue a pagina apos alguns segundos.</p>` : null}
|
|
451
|
+
</div>
|
|
452
|
+
|
|
453
|
+
<div className="form-control">
|
|
454
|
+
<label className="label cursor-pointer justify-start gap-3 p-0">
|
|
455
|
+
<input type="checkbox" className="checkbox checkbox-primary checkbox-sm rounded-md" checked=${consentAccepted} onChange=${(e) => setConsentAccepted(e.target.checked)} />
|
|
456
|
+
<span className="label-text text-[11px] text-base-content/60 leading-tight"> Aceito os <a href="/termos-de-uso/" className="text-primary font-bold hover:underline">Termos</a> e <a href="/politica-de-privacidade/" className="text-primary font-bold hover:underline">Privacidade</a>. </span>
|
|
457
|
+
</label>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
`}
|
|
461
|
+
${errorMessage
|
|
462
|
+
? html`
|
|
463
|
+
<div className="alert alert-error text-xs rounded-2xl py-3 border-none bg-error/20 text-error-content font-bold">
|
|
464
|
+
<span>${errorMessage}</span>
|
|
465
|
+
</div>
|
|
466
|
+
`
|
|
467
|
+
: null}
|
|
468
|
+
</div>
|
|
469
|
+
</div>
|
|
470
|
+
|
|
471
|
+
<div data-reveal="fade-up" className="grid grid-cols-3 gap-4">
|
|
472
|
+
${LEGAL_DOCS.map(
|
|
473
|
+
(doc) => html`
|
|
474
|
+
<a href=${doc.href} className="text-center p-3 rounded-2xl border border-base-200 hover:bg-base-200 transition-all">
|
|
475
|
+
<span className="text-[10px] font-bold uppercase tracking-widest text-base-content/40">${doc.label}</span>
|
|
476
|
+
</a>
|
|
477
|
+
`,
|
|
478
|
+
)}
|
|
479
|
+
</div>
|
|
480
|
+
</div>
|
|
481
|
+
</main>
|
|
482
|
+
|
|
483
|
+
<footer className="py-12 border-t border-base-200">
|
|
484
|
+
<div className="container mx-auto px-4 text-center">
|
|
485
|
+
<p className="text-[10px] font-bold uppercase tracking-[0.3em] text-base-content/20">© 2026 OMNIZAP SYSTEM · SECURE LOGIN V2</p>
|
|
486
|
+
</div>
|
|
487
|
+
</footer>
|
|
488
|
+
</div>
|
|
489
|
+
`;
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
const rootElement = document.getElementById('login-react-root');
|
|
493
|
+
if (rootElement) {
|
|
494
|
+
const config = resolveLoginConfig(rootElement);
|
|
495
|
+
createRoot(rootElement).render(html`<${LoginApp} config=${config} />`);
|
|
496
|
+
}
|