@luanpdd/kit-mcp 1.33.0 → 1.34.0
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/LICENSE +21 -21
- package/README.md +168 -168
- package/gates/agent-no-recursive-dispatch.md +84 -84
- package/kit/COMANDOS.md +138 -138
- package/kit/COMPATIBILITY.md +70 -70
- package/kit/README.md +76 -76
- package/kit/agents/advisor-researcher.md +109 -109
- package/kit/agents/ai-mutation-tester.md +289 -289
- package/kit/agents/assumptions-analyzer.md +110 -110
- package/kit/agents/audit-log-implementer.md +314 -314
- package/kit/agents/auditor-consistencia-isolamento.md +414 -414
- package/kit/agents/b2b-saas-architect.md +157 -157
- package/kit/agents/burn-rate-forecaster.md +153 -153
- package/kit/agents/cascading-failures-auditor.md +299 -299
- package/kit/agents/codebase-mapper.md +769 -769
- package/kit/agents/crm-pipeline-implementer.md +257 -257
- package/kit/agents/debugger.md +814 -814
- package/kit/agents/designer-ui.md +216 -216
- package/kit/agents/detector-tenant-quente.md +338 -338
- package/kit/agents/evolution-go-integrator.md +201 -201
- package/kit/agents/example-reviewer.md +22 -22
- package/kit/agents/executor.md +565 -565
- package/kit/agents/golden-signals-instrumenter.md +232 -232
- package/kit/agents/incident-investigator.md +238 -238
- package/kit/agents/integration-checker.md +203 -203
- package/kit/agents/invite-flow-implementer.md +190 -190
- package/kit/agents/legacy-characterizer.md +369 -369
- package/kit/agents/lgpd-compliance-auditor.md +296 -296
- package/kit/agents/load-shedding-instrumenter.md +290 -290
- package/kit/agents/multi-tenant-isolation-auditor.md +254 -254
- package/kit/agents/multi-tenant-rls-writer.md +341 -341
- package/kit/agents/nyquist-auditor.md +181 -181
- package/kit/agents/observability-coverage-auditor.md +316 -316
- package/kit/agents/observability-instrumenter.md +191 -191
- package/kit/agents/omm-auditor.md +291 -291
- package/kit/agents/org-onboarding-implementer.md +224 -224
- package/kit/agents/payload-capture-instrumenter.md +274 -274
- package/kit/agents/phase-researcher.md +697 -697
- package/kit/agents/plan-checker.md +275 -275
- package/kit/agents/planner.md +923 -923
- package/kit/agents/postmortem-writer.md +273 -273
- package/kit/agents/project-researcher.md +653 -653
- package/kit/agents/prr-conductor.md +287 -287
- package/kit/agents/refactor-safety-auditor.md +405 -405
- package/kit/agents/release-pipeline-auditor.md +364 -364
- package/kit/agents/research-synthesizer.md +246 -246
- package/kit/agents/roadmapper.md +678 -678
- package/kit/agents/schema-checker.md +160 -160
- package/kit/agents/seam-finder.md +360 -360
- package/kit/agents/shotgun-surgery-detector.md +350 -350
- package/kit/agents/slo-engineer.md +217 -217
- package/kit/agents/storytelling-analyst.md +300 -300
- package/kit/agents/supabase-architect.md +249 -249
- package/kit/agents/supabase-auth-bootstrapper.md +400 -400
- package/kit/agents/supabase-auth-hook-writer.md +418 -418
- package/kit/agents/supabase-branching-architect.md +563 -563
- package/kit/agents/supabase-cicd-pipeline-implementer.md +778 -778
- package/kit/agents/supabase-column-privileges-writer.md +400 -400
- package/kit/agents/supabase-edge-fn-tester.md +288 -288
- package/kit/agents/supabase-edge-fn-writer.md +341 -341
- package/kit/agents/supabase-mfa-implementer.md +439 -439
- package/kit/agents/supabase-migration-writer.md +386 -386
- package/kit/agents/supabase-oauth-server-implementer.md +507 -507
- package/kit/agents/supabase-rbac-implementer.md +393 -393
- package/kit/agents/supabase-realtime-implementer.md +364 -364
- package/kit/agents/supabase-rls-hardener.md +522 -522
- package/kit/agents/supabase-rls-writer.md +324 -324
- package/kit/agents/supabase-roles-implementer.md +356 -356
- package/kit/agents/supabase-social-auth-implementer.md +451 -451
- package/kit/agents/supabase-sso-saml-architect.md +549 -549
- package/kit/agents/supabase-storage-implementer.md +407 -407
- package/kit/agents/super-admin-implementer.md +282 -282
- package/kit/agents/toil-auditor.md +268 -268
- package/kit/agents/ui-auditor.md +438 -438
- package/kit/agents/ui-checker.md +305 -305
- package/kit/agents/ui-researcher.md +356 -356
- package/kit/agents/user-profiler.md +176 -176
- package/kit/agents/validador-evolucao-schema.md +336 -336
- package/kit/agents/verifier.md +729 -729
- package/kit/commands/adicionar-backlog.md +75 -75
- package/kit/commands/adicionar-fase.md +42 -42
- package/kit/commands/adicionar-tarefa.md +45 -45
- package/kit/commands/adicionar-testes.md +41 -41
- package/kit/commands/ajuda.md +21 -21
- package/kit/commands/atualizar.md +37 -37
- package/kit/commands/auditar-cascading.md +111 -111
- package/kit/commands/auditar-marco.md +179 -179
- package/kit/commands/auditar-observabilidade-cobertura-workflow.md +121 -0
- package/kit/commands/auditar-observabilidade-cobertura.md +183 -183
- package/kit/commands/auditar-refactor.md +219 -219
- package/kit/commands/auditar-release.md +109 -109
- package/kit/commands/auditar-uat.md +23 -23
- package/kit/commands/autonomo.md +40 -40
- package/kit/commands/branch-pr.md +24 -24
- package/kit/commands/burn-rate-status.md +408 -408
- package/kit/commands/capturar-payloads.md +193 -193
- package/kit/commands/caracterizar.md +212 -212
- package/kit/commands/concluir-marco.md +247 -247
- package/kit/commands/configuracoes.md +36 -36
- package/kit/commands/dados-distribuidos.md +188 -188
- package/kit/commands/definir-perfil.md +10 -10
- package/kit/commands/depurar.md +190 -190
- package/kit/commands/detectar-duplicacao.md +197 -197
- package/kit/commands/discutir-fase.md +131 -131
- package/kit/commands/encontrar-seams.md +136 -136
- package/kit/commands/entrar-discord.md +17 -17
- package/kit/commands/estatisticas.md +18 -18
- package/kit/commands/example-greeting.md +33 -33
- package/kit/commands/executar-fase.md +58 -58
- package/kit/commands/expresso.md +56 -56
- package/kit/commands/fase-ui.md +34 -34
- package/kit/commands/fazer.md +57 -57
- package/kit/commands/fio.md +125 -125
- package/kit/commands/fluxos-trabalho.md +64 -64
- package/kit/commands/forense.md +176 -176
- package/kit/commands/gerenciador.md +38 -38
- package/kit/commands/inserir-fase.md +31 -31
- package/kit/commands/legacy.md +263 -263
- package/kit/commands/limpeza.md +17 -17
- package/kit/commands/listar-hipoteses-fase.md +45 -45
- package/kit/commands/listar-workspaces.md +18 -18
- package/kit/commands/load-shedding.md +117 -117
- package/kit/commands/mapear-codebase.md +70 -70
- package/kit/commands/multi-tenant.md +163 -163
- package/kit/commands/nota.md +33 -33
- package/kit/commands/novo-marco.md +43 -43
- package/kit/commands/novo-projeto.md +41 -41
- package/kit/commands/novo-workspace.md +43 -43
- package/kit/commands/pausar-trabalho.md +37 -37
- package/kit/commands/perfil-usuario.md +45 -45
- package/kit/commands/pesquisar-fase.md +195 -195
- package/kit/commands/planejar-fase.md +67 -67
- package/kit/commands/planejar-lacunas.md +33 -33
- package/kit/commands/plantar-ideia.md +25 -25
- package/kit/commands/progresso.md +24 -24
- package/kit/commands/proximo.md +30 -30
- package/kit/commands/publicar.md +490 -490
- package/kit/commands/rapido.md +35 -35
- package/kit/commands/reaplicar-patches.md +124 -124
- package/kit/commands/refactor-seguro.md +321 -321
- package/kit/commands/relatorio-sessao.md +19 -19
- package/kit/commands/remover-fase.md +31 -31
- package/kit/commands/remover-workspace.md +26 -26
- package/kit/commands/resumo-marco.md +50 -50
- package/kit/commands/retomar-trabalho.md +40 -40
- package/kit/commands/revisar-backlog.md +60 -60
- package/kit/commands/revisar-ui.md +32 -32
- package/kit/commands/revisar.md +37 -37
- package/kit/commands/saude.md +21 -21
- package/kit/commands/setup-notion.md +93 -93
- package/kit/commands/storytelling.md +179 -179
- package/kit/commands/supabase.md +238 -238
- package/kit/commands/sync-main.md +68 -68
- package/kit/commands/validar-fase.md +35 -35
- package/kit/commands/verificar-tarefas.md +44 -44
- package/kit/commands/verificar-trabalho.md +64 -64
- package/kit/file-manifest.json +13 -11
- package/kit/framework/bin/lib/commands.cjs +959 -959
- package/kit/framework/bin/lib/config.cjs +442 -442
- package/kit/framework/bin/lib/core.cjs +1230 -1230
- package/kit/framework/bin/lib/frontmatter.cjs +336 -336
- package/kit/framework/bin/lib/init.cjs +1442 -1442
- package/kit/framework/bin/lib/milestone.cjs +252 -252
- package/kit/framework/bin/lib/model-profiles.cjs +68 -68
- package/kit/framework/bin/lib/phase.cjs +888 -888
- package/kit/framework/bin/lib/profile-output.cjs +952 -952
- package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
- package/kit/framework/bin/lib/roadmap.cjs +329 -329
- package/kit/framework/bin/lib/security.cjs +382 -382
- package/kit/framework/bin/lib/state.cjs +1031 -1031
- package/kit/framework/bin/lib/template.cjs +222 -222
- package/kit/framework/bin/lib/uat.cjs +282 -282
- package/kit/framework/bin/lib/verify.cjs +888 -888
- package/kit/framework/bin/lib/workstream.cjs +491 -491
- package/kit/framework/bin/tools.cjs +918 -918
- package/kit/framework/commands/workstreams.md +63 -63
- package/kit/framework/references/checkpoints.md +778 -778
- package/kit/framework/references/continuation-format.md +249 -249
- package/kit/framework/references/decimal-phase-calculation.md +64 -64
- package/kit/framework/references/git-integration.md +295 -295
- package/kit/framework/references/git-planning-commit.md +38 -38
- package/kit/framework/references/model-profile-resolution.md +36 -36
- package/kit/framework/references/model-profiles.md +139 -139
- package/kit/framework/references/phase-argument-parsing.md +61 -61
- package/kit/framework/references/planning-config.md +202 -202
- package/kit/framework/references/questioning.md +162 -162
- package/kit/framework/references/tdd.md +263 -263
- package/kit/framework/references/ui-brand.md +160 -160
- package/kit/framework/references/user-profiling.md +657 -657
- package/kit/framework/references/verification-patterns.md +612 -612
- package/kit/framework/references/workstream-flag.md +58 -58
- package/kit/framework/templates/DEBUG.md +164 -164
- package/kit/framework/templates/UAT.md +265 -265
- package/kit/framework/templates/UI-SPEC.md +100 -100
- package/kit/framework/templates/VALIDATION.md +76 -76
- package/kit/framework/templates/claude-md.md +122 -122
- package/kit/framework/templates/codebase/architecture.md +185 -185
- package/kit/framework/templates/codebase/concerns.md +205 -205
- package/kit/framework/templates/codebase/conventions.md +204 -204
- package/kit/framework/templates/codebase/integrations.md +192 -192
- package/kit/framework/templates/codebase/stack.md +158 -158
- package/kit/framework/templates/codebase/structure.md +199 -199
- package/kit/framework/templates/codebase/testing.md +301 -301
- package/kit/framework/templates/config.json +44 -44
- package/kit/framework/templates/context.md +352 -352
- package/kit/framework/templates/continue-here.md +78 -78
- package/kit/framework/templates/copilot-instructions.md +7 -7
- package/kit/framework/templates/debug-subagent-prompt.md +91 -91
- package/kit/framework/templates/dev-preferences.md +20 -20
- package/kit/framework/templates/discovery.md +146 -146
- package/kit/framework/templates/discussion-log.md +63 -63
- package/kit/framework/templates/milestone-archive.md +123 -123
- package/kit/framework/templates/milestone.md +115 -115
- package/kit/framework/templates/phase-prompt.md +610 -610
- package/kit/framework/templates/planner-subagent-prompt.md +117 -117
- package/kit/framework/templates/project.md +186 -186
- package/kit/framework/templates/requirements.md +231 -231
- package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
- package/kit/framework/templates/research-project/FEATURES.md +147 -147
- package/kit/framework/templates/research-project/PITFALLS.md +200 -200
- package/kit/framework/templates/research-project/STACK.md +120 -120
- package/kit/framework/templates/research-project/SUMMARY.md +170 -170
- package/kit/framework/templates/research.md +419 -419
- package/kit/framework/templates/retrospective.md +54 -54
- package/kit/framework/templates/roadmap.md +202 -202
- package/kit/framework/templates/state.md +176 -176
- package/kit/framework/templates/summary-complex.md +59 -59
- package/kit/framework/templates/summary-minimal.md +41 -41
- package/kit/framework/templates/summary-standard.md +48 -48
- package/kit/framework/templates/summary.md +209 -209
- package/kit/framework/templates/user-profile.md +146 -146
- package/kit/framework/templates/user-setup.md +256 -256
- package/kit/framework/templates/verification-report.md +258 -258
- package/kit/framework/workflows/add-phase.md +112 -112
- package/kit/framework/workflows/add-tests.md +351 -351
- package/kit/framework/workflows/add-todo.md +158 -158
- package/kit/framework/workflows/audit-milestone.md +340 -340
- package/kit/framework/workflows/audit-uat.md +109 -109
- package/kit/framework/workflows/autonomous.md +891 -891
- package/kit/framework/workflows/check-todos.md +177 -177
- package/kit/framework/workflows/cleanup.md +152 -152
- package/kit/framework/workflows/complete-milestone.md +696 -696
- package/kit/framework/workflows/diagnose-issues.md +231 -231
- package/kit/framework/workflows/discovery-phase.md +289 -289
- package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
- package/kit/framework/workflows/discuss-phase.md +784 -784
- package/kit/framework/workflows/do.md +104 -104
- package/kit/framework/workflows/execute-phase.md +838 -838
- package/kit/framework/workflows/execute-plan.md +510 -510
- package/kit/framework/workflows/fast.md +102 -102
- package/kit/framework/workflows/forensics.md +265 -265
- package/kit/framework/workflows/health.md +181 -181
- package/kit/framework/workflows/help.md +619 -619
- package/kit/framework/workflows/insert-phase.md +130 -130
- package/kit/framework/workflows/list-phase-assumptions.md +178 -178
- package/kit/framework/workflows/list-workspaces.md +56 -56
- package/kit/framework/workflows/manager.md +362 -362
- package/kit/framework/workflows/map-codebase.md +377 -377
- package/kit/framework/workflows/milestone-summary.md +223 -223
- package/kit/framework/workflows/new-milestone.md +486 -486
- package/kit/framework/workflows/new-project.md +1159 -1159
- package/kit/framework/workflows/new-workspace.md +237 -237
- package/kit/framework/workflows/next.md +97 -97
- package/kit/framework/workflows/node-repair.md +92 -92
- package/kit/framework/workflows/note.md +156 -156
- package/kit/framework/workflows/pause-work.md +176 -176
- package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
- package/kit/framework/workflows/plan-phase.md +765 -765
- package/kit/framework/workflows/plant-seed.md +169 -169
- package/kit/framework/workflows/pr-branch.md +129 -129
- package/kit/framework/workflows/profile-user.md +450 -450
- package/kit/framework/workflows/progress.md +507 -507
- package/kit/framework/workflows/quick.md +757 -757
- package/kit/framework/workflows/remove-phase.md +155 -155
- package/kit/framework/workflows/remove-workspace.md +90 -90
- package/kit/framework/workflows/research-phase.md +82 -82
- package/kit/framework/workflows/resume-project.md +326 -326
- package/kit/framework/workflows/review.md +228 -228
- package/kit/framework/workflows/session-report.md +146 -146
- package/kit/framework/workflows/settings.md +283 -283
- package/kit/framework/workflows/ship.md +228 -228
- package/kit/framework/workflows/stats.md +60 -60
- package/kit/framework/workflows/transition.md +671 -671
- package/kit/framework/workflows/ui-phase.md +302 -302
- package/kit/framework/workflows/ui-review.md +165 -165
- package/kit/framework/workflows/update.md +323 -323
- package/kit/framework/workflows/validate-phase.md +174 -174
- package/kit/framework/workflows/verify-phase.md +252 -252
- package/kit/framework/workflows/verify-work.md +637 -637
- package/kit/hooks/check-update.js +118 -118
- package/kit/hooks/context-monitor.js +163 -163
- package/kit/hooks/kit-attribution-reminder.cjs +92 -92
- package/kit/hooks/kit-router.cjs +137 -137
- package/kit/hooks/prompt-guard.js +103 -103
- package/kit/hooks/statusline.js +125 -125
- package/kit/hooks/workflow-guard.js +101 -101
- package/kit/settings.json +45 -45
- package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
- package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
- package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
- package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
- package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
- package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
- package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
- package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
- package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
- package/kit/skills/example-skill/SKILL.md +42 -42
- package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
- package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
- package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
- package/kit/skills/legacy-extract-class/SKILL.md +203 -203
- package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
- package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
- package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
- package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
- package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
- package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
- package/kit/skills/member-invite-flow/SKILL.md +305 -305
- package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
- package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
- package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
- package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
- package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
- package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
- package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
- package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
- package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
- package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
- package/kit/skills/supabase-auth-hardening/SKILL.md +674 -674
- package/kit/skills/supabase-auth-hooks/SKILL.md +875 -875
- package/kit/skills/supabase-auth-methods/SKILL.md +486 -486
- package/kit/skills/supabase-auth-sessions/SKILL.md +579 -579
- package/kit/skills/supabase-auth-ssr/SKILL.md +306 -306
- package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
- package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
- package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
- package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
- package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
- package/kit/skills/supabase-edge-functions/SKILL.md +330 -330
- package/kit/skills/supabase-edge-functions-auth/SKILL.md +309 -309
- package/kit/skills/supabase-edge-functions-limits/SKILL.md +302 -302
- package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +279 -279
- package/kit/skills/supabase-edge-functions-testing/SKILL.md +277 -277
- package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +357 -357
- package/kit/skills/supabase-enterprise-sso-saml/SKILL.md +545 -545
- package/kit/skills/supabase-jwt-signing-keys/SKILL.md +399 -399
- package/kit/skills/supabase-mfa/SKILL.md +488 -488
- package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
- package/kit/skills/supabase-migrations/SKILL.md +297 -297
- package/kit/skills/supabase-oauth-server/SKILL.md +537 -537
- package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
- package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
- package/kit/skills/supabase-realtime/SKILL.md +460 -460
- package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
- package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
- package/kit/skills/supabase-social-oauth/SKILL.md +480 -480
- package/kit/skills/supabase-third-party-auth/SKILL.md +450 -450
- package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
- package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
- package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
- package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
- package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
- package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
- package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
- package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
- package/kit/skills/ui-tipografia/SKILL.md +211 -211
- package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
- package/kit/workflows/auditar-observabilidade-cobertura.workflow.js +250 -0
- package/package.json +65 -63
- package/src/core/kit.js +333 -216
- package/src/core/reflect.js +247 -247
- package/src/core/registry.js +123 -112
- package/src/core/reverse-sync.js +448 -372
- package/src/core/sync.js +477 -437
- package/src/core/watch.js +121 -121
- package/src/mcp-server/index.js +794 -794
|
@@ -1,306 +1,306 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: supabase-auth-ssr
|
|
3
|
-
description: Use ao bootstrap Next.js v16 + Supabase Auth — @supabase/ssr, getAll/setAll APENAS, NUNCA auth-helpers-nextjs, proxy com getClaims, cache headers e redirects.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Supabase — Auth SSR (Next.js v16+)
|
|
7
|
-
|
|
8
|
-
## Quando usar
|
|
9
|
-
|
|
10
|
-
LLM carrega esta skill quando bootstrap ou auditar autenticação Supabase em Next.js v16+ (App Router) com SSR. Trigger phrases:
|
|
11
|
-
|
|
12
|
-
- "Next.js + Supabase auth"
|
|
13
|
-
- "@supabase/ssr"
|
|
14
|
-
- "createServerClient", "createBrowserClient"
|
|
15
|
-
- "middleware.ts auth", "proxy auth"
|
|
16
|
-
- "cookies getAll setAll"
|
|
17
|
-
- "Supabase auth Next.js v16"
|
|
18
|
-
- "getClaims proteger página SSR", "cache headers setAll"
|
|
19
|
-
|
|
20
|
-
## Regras absolutas
|
|
21
|
-
|
|
22
|
-
**WARNING — NEVER use auth-helpers-nextjs.** O pacote `@supabase/auth-helpers-nextjs` está **DEPRECATED** e **quebra em Next.js v16+** (cookies API mudou). **SEMPRE** use `@supabase/ssr`.
|
|
23
|
-
|
|
24
|
-
**Outras regras:**
|
|
25
|
-
|
|
26
|
-
- **Padrão exclusivo `getAll`/`setAll`** para cookies — **NUNCA** `get`/`set`/`remove` individuais. Os métodos individuais não funcionam corretamente com middleware/Server Actions em Next.js v16+.
|
|
27
|
-
- **Browser client e Server client são distintos:**
|
|
28
|
-
- Browser (`createBrowserClient`) → para Client Components ("use client")
|
|
29
|
-
- Server (`createServerClient`) → para Server Components, Route Handlers, Server Actions
|
|
30
|
-
- **Middleware/Proxy (`middleware.ts`) obrigatório** para refresh de sessão SSR. Deve chamar `supabase.auth.getClaims()` em cada request — `getClaims()` valida a assinatura do JWT contra as chaves públicas publicadas e faz o refresh. **NUNCA confie em `getSession()` no servidor** — não revalida o token. `getUser()` continua válido (faz round-trip ao Auth server, garante que a sessão não foi revogada), mas é mais lento; prefira `getClaims()` para proteger páginas.
|
|
31
|
-
- **Auth method order** — após `createServerClient` mas **ANTES** de `getClaims()`, NÃO chamar nada que produza response intermediário. Os cookies precisam fluir corretamente.
|
|
32
|
-
- **Cache headers no `setAll`** — desde `@supabase/ssr` v0.10.0 o `setAll` recebe um 2º argumento com headers de cache (`Cache-Control`, `Expires`, `Pragma`). No proxy, aplique-os ao response — sem isso, um CDN/ISR pode cachear o `Set-Cookie` e vazar a sessão de um usuário para outro.
|
|
33
|
-
- **`NEXT_PUBLIC_*` apenas para a chave pública** — `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY` (chave nova `sb_publishable_...`) ou `NEXT_PUBLIC_SUPABASE_ANON_KEY` (legada, válida até fim de 2026). **NUNCA** `NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY` nem `sb_secret_...` — bypassam RLS e seriam expostos ao cliente (anti-pitfall B6).
|
|
34
|
-
- **Single serverClient factory + inicializar dentro do request handler** — não criar múltiplos clients em layouts (race condition na refresh de token — B13) nem em escopo de módulo (em Vercel Fluid compute o client é reaproveitado entre requests e vaza sessão de outro usuário).
|
|
35
|
-
|
|
36
|
-
## Patterns canônicos
|
|
37
|
-
|
|
38
|
-
### Browser client — Client Components
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
// utils/supabase/client.ts — PT-BR: client para Client Components
|
|
42
|
-
import { createBrowserClient } from '@supabase/ssr'
|
|
43
|
-
|
|
44
|
-
export function createClient() {
|
|
45
|
-
return createBrowserClient(
|
|
46
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
47
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
```tsx
|
|
53
|
-
// PT-BR: uso em Client Component
|
|
54
|
-
'use client'
|
|
55
|
-
import { createClient } from '@/utils/supabase/client'
|
|
56
|
-
|
|
57
|
-
export function LogoutButton() {
|
|
58
|
-
const supabase = createClient()
|
|
59
|
-
return <button onClick={() => supabase.auth.signOut()}>Sair</button>
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Server client — Server Components / Server Actions
|
|
64
|
-
|
|
65
|
-
```ts
|
|
66
|
-
// utils/supabase/server.ts — PT-BR: client para Server Components/Actions/Route Handlers
|
|
67
|
-
import { createServerClient } from '@supabase/ssr'
|
|
68
|
-
import { cookies } from 'next/headers'
|
|
69
|
-
|
|
70
|
-
export async function createClient() {
|
|
71
|
-
const cookieStore = await cookies()
|
|
72
|
-
|
|
73
|
-
return createServerClient(
|
|
74
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
75
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
76
|
-
{
|
|
77
|
-
cookies: {
|
|
78
|
-
getAll() {
|
|
79
|
-
return cookieStore.getAll()
|
|
80
|
-
},
|
|
81
|
-
setAll(cookiesToSet) {
|
|
82
|
-
try {
|
|
83
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
84
|
-
cookieStore.set(name, value, options)
|
|
85
|
-
)
|
|
86
|
-
} catch {
|
|
87
|
-
// PT-BR: ok ignorar — chamado em Server Component (sem permissão de set)
|
|
88
|
-
// se proxy faz refresh, sessão fica saudável mesmo sem set aqui
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
}
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
```tsx
|
|
98
|
-
// PT-BR: uso em Server Component — getClaims() valida a assinatura do JWT
|
|
99
|
-
// localmente e é a forma canônica de proteger páginas no servidor
|
|
100
|
-
import { createClient } from '@/utils/supabase/server'
|
|
101
|
-
|
|
102
|
-
export default async function Dashboard() {
|
|
103
|
-
const supabase = await createClient()
|
|
104
|
-
const { data } = await supabase.auth.getClaims()
|
|
105
|
-
const claims = data?.claims
|
|
106
|
-
if (!claims) return <p>Não autenticado</p>
|
|
107
|
-
return <p>Olá, {claims.email}</p>
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Middleware — refresh de sessão (obrigatório)
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
// middleware.ts — PT-BR: proxy obrigatório para refresh de sessão SSR
|
|
115
|
-
import { createServerClient } from '@supabase/ssr'
|
|
116
|
-
import { NextResponse, type NextRequest } from 'next/server'
|
|
117
|
-
|
|
118
|
-
export async function middleware(request: NextRequest) {
|
|
119
|
-
let supabaseResponse = NextResponse.next({ request })
|
|
120
|
-
|
|
121
|
-
const supabase = createServerClient(
|
|
122
|
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
123
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
124
|
-
{
|
|
125
|
-
cookies: {
|
|
126
|
-
getAll() {
|
|
127
|
-
return request.cookies.getAll()
|
|
128
|
-
},
|
|
129
|
-
setAll(cookiesToSet, headers) {
|
|
130
|
-
cookiesToSet.forEach(({ name, value }) =>
|
|
131
|
-
request.cookies.set(name, value)
|
|
132
|
-
)
|
|
133
|
-
supabaseResponse = NextResponse.next({ request })
|
|
134
|
-
cookiesToSet.forEach(({ name, value, options }) =>
|
|
135
|
-
supabaseResponse.cookies.set(name, value, options)
|
|
136
|
-
)
|
|
137
|
-
// PT-BR: aplicar cache headers (@supabase/ssr v0.10.0+) — impede
|
|
138
|
-
// CDN/ISR de cachear o Set-Cookie e vazar sessão entre usuários
|
|
139
|
-
Object.entries(headers ?? {}).forEach(([key, value]) =>
|
|
140
|
-
supabaseResponse.headers.set(key, value)
|
|
141
|
-
)
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
}
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
// PT-BR: ATENÇÃO — não execute código entre createServerClient e getClaims()
|
|
148
|
-
// (qualquer cookie set/get fora desse path quebra refresh silencioso)
|
|
149
|
-
// getClaims() valida a assinatura do JWT e faz o refresh da sessão
|
|
150
|
-
const { data } = await supabase.auth.getClaims()
|
|
151
|
-
const user = data?.claims ?? null
|
|
152
|
-
|
|
153
|
-
// PT-BR: redirect para /login se sem user
|
|
154
|
-
if (!user && !request.nextUrl.pathname.startsWith('/login')) {
|
|
155
|
-
const url = request.nextUrl.clone()
|
|
156
|
-
url.pathname = '/login'
|
|
157
|
-
return NextResponse.redirect(url)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// PT-BR: IMPORTANTE — sempre retornar supabaseResponse (cookies precisam fluir)
|
|
161
|
-
return supabaseResponse
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export const config = {
|
|
165
|
-
matcher: [
|
|
166
|
-
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
167
|
-
],
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Login com email/senha (Server Action)
|
|
172
|
-
|
|
173
|
-
```ts
|
|
174
|
-
// app/login/actions.ts
|
|
175
|
-
'use server'
|
|
176
|
-
import { createClient } from '@/utils/supabase/server'
|
|
177
|
-
import { redirect } from 'next/navigation'
|
|
178
|
-
|
|
179
|
-
export async function loginAction(formData: FormData) {
|
|
180
|
-
const supabase = await createClient()
|
|
181
|
-
const { error } = await supabase.auth.signInWithPassword({
|
|
182
|
-
email: formData.get('email') as string,
|
|
183
|
-
password: formData.get('password') as string,
|
|
184
|
-
})
|
|
185
|
-
if (error) return { error: error.message }
|
|
186
|
-
redirect('/dashboard')
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## Anti-patterns
|
|
191
|
-
|
|
192
|
-
### Anti-pattern 1: Importar de `@supabase/auth-helpers-nextjs`
|
|
193
|
-
|
|
194
|
-
**Errado:**
|
|
195
|
-
```ts
|
|
196
|
-
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'
|
|
197
|
-
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Por quê:** `@supabase/auth-helpers-nextjs` está **DEPRECATED**. Quebra em Next.js v16+ (cookies API mudou). Não recebe mais updates de segurança.
|
|
201
|
-
|
|
202
|
-
**Certo:**
|
|
203
|
-
```ts
|
|
204
|
-
import { createServerClient, createBrowserClient } from '@supabase/ssr'
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Anti-pattern 2: `cookies: { get, set, remove }` (individual)
|
|
208
|
-
|
|
209
|
-
**Errado:**
|
|
210
|
-
```ts
|
|
211
|
-
{
|
|
212
|
-
cookies: {
|
|
213
|
-
get(name: string) { return cookieStore.get(name) },
|
|
214
|
-
set(name: string, value: string) { cookieStore.set(name, value) },
|
|
215
|
-
remove(name: string) { cookieStore.remove(name) },
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
**Por quê:** cookie methods individuais quebram em middleware quando há múltiplos cookies sendo set/get em uma única request. `getAll`/`setAll` são chamados em batch e preservam ordem.
|
|
221
|
-
|
|
222
|
-
**Certo:** ver pattern "Server client" e "Middleware" acima.
|
|
223
|
-
|
|
224
|
-
### Anti-pattern 3: `NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY`
|
|
225
|
-
|
|
226
|
-
**Errado:**
|
|
227
|
-
```bash
|
|
228
|
-
# .env.local
|
|
229
|
-
NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY=eyJhbG...
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
**Por quê:** `NEXT_PUBLIC_*` é **público** no client bundle. `service_role` bypassa RLS — vazamento = banco totalmente exposto.
|
|
233
|
-
|
|
234
|
-
**Certo:**
|
|
235
|
-
```bash
|
|
236
|
-
# .env.local
|
|
237
|
-
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
|
238
|
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbG... # ok público
|
|
239
|
-
SUPABASE_SERVICE_ROLE_KEY=eyJhbG... # privado — sem NEXT_PUBLIC_
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
Use `service_role` apenas em código server-side que NUNCA é embarcado no bundle client (Route Handlers, Server Actions com `'use server'`, Edge Functions).
|
|
243
|
-
|
|
244
|
-
### Anti-pattern 4: Múltiplos serverClient em layouts (race condition)
|
|
245
|
-
|
|
246
|
-
**Errado:**
|
|
247
|
-
```tsx
|
|
248
|
-
// app/layout.tsx
|
|
249
|
-
const supabase1 = await createClient()
|
|
250
|
-
const { user } = await supabase1.auth.getUser()
|
|
251
|
-
// ...
|
|
252
|
-
// app/(dashboard)/layout.tsx
|
|
253
|
-
const supabase2 = await createClient() // ⚠ outro client na mesma request
|
|
254
|
-
const { user } = await supabase2.auth.getUser()
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
**Por quê:** múltiplos `createServerClient` na mesma request podem corromper cookies de refresh de token. Issue [supabase/ssr#68](https://github.com/supabase/ssr/issues/68) — race condition documentada.
|
|
258
|
-
|
|
259
|
-
**Certo:** middleware faz o refresh **uma vez por request**. Layouts apenas leem os claims via `getClaims()`:
|
|
260
|
-
```tsx
|
|
261
|
-
// app/layout.tsx — middleware já fez o refresh
|
|
262
|
-
const supabase = await createClient()
|
|
263
|
-
const { data } = await supabase.auth.getClaims()
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Anti-pattern 5: Confiar em `getSession()` no servidor
|
|
267
|
-
|
|
268
|
-
**Errado:**
|
|
269
|
-
```ts
|
|
270
|
-
// middleware.ts ou Server Component
|
|
271
|
-
const { data: { session } } = await supabase.auth.getSession()
|
|
272
|
-
if (!session) redirect('/login') // ⚠ inseguro no servidor
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
**Por quê:** `getSession()` lê a sessão direto dos cookies — que podem ser forjados — e **não revalida** o token. No servidor, use `getClaims()` (valida a assinatura do JWT contra as chaves públicas do projeto) ou `getUser()` (round-trip ao Auth server). `getSession()` é aceitável apenas no cliente.
|
|
276
|
-
|
|
277
|
-
**Certo:**
|
|
278
|
-
```ts
|
|
279
|
-
const { data } = await supabase.auth.getClaims()
|
|
280
|
-
if (!data?.claims) redirect('/login')
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
### Anti-pattern 6: Cliente Supabase em escopo de módulo (vazamento em Fluid compute)
|
|
284
|
-
|
|
285
|
-
**Errado:**
|
|
286
|
-
```ts
|
|
287
|
-
// ⚠ escopo de módulo — reaproveitado entre requests
|
|
288
|
-
const supabase = createServerClient(/* ... */)
|
|
289
|
-
export async function handler(req) { /* usa supabase compartilhado */ }
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
**Por quê:** em Vercel Fluid compute (e instâncias serverless reaproveitadas) o client persiste entre requests de usuários diferentes — a sessão de um vaza para outro.
|
|
293
|
-
|
|
294
|
-
**Certo:** crie o client **dentro** do request handler, sempre via a factory `createClient()`.
|
|
295
|
-
|
|
296
|
-
## Ver também
|
|
297
|
-
|
|
298
|
-
- [supabase-auth-methods](../supabase-auth-methods/SKILL.md) — métodos de sign-in/sign-up (password, magic link, OTP, anonymous, Web3)
|
|
299
|
-
- [supabase-social-oauth](../supabase-social-oauth/SKILL.md) — social login + rota callback PKCE `/auth/callback`
|
|
300
|
-
- [supabase-auth-sessions](../supabase-auth-sessions/SKILL.md) — fluxos implicit vs PKCE, refresh tokens
|
|
301
|
-
- [supabase-jwt-signing-keys](../supabase-jwt-signing-keys/SKILL.md) — `getClaims()`, JWKS e signing keys assimétricas
|
|
302
|
-
- [supabase-auth-hardening](../supabase-auth-hardening/SKILL.md) — redirect URLs, custom SMTP, rate limits, CAPTCHA
|
|
303
|
-
- [supabase-rls-policies](../supabase-rls-policies/SKILL.md) — RLS aplicado quando user autenticado consulta tabelas
|
|
304
|
-
- [supabase-edge-functions](../supabase-edge-functions/SKILL.md) — Edge Functions usando service_role server-side
|
|
305
|
-
- [supabase-realtime](../supabase-realtime/SKILL.md) — Realtime exige usuário autenticado para canais privados
|
|
306
|
-
- [glossário](../_shared-supabase/glossary.md) — termos PT-BR↔EN + comandos CLI
|
|
1
|
+
---
|
|
2
|
+
name: supabase-auth-ssr
|
|
3
|
+
description: Use ao bootstrap Next.js v16 + Supabase Auth — @supabase/ssr, getAll/setAll APENAS, NUNCA auth-helpers-nextjs, proxy com getClaims, cache headers e redirects.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Supabase — Auth SSR (Next.js v16+)
|
|
7
|
+
|
|
8
|
+
## Quando usar
|
|
9
|
+
|
|
10
|
+
LLM carrega esta skill quando bootstrap ou auditar autenticação Supabase em Next.js v16+ (App Router) com SSR. Trigger phrases:
|
|
11
|
+
|
|
12
|
+
- "Next.js + Supabase auth"
|
|
13
|
+
- "@supabase/ssr"
|
|
14
|
+
- "createServerClient", "createBrowserClient"
|
|
15
|
+
- "middleware.ts auth", "proxy auth"
|
|
16
|
+
- "cookies getAll setAll"
|
|
17
|
+
- "Supabase auth Next.js v16"
|
|
18
|
+
- "getClaims proteger página SSR", "cache headers setAll"
|
|
19
|
+
|
|
20
|
+
## Regras absolutas
|
|
21
|
+
|
|
22
|
+
**WARNING — NEVER use auth-helpers-nextjs.** O pacote `@supabase/auth-helpers-nextjs` está **DEPRECATED** e **quebra em Next.js v16+** (cookies API mudou). **SEMPRE** use `@supabase/ssr`.
|
|
23
|
+
|
|
24
|
+
**Outras regras:**
|
|
25
|
+
|
|
26
|
+
- **Padrão exclusivo `getAll`/`setAll`** para cookies — **NUNCA** `get`/`set`/`remove` individuais. Os métodos individuais não funcionam corretamente com middleware/Server Actions em Next.js v16+.
|
|
27
|
+
- **Browser client e Server client são distintos:**
|
|
28
|
+
- Browser (`createBrowserClient`) → para Client Components ("use client")
|
|
29
|
+
- Server (`createServerClient`) → para Server Components, Route Handlers, Server Actions
|
|
30
|
+
- **Middleware/Proxy (`middleware.ts`) obrigatório** para refresh de sessão SSR. Deve chamar `supabase.auth.getClaims()` em cada request — `getClaims()` valida a assinatura do JWT contra as chaves públicas publicadas e faz o refresh. **NUNCA confie em `getSession()` no servidor** — não revalida o token. `getUser()` continua válido (faz round-trip ao Auth server, garante que a sessão não foi revogada), mas é mais lento; prefira `getClaims()` para proteger páginas.
|
|
31
|
+
- **Auth method order** — após `createServerClient` mas **ANTES** de `getClaims()`, NÃO chamar nada que produza response intermediário. Os cookies precisam fluir corretamente.
|
|
32
|
+
- **Cache headers no `setAll`** — desde `@supabase/ssr` v0.10.0 o `setAll` recebe um 2º argumento com headers de cache (`Cache-Control`, `Expires`, `Pragma`). No proxy, aplique-os ao response — sem isso, um CDN/ISR pode cachear o `Set-Cookie` e vazar a sessão de um usuário para outro.
|
|
33
|
+
- **`NEXT_PUBLIC_*` apenas para a chave pública** — `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY` (chave nova `sb_publishable_...`) ou `NEXT_PUBLIC_SUPABASE_ANON_KEY` (legada, válida até fim de 2026). **NUNCA** `NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY` nem `sb_secret_...` — bypassam RLS e seriam expostos ao cliente (anti-pitfall B6).
|
|
34
|
+
- **Single serverClient factory + inicializar dentro do request handler** — não criar múltiplos clients em layouts (race condition na refresh de token — B13) nem em escopo de módulo (em Vercel Fluid compute o client é reaproveitado entre requests e vaza sessão de outro usuário).
|
|
35
|
+
|
|
36
|
+
## Patterns canônicos
|
|
37
|
+
|
|
38
|
+
### Browser client — Client Components
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
// utils/supabase/client.ts — PT-BR: client para Client Components
|
|
42
|
+
import { createBrowserClient } from '@supabase/ssr'
|
|
43
|
+
|
|
44
|
+
export function createClient() {
|
|
45
|
+
return createBrowserClient(
|
|
46
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
47
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
// PT-BR: uso em Client Component
|
|
54
|
+
'use client'
|
|
55
|
+
import { createClient } from '@/utils/supabase/client'
|
|
56
|
+
|
|
57
|
+
export function LogoutButton() {
|
|
58
|
+
const supabase = createClient()
|
|
59
|
+
return <button onClick={() => supabase.auth.signOut()}>Sair</button>
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Server client — Server Components / Server Actions
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// utils/supabase/server.ts — PT-BR: client para Server Components/Actions/Route Handlers
|
|
67
|
+
import { createServerClient } from '@supabase/ssr'
|
|
68
|
+
import { cookies } from 'next/headers'
|
|
69
|
+
|
|
70
|
+
export async function createClient() {
|
|
71
|
+
const cookieStore = await cookies()
|
|
72
|
+
|
|
73
|
+
return createServerClient(
|
|
74
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
75
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
76
|
+
{
|
|
77
|
+
cookies: {
|
|
78
|
+
getAll() {
|
|
79
|
+
return cookieStore.getAll()
|
|
80
|
+
},
|
|
81
|
+
setAll(cookiesToSet) {
|
|
82
|
+
try {
|
|
83
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
84
|
+
cookieStore.set(name, value, options)
|
|
85
|
+
)
|
|
86
|
+
} catch {
|
|
87
|
+
// PT-BR: ok ignorar — chamado em Server Component (sem permissão de set)
|
|
88
|
+
// se proxy faz refresh, sessão fica saudável mesmo sem set aqui
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
// PT-BR: uso em Server Component — getClaims() valida a assinatura do JWT
|
|
99
|
+
// localmente e é a forma canônica de proteger páginas no servidor
|
|
100
|
+
import { createClient } from '@/utils/supabase/server'
|
|
101
|
+
|
|
102
|
+
export default async function Dashboard() {
|
|
103
|
+
const supabase = await createClient()
|
|
104
|
+
const { data } = await supabase.auth.getClaims()
|
|
105
|
+
const claims = data?.claims
|
|
106
|
+
if (!claims) return <p>Não autenticado</p>
|
|
107
|
+
return <p>Olá, {claims.email}</p>
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Middleware — refresh de sessão (obrigatório)
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// middleware.ts — PT-BR: proxy obrigatório para refresh de sessão SSR
|
|
115
|
+
import { createServerClient } from '@supabase/ssr'
|
|
116
|
+
import { NextResponse, type NextRequest } from 'next/server'
|
|
117
|
+
|
|
118
|
+
export async function middleware(request: NextRequest) {
|
|
119
|
+
let supabaseResponse = NextResponse.next({ request })
|
|
120
|
+
|
|
121
|
+
const supabase = createServerClient(
|
|
122
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
123
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
124
|
+
{
|
|
125
|
+
cookies: {
|
|
126
|
+
getAll() {
|
|
127
|
+
return request.cookies.getAll()
|
|
128
|
+
},
|
|
129
|
+
setAll(cookiesToSet, headers) {
|
|
130
|
+
cookiesToSet.forEach(({ name, value }) =>
|
|
131
|
+
request.cookies.set(name, value)
|
|
132
|
+
)
|
|
133
|
+
supabaseResponse = NextResponse.next({ request })
|
|
134
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
135
|
+
supabaseResponse.cookies.set(name, value, options)
|
|
136
|
+
)
|
|
137
|
+
// PT-BR: aplicar cache headers (@supabase/ssr v0.10.0+) — impede
|
|
138
|
+
// CDN/ISR de cachear o Set-Cookie e vazar sessão entre usuários
|
|
139
|
+
Object.entries(headers ?? {}).forEach(([key, value]) =>
|
|
140
|
+
supabaseResponse.headers.set(key, value)
|
|
141
|
+
)
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
// PT-BR: ATENÇÃO — não execute código entre createServerClient e getClaims()
|
|
148
|
+
// (qualquer cookie set/get fora desse path quebra refresh silencioso)
|
|
149
|
+
// getClaims() valida a assinatura do JWT e faz o refresh da sessão
|
|
150
|
+
const { data } = await supabase.auth.getClaims()
|
|
151
|
+
const user = data?.claims ?? null
|
|
152
|
+
|
|
153
|
+
// PT-BR: redirect para /login se sem user
|
|
154
|
+
if (!user && !request.nextUrl.pathname.startsWith('/login')) {
|
|
155
|
+
const url = request.nextUrl.clone()
|
|
156
|
+
url.pathname = '/login'
|
|
157
|
+
return NextResponse.redirect(url)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// PT-BR: IMPORTANTE — sempre retornar supabaseResponse (cookies precisam fluir)
|
|
161
|
+
return supabaseResponse
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const config = {
|
|
165
|
+
matcher: [
|
|
166
|
+
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
|
|
167
|
+
],
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Login com email/senha (Server Action)
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
// app/login/actions.ts
|
|
175
|
+
'use server'
|
|
176
|
+
import { createClient } from '@/utils/supabase/server'
|
|
177
|
+
import { redirect } from 'next/navigation'
|
|
178
|
+
|
|
179
|
+
export async function loginAction(formData: FormData) {
|
|
180
|
+
const supabase = await createClient()
|
|
181
|
+
const { error } = await supabase.auth.signInWithPassword({
|
|
182
|
+
email: formData.get('email') as string,
|
|
183
|
+
password: formData.get('password') as string,
|
|
184
|
+
})
|
|
185
|
+
if (error) return { error: error.message }
|
|
186
|
+
redirect('/dashboard')
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Anti-patterns
|
|
191
|
+
|
|
192
|
+
### Anti-pattern 1: Importar de `@supabase/auth-helpers-nextjs`
|
|
193
|
+
|
|
194
|
+
**Errado:**
|
|
195
|
+
```ts
|
|
196
|
+
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'
|
|
197
|
+
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Por quê:** `@supabase/auth-helpers-nextjs` está **DEPRECATED**. Quebra em Next.js v16+ (cookies API mudou). Não recebe mais updates de segurança.
|
|
201
|
+
|
|
202
|
+
**Certo:**
|
|
203
|
+
```ts
|
|
204
|
+
import { createServerClient, createBrowserClient } from '@supabase/ssr'
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Anti-pattern 2: `cookies: { get, set, remove }` (individual)
|
|
208
|
+
|
|
209
|
+
**Errado:**
|
|
210
|
+
```ts
|
|
211
|
+
{
|
|
212
|
+
cookies: {
|
|
213
|
+
get(name: string) { return cookieStore.get(name) },
|
|
214
|
+
set(name: string, value: string) { cookieStore.set(name, value) },
|
|
215
|
+
remove(name: string) { cookieStore.remove(name) },
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Por quê:** cookie methods individuais quebram em middleware quando há múltiplos cookies sendo set/get em uma única request. `getAll`/`setAll` são chamados em batch e preservam ordem.
|
|
221
|
+
|
|
222
|
+
**Certo:** ver pattern "Server client" e "Middleware" acima.
|
|
223
|
+
|
|
224
|
+
### Anti-pattern 3: `NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY`
|
|
225
|
+
|
|
226
|
+
**Errado:**
|
|
227
|
+
```bash
|
|
228
|
+
# .env.local
|
|
229
|
+
NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY=eyJhbG...
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Por quê:** `NEXT_PUBLIC_*` é **público** no client bundle. `service_role` bypassa RLS — vazamento = banco totalmente exposto.
|
|
233
|
+
|
|
234
|
+
**Certo:**
|
|
235
|
+
```bash
|
|
236
|
+
# .env.local
|
|
237
|
+
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
|
238
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbG... # ok público
|
|
239
|
+
SUPABASE_SERVICE_ROLE_KEY=eyJhbG... # privado — sem NEXT_PUBLIC_
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Use `service_role` apenas em código server-side que NUNCA é embarcado no bundle client (Route Handlers, Server Actions com `'use server'`, Edge Functions).
|
|
243
|
+
|
|
244
|
+
### Anti-pattern 4: Múltiplos serverClient em layouts (race condition)
|
|
245
|
+
|
|
246
|
+
**Errado:**
|
|
247
|
+
```tsx
|
|
248
|
+
// app/layout.tsx
|
|
249
|
+
const supabase1 = await createClient()
|
|
250
|
+
const { user } = await supabase1.auth.getUser()
|
|
251
|
+
// ...
|
|
252
|
+
// app/(dashboard)/layout.tsx
|
|
253
|
+
const supabase2 = await createClient() // ⚠ outro client na mesma request
|
|
254
|
+
const { user } = await supabase2.auth.getUser()
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Por quê:** múltiplos `createServerClient` na mesma request podem corromper cookies de refresh de token. Issue [supabase/ssr#68](https://github.com/supabase/ssr/issues/68) — race condition documentada.
|
|
258
|
+
|
|
259
|
+
**Certo:** middleware faz o refresh **uma vez por request**. Layouts apenas leem os claims via `getClaims()`:
|
|
260
|
+
```tsx
|
|
261
|
+
// app/layout.tsx — middleware já fez o refresh
|
|
262
|
+
const supabase = await createClient()
|
|
263
|
+
const { data } = await supabase.auth.getClaims()
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Anti-pattern 5: Confiar em `getSession()` no servidor
|
|
267
|
+
|
|
268
|
+
**Errado:**
|
|
269
|
+
```ts
|
|
270
|
+
// middleware.ts ou Server Component
|
|
271
|
+
const { data: { session } } = await supabase.auth.getSession()
|
|
272
|
+
if (!session) redirect('/login') // ⚠ inseguro no servidor
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Por quê:** `getSession()` lê a sessão direto dos cookies — que podem ser forjados — e **não revalida** o token. No servidor, use `getClaims()` (valida a assinatura do JWT contra as chaves públicas do projeto) ou `getUser()` (round-trip ao Auth server). `getSession()` é aceitável apenas no cliente.
|
|
276
|
+
|
|
277
|
+
**Certo:**
|
|
278
|
+
```ts
|
|
279
|
+
const { data } = await supabase.auth.getClaims()
|
|
280
|
+
if (!data?.claims) redirect('/login')
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Anti-pattern 6: Cliente Supabase em escopo de módulo (vazamento em Fluid compute)
|
|
284
|
+
|
|
285
|
+
**Errado:**
|
|
286
|
+
```ts
|
|
287
|
+
// ⚠ escopo de módulo — reaproveitado entre requests
|
|
288
|
+
const supabase = createServerClient(/* ... */)
|
|
289
|
+
export async function handler(req) { /* usa supabase compartilhado */ }
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Por quê:** em Vercel Fluid compute (e instâncias serverless reaproveitadas) o client persiste entre requests de usuários diferentes — a sessão de um vaza para outro.
|
|
293
|
+
|
|
294
|
+
**Certo:** crie o client **dentro** do request handler, sempre via a factory `createClient()`.
|
|
295
|
+
|
|
296
|
+
## Ver também
|
|
297
|
+
|
|
298
|
+
- [supabase-auth-methods](../supabase-auth-methods/SKILL.md) — métodos de sign-in/sign-up (password, magic link, OTP, anonymous, Web3)
|
|
299
|
+
- [supabase-social-oauth](../supabase-social-oauth/SKILL.md) — social login + rota callback PKCE `/auth/callback`
|
|
300
|
+
- [supabase-auth-sessions](../supabase-auth-sessions/SKILL.md) — fluxos implicit vs PKCE, refresh tokens
|
|
301
|
+
- [supabase-jwt-signing-keys](../supabase-jwt-signing-keys/SKILL.md) — `getClaims()`, JWKS e signing keys assimétricas
|
|
302
|
+
- [supabase-auth-hardening](../supabase-auth-hardening/SKILL.md) — redirect URLs, custom SMTP, rate limits, CAPTCHA
|
|
303
|
+
- [supabase-rls-policies](../supabase-rls-policies/SKILL.md) — RLS aplicado quando user autenticado consulta tabelas
|
|
304
|
+
- [supabase-edge-functions](../supabase-edge-functions/SKILL.md) — Edge Functions usando service_role server-side
|
|
305
|
+
- [supabase-realtime](../supabase-realtime/SKILL.md) — Realtime exige usuário autenticado para canais privados
|
|
306
|
+
- [glossário](../_shared-supabase/glossary.md) — termos PT-BR↔EN + comandos CLI
|