From 95675f737900f90975d40685d12a7132c8021e33 Mon Sep 17 00:00:00 2001
From: Guilherme Biff Zarelli
Date: Tue, 27 Oct 2026 15:23:20 -0300
Subject: [PATCH] Add Strava OAuth callback and privacy disclosures
---
public/.well-known/assetlinks.json | 12 ++
.../velocimetro-alerta/privacidade/page.tsx | 172 ++++++++++++++----
.../strava/callback/page.tsx | 11 ++
.../callback/strava-callback-fallback.tsx | 60 ++++++
src/app/components/GoogleAnalytics.tsx | 18 +-
5 files changed, 231 insertions(+), 42 deletions(-)
create mode 100644 public/.well-known/assetlinks.json
create mode 100644 src/app/apps/velocimetro-alerta/strava/callback/page.tsx
create mode 100644 src/app/apps/velocimetro-alerta/strava/callback/strava-callback-fallback.tsx
diff --git a/public/.well-known/assetlinks.json b/public/.well-known/assetlinks.json
new file mode 100644
index 0000000..57b9813
--- /dev/null
+++ b/public/.well-known/assetlinks.json
@@ -0,0 +1,12 @@
+[
+ {
+ "relation": ["delegate_permission/common.handle_all_urls"],
+ "target": {
+ "namespace": "android_app",
+ "package_name": "br.com.helpdev.velocimetroalerta.v2",
+ "sha256_cert_fingerprints": [
+ "FE:0E:92:C0:E8:6B:9F:7E:62:90:58:49:D6:33:33:24:E8:29:F6:88:44:F4:35:3C:D4:99:6A:6B:7D:94:95:B6"
+ ]
+ }
+ }
+]
diff --git a/src/app/apps/velocimetro-alerta/privacidade/page.tsx b/src/app/apps/velocimetro-alerta/privacidade/page.tsx
index 857e67b..58eb762 100644
--- a/src/app/apps/velocimetro-alerta/privacidade/page.tsx
+++ b/src/app/apps/velocimetro-alerta/privacidade/page.tsx
@@ -13,7 +13,7 @@ export const metadata: Metadata = {
},
};
-const updatedAt = '26 de outubro de 2026';
+const updatedAt = '27 de outubro de 2026';
export default function VelocimetroAlertaPrivacyPolicyPage() {
return (
@@ -36,7 +36,8 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
Esta política se aplica ao aplicativo gratuito Velocímetro Alerta para Android, publicado com o
identificador br.com.helpdev.velocimetroalerta.v2.
- O aplicativo não exige criação de conta e não oferece compras ou assinaturas dentro do app.
+ Os recursos locais podem ser usados sem conta. Uma conta Google é necessária para sincronizar algumas
+ preferências ou conectar o Strava. O aplicativo não oferece compras ou assinaturas dentro do app.
@@ -50,9 +51,9 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
A localização e as métricas da atividade são processadas no dispositivo. A Help DEV não recebe esses
- dados em seus servidores, não mantém uma conta de usuário para o app e o app não mantém um histórico
- remoto das atividades. Os dados enviados ao Google Maps SDK ao exibir um mapa estão descritos na seção
- abaixo. A permissão de localização é necessária para os recursos de velocidade e
+ dados no Firebase. Se você optar por enviar uma atividade ao Strava, os dados do arquivo GPX seguem
+ diretamente do aparelho para o Strava, conforme descrito abaixo. Os dados enviados ao Google Maps SDK ao
+ exibir um mapa estão descritos na seção abaixo. A permissão de localização é necessária para os recursos de velocidade e
rastreamento; você pode recusá-la ou revogá-la nas configurações do Android, mas esses recursos podem
deixar de funcionar.
@@ -93,16 +94,31 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
- Preferências e armazenamento
+ Conta Google, Firebase e preferências
- Preferências do app, como limites de velocidade, alertas, sensores configurados e zonas de frequência
- cardíaca, ficam no armazenamento local do aplicativo. Conforme as configurações do aparelho e da conta,
- o Android pode incluir dados locais do app em um backup ou transferi-los para outro dispositivo. Esses
- backups são administrados pelo Android e pelo serviço de backup escolhido; a Help DEV não os controla.
+ O login Google é opcional para o uso local e necessário para sincronizar preferências e conectar o
+ Strava. Quando você entra, o Firebase Authentication processa identificadores da conta e informações de
+ perfil disponibilizadas pelo Google, como nome e e-mail. O Firebase Authentication opera em centros de
+ dados nos Estados Unidos. O Google trata esses dados conforme sua{' '}
+
+ Política de Privacidade
+ .
+
+
+ Se você escolher sincronizar, um conjunto limitado de preferências — incluindo opções de alertas,
+ intervalos, zonas de frequência cardíaca e a opção de sincronização automática — fica associado à sua
+ conta no Cloud Firestore do Firebase. O banco e as Cloud Functions do projeto estão configurados na
+ região de São Paulo; outros dados de serviço do Firebase podem ser processados pela infraestrutura global
+ do Google. As atividades salvas, arquivos GPX e estados de envio continuam no aparelho e não são enviados
+ ao Firebase. Mais informações estão na página de{' '}
+
+ privacidade e segurança do Firebase
+ .
- O app não envia automaticamente localização, métricas de atividade ou preferências para um servidor e não
- mantém um serviço próprio de histórico de atividades.
+ Preferências e atividades locais permanecem no armazenamento do aplicativo. Conforme as configurações do
+ aparelho e da conta, o Android pode incluí-las em um backup ou transferi-las para outro dispositivo; esses
+ backups são administrados pelo Android e pelo serviço de backup escolhido.
@@ -122,6 +138,28 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
+
+ Conexão e envio de atividades ao Strava
+
+ Para conectar uma conta, você autoriza o Strava pelo navegador com a permissão de criar atividades
+ (activity:write). O código temporário de autorização é processado pelas Cloud Functions; os
+ tokens de acesso e renovação ficam no Firestore em um registro privado da sua conta. Quando a integração
+ estiver ativa, o segredo do aplicativo Strava fica no Google Secret Manager. Para enviar uma atividade, a função devolve ao aparelho
+ um token de acesso de curta duração, usado para enviar o GPX diretamente à API do Strava. A Help DEV não
+ recebe o arquivo GPX nem as coordenadas da atividade pelo Firebase.
+
+
+ O envio manual transmite a atividade escolhida nos detalhes. Se você ativar Sincronizar
+ automático, atividades elegíveis salvas depois dessa escolha podem ser enviadas automaticamente;
+ atividades antigas não são enviadas em lote. O GPX pode conter trajeto, coordenadas, horários, elevação e,
+ quando disponíveis, frequência cardíaca, cadência, temperatura e umidade. O app também envia o nome, o
+ tipo e um identificador do arquivo. O Strava processa e armazena esses dados de acordo com a{' '}
+
+ Política de Privacidade do Strava
+ .
+
+
+
Anúncios, análise e identificadores
@@ -162,13 +200,27 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
-
- Retenção e exclusão
+
+ Retenção e exclusão de dados
As preferências, atividades salvas e rotas permanecem no dispositivo até você excluí-las em Minhas
- atividades, limpar os dados do app nas configurações do Android ou desinstalá-lo. A Help DEV não mantém
- um histórico remoto dessas atividades. Arquivos GPX exportados e cópias em backups devem ser excluídos
- por você no serviço ou dispositivo em que foram salvos, conforme as opções desse destino.
+ atividades, limpar os dados do app nas configurações do Android ou desinstalá-lo. Preferências sincronizadas
+ ficam no Firestore enquanto o registro da conta existir; sair da conta Google no app não as exclui.
+ Quando a desconexão do Strava é concluída pelo app, a autorização é revogada e os tokens armazenados são
+ removidos. Atividades já enviadas ficam na conta Strava e devem ser excluídas por você diretamente no
+ Strava. Arquivos GPX exportados e cópias em backups devem ser excluídos no serviço ou dispositivo onde
+ foram salvos.
+
+
+ Para solicitar a exclusão da conta Firebase usada pelo aplicativo, das preferências na nuvem e dos tokens
+ Strava associados, use o{' '}
+
+ e-mail de suporte da Help DEV
+ {' '}
+ e informe o e-mail da conta Google usada no app. A solicitação remove a autorização e os tokens Strava
+ armazenados, mas não remove atividades já enviadas à sua conta
+ Strava nem os arquivos GPX que continuam no dispositivo; esses itens devem ser removidos nos respectivos
+ serviços ou no app.
@@ -193,7 +245,8 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
This policy applies to the free Velocímetro Alerta Android app, package
br.com.helpdev.velocimetroalerta.v2.
- The app does not require an account and does not offer in-app purchases or subscriptions.
+ Local features can be used without an account. A Google account is required to sync some preferences or
+ connect Strava. The app does not offer in-app purchases or subscriptions.
@@ -206,11 +259,11 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
settings. The app does not start tracking automatically.
- Location and activity metrics are processed on your device. Help DEV does not receive this data on its
- servers, the app does not require a user account, and the app does not keep a remote activity history.
- Data sent to the Google Maps SDK when a map is shown is described below. Location access is required for
- speed and tracking features; you can deny or revoke it in Android settings, but those features may stop
- working.
+ Location and activity metrics are processed on your device. Help DEV does not receive them through
+ Firebase. If you choose to send an activity to Strava, the GPX file goes directly from your device to
+ Strava, as described below. Data sent to the Google Maps SDK when a map is shown is described below.
+ Location access is required for speed and tracking features; you can deny or revoke it in Android
+ settings, but those features may stop working.
@@ -247,16 +300,30 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
- Preferences and storage
+ Google account, Firebase, and preferences
- App preferences, including speed limits, alerts, configured sensors, and heart-rate zones, are stored
- locally by the app. Depending on your device and account settings, Android may include local app data in a
- backup or transfer it to another device. Android and the backup service you choose manage those backups;
- Help DEV does not control them.
+ Google sign-in is optional for local use and required to sync preferences and connect Strava. When you
+ sign in, Firebase Authentication processes account identifiers and profile information made available by
+ Google, such as your name and email address. Firebase Authentication operates from data centers in the
+ United States. Google handles this data under its{' '}
+
+ Privacy Policy
+ .
+
+
+ If you choose to sync, a limited set of preferences — including alert options, intervals, heart-rate
+ zones, and the automatic-sync setting — is associated with your account in Firebase Cloud Firestore. The
+ database and Cloud Functions are configured in the São Paulo region; other Firebase service data may be
+ processed across Google’s global infrastructure. Saved activities, GPX files, and upload statuses remain
+ on your device and are not sent to Firebase. See Firebase’s{' '}
+
+ privacy and security information
+ .
- The app does not automatically send location, activity metrics, or preferences to a server and does not
- maintain its own remote activity-history service.
+ Preferences and activities remain in the app’s local storage. Depending on your device and account
+ settings, Android may include them in a backup or transfer them to another device; Android and the backup
+ service you choose manage those backups.
@@ -275,6 +342,28 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
+
+ Strava connection and activity uploads
+
+ To connect an account, you authorize Strava in a browser with permission to create activities
+ (activity:write). Cloud Functions process the temporary authorization code; access and
+ refresh tokens are stored in a private Firestore record for your account. When the integration is active,
+ the Strava application secret is held in Google Secret Manager. When an activity is sent, a function returns a short-lived access token
+ to the device, which uploads the GPX directly to Strava’s API. Help DEV does not receive the GPX file or
+ activity coordinates through Firebase.
+
+
+ A manual upload sends the activity selected in its details. If you turn on Automatic sync,
+ eligible activities saved after you opt in may be uploaded automatically; existing activities are not
+ uploaded in a batch. A GPX file may contain the route, coordinates, timestamps, elevation, and, when
+ available, heart rate, cadence, temperature, and humidity. The app also sends the activity name, type, and
+ a file identifier. Strava processes and stores this data under its{' '}
+
+ Privacy Policy
+ .
+
+
+
Ads, analytics, and identifiers
@@ -311,13 +400,26 @@ export default function VelocimetroAlertaPrivacyPolicyPage() {
-
- Retention and deletion
+
+ Data retention and deletion
Preferences, saved activities, and routes remain on your device until you delete them in My activities,
- clear the app's data in Android settings, or uninstall the app. Help DEV does not keep a remote history
- of these activities. You are responsible for deleting exported GPX files and backup copies from the
- service or device where they were saved, using that destination's available options.
+ clear the app's data in Android settings, or uninstall the app. Synced preferences remain in Firestore
+ while the account record exists; signing out of Google in the app does not delete them. When you
+ disconnect Strava in the app, its authorization is revoked and stored tokens are removed. Activities
+ already uploaded remain in your Strava account and must be deleted there. Delete exported GPX files and
+ backup copies in the service or device where they were saved.
+
+
+ To request deletion of the Firebase account used by the app, its cloud preferences, and associated Strava
+ tokens, use Help DEV's{' '}
+
+ support email
+ {' '}
+ and include the email address of the Google account used in the app. The request removes the stored Strava
+ authorization and tokens, but it does not remove
+ activities already uploaded to your Strava account or GPX files that remain on your device; remove those
+ items in their respective services or in the app.
diff --git a/src/app/apps/velocimetro-alerta/strava/callback/page.tsx b/src/app/apps/velocimetro-alerta/strava/callback/page.tsx
new file mode 100644
index 0000000..2a638f2
--- /dev/null
+++ b/src/app/apps/velocimetro-alerta/strava/callback/page.tsx
@@ -0,0 +1,11 @@
+import type { Metadata } from 'next';
+import StravaCallbackFallback from './strava-callback-fallback';
+
+export const metadata: Metadata = {
+ title: 'Retorno do Strava — Velocímetro Alerta',
+ robots: { index: false, follow: false },
+};
+
+export default function StravaCallbackPage() {
+ return ;
+}
diff --git a/src/app/apps/velocimetro-alerta/strava/callback/strava-callback-fallback.tsx b/src/app/apps/velocimetro-alerta/strava/callback/strava-callback-fallback.tsx
new file mode 100644
index 0000000..e17b297
--- /dev/null
+++ b/src/app/apps/velocimetro-alerta/strava/callback/strava-callback-fallback.tsx
@@ -0,0 +1,60 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+
+const callbackPath = '/apps/velocimetro-alerta/strava/callback';
+const appPackage = 'br.com.helpdev.velocimetroalerta.v2';
+const playStoreUrl = 'https://play.google.com/store/apps/details?id=br.com.helpdev.velocimetroalerta.v2';
+
+export default function StravaCallbackFallback() {
+ const [appIntent, setAppIntent] = useState(null);
+
+ useEffect(() => {
+ const currentUrl = new URL(window.location.href);
+ const callbackParams = new URLSearchParams();
+ for (const name of ['code', 'state', 'error']) {
+ const value = currentUrl.searchParams.get(name);
+ if (value) callbackParams.set(name, value);
+ }
+
+ if (callbackParams.has('state') && (callbackParams.has('code') || callbackParams.has('error'))) {
+ const query = callbackParams.toString();
+ const fallback = encodeURIComponent(playStoreUrl);
+ setAppIntent(
+ `intent://helpdev.com.br${callbackPath}?${query}` +
+ `#Intent;scheme=https;package=${appPackage};S.browser_fallback_url=${fallback};end`
+ );
+ }
+
+ window.history.replaceState(null, document.title, callbackPath);
+ }, []);
+
+ return (
+
+
+ Velocímetro Alerta
+ Retorno do Strava
+
+ A autorização está voltando para o aplicativo. Se ele não abriu automaticamente, use o botão abaixo para
+ concluir a conexão.
+
+ {appIntent ? (
+
+ Abrir o Velocímetro Alerta
+
+ ) : (
+
+ Não encontramos os dados de retorno. Volte ao app e inicie a conexão com o Strava novamente.
+
+ )}
+
+ Se a conta não aparecer conectada em Conta e conexões, volte ao app e tente conectar
+ novamente.
+
+
+
+ );
+}
diff --git a/src/app/components/GoogleAnalytics.tsx b/src/app/components/GoogleAnalytics.tsx
index 0be8a0a..7186396 100644
--- a/src/app/components/GoogleAnalytics.tsx
+++ b/src/app/components/GoogleAnalytics.tsx
@@ -6,17 +6,21 @@ export default function GoogleAnalytics() {
-
>
);
}