From d77af5c6149bd432a7e71e4e5987105d7303c5e7 Mon Sep 17 00:00:00 2001 From: Ricardo Carneiro Date: Fri, 7 Nov 2025 17:32:19 -0300 Subject: [PATCH 1/3] fix: whatsapp links --- src/BCards.Web/Views/UserPage/Display.cshtml | 90 +++++++++++++++++--- 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/src/BCards.Web/Views/UserPage/Display.cshtml b/src/BCards.Web/Views/UserPage/Display.cshtml index 0501289..c239bdd 100644 --- a/src/BCards.Web/Views/UserPage/Display.cshtml +++ b/src/BCards.Web/Views/UserPage/Display.cshtml @@ -19,43 +19,92 @@ { if (string.IsNullOrEmpty(url)) return "#"; - // Se já tem protocolo, retorna direto - if (url.StartsWith("http://") || url.StartsWith("https://")) - return url; - - // WhatsApp - garantir prefixo wa.me + // WhatsApp - sempre normalizar para evitar URLs malformadas if (!string.IsNullOrEmpty(icon) && icon.Contains("whatsapp")) { - // Remove qualquer prefixo parcial que possa existir - var cleanUrl = url.Replace("wa.me/", "").Replace("whatsapp://", ""); + // Remove qualquer prefixo conhecido (incluindo https://) + var cleanUrl = url + .Replace("https://wa.me/", "") + .Replace("http://wa.me/", "") + .Replace("https://api.whatsapp.com/send?phone=", "") + .Replace("https://api.whatsapp.com/", "") + .Replace("wa.me/", "") + .Replace("whatsapp://send?phone=", "") + .Replace("whatsapp://", ""); + + // Remove barras extras + cleanUrl = cleanUrl.TrimStart('/').Trim(); + + // Apenas números devem sobrar return $"https://wa.me/{cleanUrl}"; } + // Se já tem protocolo correto para outras redes, retorna direto + if (url.StartsWith("http://") || url.StartsWith("https://")) + return url; + // Facebook if (!string.IsNullOrEmpty(icon) && icon.Contains("facebook")) { - var cleanUrl = url.Replace("facebook.com/", "").Replace("fb.com/", ""); + var cleanUrl = url + .Replace("https://facebook.com/", "") + .Replace("https://www.facebook.com/", "") + .Replace("https://fb.com/", "") + .Replace("https://www.fb.com/", "") + .Replace("http://facebook.com/", "") + .Replace("http://www.facebook.com/", "") + .Replace("facebook.com/", "") + .Replace("fb.com/", "") + .TrimStart('/').Trim(); return $"https://facebook.com/{cleanUrl}"; } // Instagram if (!string.IsNullOrEmpty(icon) && icon.Contains("instagram")) { - var cleanUrl = url.Replace("instagram.com/", "").Replace("instagr.am/", ""); + var cleanUrl = url + .Replace("https://instagram.com/", "") + .Replace("https://www.instagram.com/", "") + .Replace("https://instagr.am/", "") + .Replace("http://instagram.com/", "") + .Replace("http://www.instagram.com/", "") + .Replace("instagram.com/", "") + .Replace("instagr.am/", "") + .TrimStart('/').Trim(); return $"https://instagram.com/{cleanUrl}"; } // Twitter/X if (!string.IsNullOrEmpty(icon) && (icon.Contains("twitter") || icon.Contains("x-twitter"))) { - var cleanUrl = url.Replace("x.com/", "").Replace("twitter.com/", ""); + var cleanUrl = url + .Replace("https://x.com/", "") + .Replace("https://twitter.com/", "") + .Replace("https://www.twitter.com/", "") + .Replace("https://www.x.com/", "") + .Replace("http://x.com/", "") + .Replace("http://twitter.com/", "") + .Replace("x.com/", "") + .Replace("twitter.com/", "") + .TrimStart('/').Trim(); return $"https://x.com/{cleanUrl}"; } // TikTok if (!string.IsNullOrEmpty(icon) && icon.Contains("tiktok")) { - var cleanUrl = url.Replace("tiktok.com/", "").Replace("tiktok.com/@", ""); + var cleanUrl = url + .Replace("https://tiktok.com/@", "") + .Replace("https://www.tiktok.com/@", "") + .Replace("https://tiktok.com/", "") + .Replace("https://www.tiktok.com/", "") + .Replace("https://vm.tiktok.com/", "") + .Replace("http://tiktok.com/@", "") + .Replace("http://tiktok.com/", "") + .Replace("tiktok.com/@", "") + .Replace("tiktok.com/", "") + .TrimStart('/').Trim(); + // Se não tem @, adiciona if (!cleanUrl.StartsWith("@")) cleanUrl = "@" + cleanUrl; @@ -65,14 +114,29 @@ // Pinterest if (!string.IsNullOrEmpty(icon) && icon.Contains("pinterest")) { - var cleanUrl = url.Replace("pinterest.com/", "").Replace("pin.it/", ""); + var cleanUrl = url + .Replace("https://pinterest.com/", "") + .Replace("https://www.pinterest.com/", "") + .Replace("https://pin.it/", "") + .Replace("http://pinterest.com/", "") + .Replace("http://www.pinterest.com/", "") + .Replace("pinterest.com/", "") + .Replace("pin.it/", "") + .TrimStart('/').Trim(); return $"https://pinterest.com/{cleanUrl}"; } // Discord if (!string.IsNullOrEmpty(icon) && icon.Contains("discord")) { - var cleanUrl = url.Replace("discord.gg/", "").Replace("discord.com/invite/", ""); + var cleanUrl = url + .Replace("https://discord.gg/", "") + .Replace("https://discord.com/invite/", "") + .Replace("http://discord.gg/", "") + .Replace("http://discord.com/invite/", "") + .Replace("discord.gg/", "") + .Replace("discord.com/invite/", "") + .TrimStart('/').Trim(); return $"https://discord.gg/{cleanUrl}"; } -- 2.45.2 From 96cc089b60a55fa0d7287eebfabafc228edc410d Mon Sep 17 00:00:00 2001 From: Ricardo Carneiro Date: Fri, 14 Nov 2025 23:07:12 -0300 Subject: [PATCH 2/3] fix: ajustes de certificado e artigos --- .gitea/workflows/deploy-bcards.yml | 5 +- Dockerfile | 6 +- src/BCards.Web/Program.cs | 7 ++ src/BCards.Web/Views/Admin/ManagePage.cshtml | 86 ++++++++++++++++++++ 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/deploy-bcards.yml b/.gitea/workflows/deploy-bcards.yml index 728e12a..f6cc88d 100644 --- a/.gitea/workflows/deploy-bcards.yml +++ b/.gitea/workflows/deploy-bcards.yml @@ -162,7 +162,7 @@ jobs: # Build para a plataforma correta if [ "${{ steps.settings.outputs.deploy_target }}" = "production" ]; then - # Build para produção (main branch) + # Build para produção (main branch) - Usa Configuration=Release (padrão) docker buildx build \ --platform ${{ steps.settings.outputs.platform }} \ --file ${{ steps.settings.outputs.dockerfile }} \ @@ -171,12 +171,13 @@ jobs: --progress=plain \ . else - # Build para staging (Release branches) + # Build para staging (Release branches) - Usa Configuration=Testing para habilitar código de teste docker buildx build \ --platform ${{ steps.settings.outputs.platform }} \ --file ${{ steps.settings.outputs.dockerfile }} \ --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.settings.outputs.tag }} \ --push \ + --build-arg BUILD_CONFIGURATION=Testing \ --build-arg VERSION=${{ steps.settings.outputs.version || 'latest' }} \ --build-arg COMMIT=${{ steps.settings.outputs.commit }} \ --progress=plain \ diff --git a/Dockerfile b/Dockerfile index f34ff92..1b0dad4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,15 +5,17 @@ EXPOSE 8080 EXPOSE 8443 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["src/BCards.Web/BCards.Web.csproj", "src/BCards.Web/"] RUN dotnet restore "src/BCards.Web/BCards.Web.csproj" COPY . . WORKDIR "/src/src/BCards.Web" -RUN dotnet build "BCards.Web.csproj" -c Release -o /app/build +RUN dotnet build "BCards.Web.csproj" -c ${BUILD_CONFIGURATION} -o /app/build FROM build AS publish -RUN dotnet publish "BCards.Web.csproj" -c Release -o /app/publish /p:UseAppHost=false +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "BCards.Web.csproj" -c ${BUILD_CONFIGURATION} -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app diff --git a/src/BCards.Web/Program.cs b/src/BCards.Web/Program.cs index 6bd165f..1cd1aa5 100644 --- a/src/BCards.Web/Program.cs +++ b/src/BCards.Web/Program.cs @@ -572,6 +572,13 @@ builder.Services.AddHttpClient(client => client.DefaultRequestHeaders.Add("User-Agent", "BCards-CriticalCheck/1.0"); }); +builder.Services.AddHsts(options => +{ + options.MaxAge = TimeSpan.FromDays(365); + options.IncludeSubDomains = true; + options.Preload = true; +}); + var app = builder.Build(); app.UseForwardedHeaders(); diff --git a/src/BCards.Web/Views/Admin/ManagePage.cshtml b/src/BCards.Web/Views/Admin/ManagePage.cshtml index 1d47fec..d8b9511 100644 --- a/src/BCards.Web/Views/Admin/ManagePage.cshtml +++ b/src/BCards.Web/Views/Admin/ManagePage.cshtml @@ -239,6 +239,35 @@
+ @if (!Model.AllowDocumentUpload) + { + +
+ +
+
+ Anexar PDFs é exclusivo dos planos Premium +
+

+ Compartilhe apresentações, catálogos, portfólios e documentos diretamente na sua página profissional. +

+ +
+ + Plano Premium: até 5 PDFs + + + Plano Premium + Afiliados: até 10 PDFs + +
+ + + Fazer upgrade e desbloquear PDFs + +
+
+ } + @if (Model.AllowDocumentUpload) {

Anexe PDFs com apresentações, catálogos ou materiais exclusivos para quem acessar sua página Premium.

@@ -2594,6 +2623,63 @@ @:} } } + + // ======================================== + // Sistema de Confirmação ao Sair da Página + // ======================================== + let formChanged = false; + let isSubmitting = false; + + $(document).ready(function() { + // Marcar formulário como alterado quando qualquer campo mudar + $('form :input').on('change input', function() { + if (!isSubmitting) { + formChanged = true; + console.log('Formulário alterado detectado'); + } + }); + + // Quando submeter o formulário, desabilitar aviso + $('form').on('submit', function() { + console.log('Formulário submetido - desabilitando avisos'); + isSubmitting = true; + formChanged = false; + }); + + // Aviso ao tentar fechar/recarregar a página + window.addEventListener('beforeunload', function(e) { + if (formChanged && !isSubmitting) { + console.log('beforeunload: Tentativa de sair com alterações não salvas'); + e.preventDefault(); + e.returnValue = ''; // Chrome requer isso + return 'Você tem alterações não salvas. Deseja realmente sair?'; + } + }); + + // Interceptar cliques em links de navegação (incluindo Dashboard) + $(document).on('click', 'a:not(.no-confirm)', function(e) { + if (formChanged && !isSubmitting) { + const href = $(this).attr('href'); + + // Não avisar para links externos, âncoras ou JavaScript + if (href && !href.startsWith('#') && !href.startsWith('javascript:')) { + console.log('Link clicado com alterações não salvas:', href); + + if (!confirm('Você tem alterações não salvas. Deseja realmente sair desta página?')) { + e.preventDefault(); + console.log('Usuário cancelou navegação'); + return false; + } + + // Usuário confirmou, permitir navegação + console.log('Usuário confirmou saída'); + formChanged = false; + } + } + }); + + console.log('Sistema de confirmação ao sair inicializado'); + }); } -- 2.45.2 From 175effd1bed43804134780600b9e5b04e536f8dd Mon Sep 17 00:00:00 2001 From: Ricardo Carneiro Date: Fri, 14 Nov 2025 23:15:55 -0300 Subject: [PATCH 3/3] fix: ajustes de artigos --- src/BCards.Web/BCards.Web.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/BCards.Web/BCards.Web.csproj b/src/BCards.Web/BCards.Web.csproj index 364a569..f03b487 100644 --- a/src/BCards.Web/BCards.Web.csproj +++ b/src/BCards.Web/BCards.Web.csproj @@ -40,8 +40,9 @@ - - + + PreserveNewest + -- 2.45.2