mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 09:19:51 +00:00
perf: use getSession() instead of getUser() in client components
Major performance improvement. Every client component that needed the
current user was calling supabase.auth.getUser(), which makes a
network round-trip to Supabase to validate the JWT. On a page that
fetches data conditional on the user, the flow was:
Page mount
-> getUser() [network ~150-400ms]
-> query data [network ~150-400ms]
-> render
That's 2 serial round-trips before the page renders.
supabase.auth.getSession() reads the session from localStorage with
NO network call. Using it in client code cuts per-page load by one
full round-trip (~150-400ms depending on region latency).
Replaced in 10 client files:
- src/app/(dashboard)/inbox/page.tsx
- src/app/(dashboard)/pipelines/page.tsx
- src/components/contacts/contact-detail-view.tsx
- src/components/contacts/contact-form.tsx
- src/components/contacts/import-modal.tsx
- src/components/inbox/contact-sidebar.tsx
- src/components/pipelines/deal-form.tsx
- src/components/pipelines/pipeline-settings.tsx
- src/components/settings/tag-manager.tsx
- src/components/settings/template-manager.tsx
- src/components/settings/whatsapp-config.tsx
NOT changed (correctly continue using getUser):
- src/middleware.ts (server-side, needs JWT validation)
- src/app/api/whatsapp/*/route.ts (server-side, security-critical)
- src/hooks/use-auth.ts (PR #4 handles this file)
Security note: getSession() trusts the client-stored session. For
API routes and middleware that make authorization decisions, we still
use getUser() which verifies with Supabase. Client components only
use the session's user ID to filter RLS-protected queries — the RLS
on the database is the actual authorization boundary, so a forged
user ID in the browser wouldn't bypass server-side policies.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
658d070811
commit
2e7d7a6282
@ -25,8 +25,9 @@ export default function InboxPage() {
|
||||
const checkConnection = async () => {
|
||||
const supabase = createClient();
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
|
||||
if (!user) return;
|
||||
|
||||
|
||||
@ -85,8 +85,9 @@ export default function PipelinesPage() {
|
||||
setCreating(true);
|
||||
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
if (!user) {
|
||||
setCreating(false);
|
||||
return;
|
||||
|
||||
@ -223,8 +223,9 @@ export function ContactDetailView({
|
||||
setSavingNote(true);
|
||||
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
if (!user) {
|
||||
toast.error('Not authenticated');
|
||||
setSavingNote(false);
|
||||
|
||||
@ -87,8 +87,9 @@ export function ContactForm({
|
||||
|
||||
try {
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
if (!user) throw new Error('Not authenticated');
|
||||
|
||||
let contactId = contact?.id;
|
||||
|
||||
@ -123,8 +123,9 @@ export function ImportModal({ open, onOpenChange, onImported }: ImportModalProps
|
||||
|
||||
try {
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
if (!user) throw new Error('Not authenticated');
|
||||
|
||||
let imported = 0;
|
||||
|
||||
@ -84,8 +84,9 @@ export function ContactSidebar({ contact }: ContactSidebarProps) {
|
||||
|
||||
const supabase = createClient();
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from("contact_notes")
|
||||
|
||||
@ -96,8 +96,9 @@ export function DealForm({
|
||||
await supabase.from("deals").update(payload).eq("id", deal.id);
|
||||
} else {
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
if (user) {
|
||||
await supabase
|
||||
.from("deals")
|
||||
|
||||
@ -92,8 +92,9 @@ export function PipelineSettings({
|
||||
async function handleAddStage() {
|
||||
if (!newStageName.trim()) return;
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const user = session?.user;
|
||||
if (!user) return;
|
||||
|
||||
const { data } = await supabase
|
||||
|
||||
@ -49,7 +49,7 @@ export function TagManager() {
|
||||
async function fetchTags() {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const { data: { session } } = await supabase.auth.getSession(); const user = session?.user;
|
||||
if (!user) return;
|
||||
|
||||
const { data, error } = await supabase
|
||||
@ -76,7 +76,7 @@ export function TagManager() {
|
||||
|
||||
try {
|
||||
setSaving(true);
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const { data: { session } } = await supabase.auth.getSession(); const user = session?.user;
|
||||
if (!user) {
|
||||
toast.error('Not authenticated');
|
||||
return;
|
||||
|
||||
@ -77,7 +77,7 @@ export function TemplateManager() {
|
||||
async function fetchTemplates() {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const { data: { session } } = await supabase.auth.getSession(); const user = session?.user;
|
||||
if (!user) return;
|
||||
|
||||
const { data, error } = await supabase
|
||||
@ -108,7 +108,7 @@ export function TemplateManager() {
|
||||
|
||||
try {
|
||||
setSaving(true);
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const { data: { session } } = await supabase.auth.getSession(); const user = session?.user;
|
||||
if (!user) {
|
||||
toast.error('Not authenticated');
|
||||
return;
|
||||
|
||||
@ -56,7 +56,7 @@ export function WhatsAppConfig() {
|
||||
async function fetchConfig() {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const { data: { session } } = await supabase.auth.getSession(); const user = session?.user;
|
||||
if (!user) return;
|
||||
|
||||
const { data, error } = await supabase
|
||||
@ -97,7 +97,7 @@ export function WhatsAppConfig() {
|
||||
|
||||
try {
|
||||
setSaving(true);
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const { data: { session } } = await supabase.auth.getSession(); const user = session?.user;
|
||||
if (!user) {
|
||||
toast.error('Not authenticated');
|
||||
return;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user