Auth
Este aplicativo executa seu próprio Better Auth em
/api/auth/*, federando ao broker de autenticação Grok compartilhado (auth.grok.me)
via o plugin genericOAuth. Este modelo conecta Google e X.
Métodos de login suportados — use APENAS estes três; nada mais é suportado:
Google, X e email/senha. Nenhum outro provedor social/OAuth (GitHub, Apple,
Discord, …), sem links mágicos, chaves de acesso, OTP, telefone/SMS ou login anônimo. Não
adicione entradas a GROK_PROVIDERS. Detalhes do método e a chave de email/senha
(edite apenas src/lib/auth/email-password.ts): references/sign-in-methods.md.
Exceção — visualizadores de gate já estão logados; NUNCA renderize botões de login/re-autenticação
para eles. Aplicativos connector / app-data: APENAS gate "Continuar com Grok",
sem botões do Google/X: references/grok-identity.md.
O login está DESLIGADO por padrão — o modelo fornece .grok/app-env.json com
{"VITE_AUTH_ENABLED": "false"}, então adicione contas apenas quando a solicitação exigir
(AGENTS.md §0.5). Ativá-lo é "Ativando o login" abaixo.
Uma vez ativo, o login é REAL — inclusive na pré-visualização ao vivo do sandbox. NÃO
monte usuários de demonstração/mock/hardcoded. Pré-visualização: popup + cliente de pré-visualização embutido;
implantado: cliente por aplicativo + DATABASE_URL + login de gate com zero clique
(references/prewired-and-env.md).
Enquanto DESLIGADO (VITE_AUTH_ENABLED=false) um usuário de desenvolvimento é retornado para que um
aplicativo sem autenticação renderize sem um visitante logado — apenas em desenvolvimento e pré-visualização.
Implantado, a flag é da plataforma (sempre "true"), então requireUserId
rejeita todo visitante — aplicativos sem autenticação não usam nem ela nem authMiddleware.
Tudo está pré-instalado e pré-configurado em src/lib/auth/ — não execute
npm install em nada; better-auth é o único pacote de autenticação (nunca
@neondatabase/*, @stackframe/* ou @clerk/*). Não edite ou reescreva nenhum
arquivo em src/lib/auth/ — server.ts menos ainda — exceto
email-password.ts para sua única flag. Mapa por arquivo:
references/prewired-and-env.md.
/auth/popup já é tratado pelo plugin Vite do modelo
(vite.config.ts → popup.server.ts): ele nunca renderiza o aplicativo React. NÃO
crie src/routes/auth/popup.tsx (ou qualquer página React / OAuth de cliente nesse
caminho) — isso mostra o aplicativo completo dentro do popup, o modo de falha comum.
Nunca escreva um arquivo .env / .env.local / .env.example neste sandbox:
a pré-visualização ao vivo precisa de zero configuração de ambiente e um aplicativo implantado recebe suas variáveis
injetadas pela plataforma. Os botões que existem estão em
references/prewired-and-env.md — nunca exponha uma variável que não seja VITE_ ao cliente.
migrations/auth/0001_auth.sql é o schema do Better Auth — não edite. Ele
fica fora do diretório migrations/ com glob (nenhum aplicador desce),
portanto não é aplicado a aplicativos sem login; "Ativando o login" o copia para cima.
Ativando o login
Faça tudo isso — apenas as rotas renderizam o ramo desabilitado:
- Flag: remova a chave
VITE_AUTH_ENABLEDde.grok/app-env.jsone reinicie o servidor de desenvolvimento. O Vite lê as variáveis de ambiente na inicialização, então HMR não as reconhecerá.npm run dev,npm run buildenpm run previewleem esse arquivo através descripts/with-app-env.mjs, então a pré-visualização e a saída compilada mudam juntas — nunca inicie o Vite diretamente. - Schema:
cp migrations/auth/0001_auth.sql migrations/0001_auth.sql, então reinicie para que seja aplicado. Ele é rastreado pelo nome base em_migrations, então um banco de dados que já o possui não o executará novamente. - Rotas: adicione
src/routes/api/auth/$.ts+src/routes/login.tsx— copie ambos dereferences/wiring.md(a rota de API catch-all é o que faz/api/auth/*e o callback do broker funcionarem). - Logout: um login sem saída não está completo — renderize
<UserButton />de@/lib/auth/gates(que chamasignOut(); oculta logout para sessões de gate). - Dados existentes: envolva as funções de servidor do aplicativo em
authMiddleware(um aplicativo sem autenticação não deve ter usado isso — veja o skillneon). Linhas de antes do login existir são dados de desenvolvimento: descarte e recrie-os a menos que o usuário diga o contrário — não os entregue a quem fizer login primeiro.
Construindo sobre ele uma vez ativo
- Login / logout:
signIn(providerId)esignOut()de@/lib/auth/client;GROK_PROVIDERSrenderiza os botões. O popup, hand-off do token bearer e anexo de requisição são internos — deixe-os em paz. Prefira<UserButton />(ele lida com os estados pendente e de falha);signOut()rejeita quando implantado se o servidor nunca confirma — capture isso. NuncaauthClient.signOut(): ele deixa o token bearer da pré-visualização anexado a toda requisição posterior, então o visitante permanece logado. - Lendo o usuário:
useCurrentUser()é apenas para exibição (nullsignifica carregando OU desconectado, então nunca redirecione apenas com base nele); proteja-se comuseCurrentUserState()'sisPendingem vez disso. Gates (SignedIn,SignedOut,SignInGate,RedirectToSignIn,UserButton) estão em@/lib/auth/gates. Regras rígidas de CTA, esqueleto e cookie-SSR sem flash:references/session-ui.md. - Dados por usuário (obrigatório): toda função de servidor que acessa dados por usuário
deve usar o
authMiddlewarepré-configurado e escopar toda leitura e escrita acontext.userId— um driver Postgres tem acesso total ao banco, então nada mais limita a consulta. Mantenha colunasuser_idcomoTEXT; nunca confie em um ID de usuário fornecido pelo cliente; desconectado, o middleware lançaUnauthorizedError(401). Código e semântica do modo desabilitado:references/per-user-data.md. - Modelo de segurança: broker headless, cookies
__Host-+trustedOriginse isolamento de irmãos Fetch-Metadata já estão configurados — nunca os enfraqueça para fazer um erro desaparecer (references/sign-in-methods.mdcobre o modelo e a correção do "Origem inválida").