validating data
This commit is contained in:
@@ -22,7 +22,7 @@ const authModule = {
|
|||||||
// (because your Krow user metadata is stored in the "users" table)
|
// (because your Krow user metadata is stored in the "users" table)
|
||||||
let krowUser = null;
|
let krowUser = null;
|
||||||
try {
|
try {
|
||||||
const response = await dcSdk.getUser(dataConnect, { id: fbUser.uid });
|
const response = await dcSdk.getUserById(dataConnect, { id: fbUser.uid });
|
||||||
krowUser = response.data?.user || null;
|
krowUser = response.data?.user || null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("Krow user not found in DataConnect, returning Firebase-only info.");
|
console.warn("Krow user not found in DataConnect, returning Firebase-only info.");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { base44 } from "@/api/base44Client";
|
import { krowSDK } from "@/api/krowSDK";
|
||||||
import { useMutation, useQueryClient, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQueryClient, useQuery } from "@tanstack/react-query";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { createPageUrl } from "@/utils";
|
import { createPageUrl } from "@/utils";
|
||||||
@@ -21,17 +21,17 @@ export default function CreateEvent() {
|
|||||||
|
|
||||||
const { data: currentUser } = useQuery({
|
const { data: currentUser } = useQuery({
|
||||||
queryKey: ['current-user-create-event'],
|
queryKey: ['current-user-create-event'],
|
||||||
queryFn: () => base44.auth.me(),
|
queryFn: () => krowSDK.auth.me(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: allEvents = [] } = useQuery({
|
const { data: allEvents = [] } = useQuery({
|
||||||
queryKey: ['events-for-conflict-check'],
|
queryKey: ['events-for-conflict-check'],
|
||||||
queryFn: () => base44.entities.Event.list(),
|
queryFn: () => krowSDK.entities.Event.list(),
|
||||||
initialData: [],
|
initialData: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const createEventMutation = useMutation({
|
const createEventMutation = useMutation({
|
||||||
mutationFn: (eventData) => base44.entities.Event.create(eventData),
|
mutationFn: (eventData) => krowSDK.entities.Event.create(eventData),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['events'] });
|
queryClient.invalidateQueries({ queryKey: ['events'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['client-events'] });
|
queryClient.invalidateQueries({ queryKey: ['client-events'] });
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { base44 } from "@/api/base44Client";
|
import { krowSDK } from "@/api/krowSDK";
|
||||||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { createPageUrl } from "@/utils";
|
import { createPageUrl } from "@/utils";
|
||||||
@@ -79,7 +79,7 @@ export default function Teams() {
|
|||||||
|
|
||||||
const { data: user } = useQuery({
|
const { data: user } = useQuery({
|
||||||
queryKey: ['current-user-teams'],
|
queryKey: ['current-user-teams'],
|
||||||
queryFn: () => base44.auth.me(),
|
queryFn: () => krowSDK.auth.me(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const userRole = user?.user_role || user?.role;
|
const userRole = user?.user_role || user?.role;
|
||||||
@@ -100,7 +100,7 @@ export default function Teams() {
|
|||||||
*/
|
*/
|
||||||
const { data: userTeam } = useQuery({
|
const { data: userTeam } = useQuery({
|
||||||
queryKey: ['user-team', user?.id, userRole],
|
queryKey: ['user-team', user?.id, userRole],
|
||||||
queryFn: async () => {
|
queryFn: async () => {debugger;
|
||||||
if (!user?.id) {
|
if (!user?.id) {
|
||||||
console.warn("⚠️ No user ID found - cannot fetch team");
|
console.warn("⚠️ No user ID found - cannot fetch team");
|
||||||
return null;
|
return null;
|
||||||
@@ -108,13 +108,15 @@ export default function Teams() {
|
|||||||
|
|
||||||
// SECURITY: Fetch ALL teams and filter by owner_id
|
// SECURITY: Fetch ALL teams and filter by owner_id
|
||||||
// This ensures only THIS user's team is returned
|
// This ensures only THIS user's team is returned
|
||||||
const allTeams = await base44.entities.Team.list('-created_date');
|
const result = await krowSDK.entities.Team.list('-created_date');
|
||||||
|
|
||||||
|
const allTeams = result?.data?.teams ?? [];//new, get array from object
|
||||||
|
|
||||||
// Find ONLY teams owned by this specific user
|
// Find ONLY teams owned by this specific user
|
||||||
let team = allTeams.find(t => t.owner_id === user.id);
|
let team = allTeams.find(t => t.owner_id === user.id);
|
||||||
|
debugger;
|
||||||
// ISOLATION VERIFICATION
|
// ISOLATION VERIFICATION
|
||||||
if (team && team.owner_id !== user.id) {
|
if (team && team.ownerId !== user.id) {//it had team.owner_id I changed it to team.ownerId
|
||||||
console.error("🚨 SECURITY VIOLATION: Team owner mismatch!");
|
console.error("🚨 SECURITY VIOLATION: Team owner mismatch!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -122,23 +124,29 @@ export default function Teams() {
|
|||||||
// Auto-create team if doesn't exist (first time user accesses Teams)
|
// Auto-create team if doesn't exist (first time user accesses Teams)
|
||||||
if (!team && user.id) {
|
if (!team && user.id) {
|
||||||
console.log(`✅ Creating new isolated team for ${userRole} user: ${user.email}`);
|
console.log(`✅ Creating new isolated team for ${userRole} user: ${user.email}`);
|
||||||
const teamName = user.company_name || `${user.full_name}'s Team` || "My Team";
|
const teamName = user.companyName || `${user.fullName}'s Team` || "My Team";
|
||||||
|
try {
|
||||||
team = await base44.entities.Team.create({
|
team = await krowSDK.entities.Team.create({
|
||||||
team_name: teamName,
|
data: {
|
||||||
owner_id: user.id, // CRITICAL: Links team to THIS user only
|
teamName: teamName,
|
||||||
owner_name: user.full_name || user.email,
|
ownerId: user.id, // CRITICAL: Links team to THIS user only
|
||||||
owner_role: userRole, // Tracks which layer this team belongs to
|
ownerName: user.fullName || user.email,
|
||||||
email: user.email,
|
ownerRole: userRole, // Tracks which layer this team belongs to
|
||||||
phone: user.phone || "",
|
//email: user.email,
|
||||||
total_members: 0,
|
//phone: user.phone || "",
|
||||||
active_members: 0,
|
//totalMembers: 0,
|
||||||
total_hubs: 0,
|
//active_members: 0,
|
||||||
favorite_staff_count: 0,
|
//total_hubs: 0,
|
||||||
blocked_staff_count: 0,
|
favoriteStaff: 0,//favoriteStaff_count: 0,
|
||||||
departments: [], // Initialize with an empty array for departments
|
blockedStaff: 0,//blockedStaff_count: 0,
|
||||||
});
|
//departments: [], // Initialize with an empty array for departments
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.log('🔥 Error in user-team queryFn:', err);
|
||||||
|
throw err; // deja que React Query lo maneje como error
|
||||||
|
}
|
||||||
console.log(`✅ Team created successfully for ${userRole}: ${team.id}`);
|
console.log(`✅ Team created successfully for ${userRole}: ${team.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +185,7 @@ export default function Teams() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fetch all members and filter by team_id
|
// Fetch all members and filter by team_id
|
||||||
const allMembers = await base44.entities.TeamMember.list('-created_date');
|
const allMembers = await krowSDK.entities.TeamMember.list('-created_date');
|
||||||
|
|
||||||
// SECURITY: Only return members that belong to THIS user's team
|
// SECURITY: Only return members that belong to THIS user's team
|
||||||
const filteredMembers = allMembers.filter(m => m.team_id === userTeam.id);
|
const filteredMembers = allMembers.filter(m => m.team_id === userTeam.id);
|
||||||
@@ -202,7 +210,7 @@ export default function Teams() {
|
|||||||
queryKey: ['team-invites', userTeam?.id],
|
queryKey: ['team-invites', userTeam?.id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (!userTeam?.id) return [];
|
if (!userTeam?.id) return [];
|
||||||
const allInvites = await base44.entities.TeamMemberInvite.list('-invited_date');
|
const allInvites = await krowSDK.entities.TeamMemberInvite.list('-invited_date');
|
||||||
return allInvites.filter(inv => inv.team_id === userTeam.id && inv.invite_status === 'pending');
|
return allInvites.filter(inv => inv.team_id === userTeam.id && inv.invite_status === 'pending');
|
||||||
},
|
},
|
||||||
enabled: !!userTeam?.id,
|
enabled: !!userTeam?.id,
|
||||||
@@ -211,7 +219,7 @@ export default function Teams() {
|
|||||||
|
|
||||||
const { data: allStaff = [] } = useQuery({
|
const { data: allStaff = [] } = useQuery({
|
||||||
queryKey: ['staff-for-favorites'],
|
queryKey: ['staff-for-favorites'],
|
||||||
queryFn: () => base44.entities.Staff.list(),
|
queryFn: () => krowSDK.entities.Staff.list(),
|
||||||
enabled: !!userTeam?.id,
|
enabled: !!userTeam?.id,
|
||||||
initialData: [],
|
initialData: [],
|
||||||
});
|
});
|
||||||
@@ -220,7 +228,7 @@ export default function Teams() {
|
|||||||
queryKey: ['team-hubs-main', userTeam?.id],
|
queryKey: ['team-hubs-main', userTeam?.id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (!userTeam?.id) return [];
|
if (!userTeam?.id) return [];
|
||||||
const allHubs = await base44.entities.TeamHub.list('-created_date');
|
const allHubs = await krowSDK.entities.TeamHub.list('-created_date');
|
||||||
return allHubs.filter(h => h.team_id === userTeam.id);
|
return allHubs.filter(h => h.team_id === userTeam.id);
|
||||||
},
|
},
|
||||||
enabled: !!userTeam?.id,
|
enabled: !!userTeam?.id,
|
||||||
@@ -251,7 +259,7 @@ export default function Teams() {
|
|||||||
const firstHub = teamHubs.length > 0 ? teamHubs[0].hub_name : "";
|
const firstHub = teamHubs.length > 0 ? teamHubs[0].hub_name : "";
|
||||||
const firstDept = uniqueDepartments.length > 0 ? uniqueDepartments[0] : "Operations";
|
const firstDept = uniqueDepartments.length > 0 ? uniqueDepartments[0] : "Operations";
|
||||||
|
|
||||||
const invite = await base44.entities.TeamMemberInvite.create({
|
const invite = await krowSDK.entities.TeamMemberInvite.create({
|
||||||
team_id: userTeam.id,
|
team_id: userTeam.id,
|
||||||
team_name: userTeam.team_name || "Team",
|
team_name: userTeam.team_name || "Team",
|
||||||
invite_code: inviteCode,
|
invite_code: inviteCode,
|
||||||
@@ -295,7 +303,7 @@ export default function Teams() {
|
|||||||
|
|
||||||
if (data.hub && !existingHub) {
|
if (data.hub && !existingHub) {
|
||||||
// Create new hub with department
|
// Create new hub with department
|
||||||
await base44.entities.TeamHub.create({
|
await krowSDK.entities.TeamHub.create({
|
||||||
team_id: userTeam.id,
|
team_id: userTeam.id,
|
||||||
hub_name: data.hub,
|
hub_name: data.hub,
|
||||||
address: "",
|
address: "",
|
||||||
@@ -309,7 +317,7 @@ export default function Teams() {
|
|||||||
const departmentExists = hubDepartments.some(d => d.department_name === data.department);
|
const departmentExists = hubDepartments.some(d => d.department_name === data.department);
|
||||||
|
|
||||||
if (!departmentExists) {
|
if (!departmentExists) {
|
||||||
await base44.entities.TeamHub.update(existingHub.id, {
|
await krowSDK.entities.TeamHub.update(existingHub.id, {
|
||||||
departments: [...hubDepartments, { department_name: data.department, cost_center: "" }]
|
departments: [...hubDepartments, { department_name: data.department, cost_center: "" }]
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries({ queryKey: ['team-hubs-main', userTeam?.id] });
|
queryClient.invalidateQueries({ queryKey: ['team-hubs-main', userTeam?.id] });
|
||||||
@@ -318,7 +326,7 @@ export default function Teams() {
|
|||||||
|
|
||||||
const inviteCode = `TEAM-${Math.floor(10000 + Math.random() * 90000)}`;
|
const inviteCode = `TEAM-${Math.floor(10000 + Math.random() * 90000)}`;
|
||||||
|
|
||||||
const invite = await base44.entities.TeamMemberInvite.create({
|
const invite = await krowSDK.entities.TeamMemberInvite.create({
|
||||||
team_id: userTeam.id,
|
team_id: userTeam.id,
|
||||||
team_name: userTeam.team_name || "Team",
|
team_name: userTeam.team_name || "Team",
|
||||||
invite_code: inviteCode,
|
invite_code: inviteCode,
|
||||||
@@ -335,7 +343,7 @@ export default function Teams() {
|
|||||||
|
|
||||||
const registerUrl = `${window.location.origin}${createPageUrl('Onboarding')}?invite=${inviteCode}`;
|
const registerUrl = `${window.location.origin}${createPageUrl('Onboarding')}?invite=${inviteCode}`;
|
||||||
|
|
||||||
await base44.integrations.Core.SendEmail({
|
await krowSDK.integrations.Core.SendEmail({
|
||||||
from_name: userTeam.team_name || "KROW",
|
from_name: userTeam.team_name || "KROW",
|
||||||
to: data.email,
|
to: data.email,
|
||||||
subject: `🚀 Welcome to KROW! You've been invited to ${data.hub || userTeam.team_name}`,
|
subject: `🚀 Welcome to KROW! You've been invited to ${data.hub || userTeam.team_name}`,
|
||||||
@@ -439,7 +447,7 @@ export default function Teams() {
|
|||||||
mutationFn: async (invite) => {
|
mutationFn: async (invite) => {
|
||||||
const registerUrl = `${window.location.origin}${createPageUrl('Onboarding')}?invite=${invite.invite_code}`;
|
const registerUrl = `${window.location.origin}${createPageUrl('Onboarding')}?invite=${invite.invite_code}`;
|
||||||
|
|
||||||
await base44.integrations.Core.SendEmail({
|
await krowSDK.integrations.Core.SendEmail({
|
||||||
from_name: userTeam.team_name || "Team",
|
from_name: userTeam.team_name || "Team",
|
||||||
to: invite.email,
|
to: invite.email,
|
||||||
subject: `Reminder: You're invited to join ${userTeam.team_name || 'our team'}!`,
|
subject: `Reminder: You're invited to join ${userTeam.team_name || 'our team'}!`,
|
||||||
@@ -501,7 +509,7 @@ export default function Teams() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const updateMemberMutation = useMutation({
|
const updateMemberMutation = useMutation({
|
||||||
mutationFn: ({ id, data }) => base44.entities.TeamMember.update(id, data),
|
mutationFn: ({ id, data }) => krowSDK.entities.TeamMember.update(id, data),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['team-members', userTeam?.id] });
|
queryClient.invalidateQueries({ queryKey: ['team-members', userTeam?.id] });
|
||||||
setShowEditMemberDialog(false);
|
setShowEditMemberDialog(false);
|
||||||
@@ -514,7 +522,7 @@ export default function Teams() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const deactivateMemberMutation = useMutation({
|
const deactivateMemberMutation = useMutation({
|
||||||
mutationFn: ({ id }) => base44.entities.TeamMember.update(id, { is_active: false }),
|
mutationFn: ({ id }) => krowSDK.entities.TeamMember.update(id, { is_active: false }),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['team-members', userTeam?.id] });
|
queryClient.invalidateQueries({ queryKey: ['team-members', userTeam?.id] });
|
||||||
toast({
|
toast({
|
||||||
@@ -525,7 +533,7 @@ export default function Teams() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const activateMemberMutation = useMutation({
|
const activateMemberMutation = useMutation({
|
||||||
mutationFn: ({ id }) => base44.entities.TeamMember.update(id, { is_active: true }),
|
mutationFn: ({ id }) => krowSDK.entities.TeamMember.update(id, { is_active: true }),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['team-members', userTeam?.id] });
|
queryClient.invalidateQueries({ queryKey: ['team-members', userTeam?.id] });
|
||||||
toast({
|
toast({
|
||||||
@@ -607,7 +615,7 @@ export default function Teams() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the team with new departments list
|
// Update the team with new departments list
|
||||||
await base44.entities.Team.update(userTeam.id, {
|
await krowSDK.entities.Team.update(userTeam.id, {
|
||||||
departments: updatedDepartments
|
departments: updatedDepartments
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -638,7 +646,7 @@ export default function Teams() {
|
|||||||
const currentDepartments = userTeam.departments || [];
|
const currentDepartments = userTeam.departments || [];
|
||||||
const updatedDepartments = currentDepartments.filter(dept => dept !== deptToDelete);
|
const updatedDepartments = currentDepartments.filter(dept => dept !== deptToDelete);
|
||||||
|
|
||||||
await base44.entities.Team.update(userTeam.id, {
|
await krowSDK.entities.Team.update(userTeam.id, {
|
||||||
departments: updatedDepartments
|
departments: updatedDepartments
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -658,7 +666,7 @@ export default function Teams() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateTeamMutation = useMutation({
|
const updateTeamMutation = useMutation({
|
||||||
mutationFn: ({ id, data }) => base44.entities.Team.update(id, data),
|
mutationFn: ({ id, data }) => krowSDK.entities.Team.update(id, data),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['user-team', user?.id, userRole] });
|
queryClient.invalidateQueries({ queryKey: ['user-team', user?.id, userRole] });
|
||||||
toast({
|
toast({
|
||||||
@@ -761,7 +769,7 @@ export default function Teams() {
|
|||||||
}, [isGoogleMapsLoaded, showAddHubDialog]);
|
}, [isGoogleMapsLoaded, showAddHubDialog]);
|
||||||
|
|
||||||
const createHubMutation = useMutation({
|
const createHubMutation = useMutation({
|
||||||
mutationFn: (hubData) => base44.entities.TeamHub.create({
|
mutationFn: (hubData) => krowSDK.entities.TeamHub.create({
|
||||||
...hubData,
|
...hubData,
|
||||||
team_id: userTeam.id,
|
team_id: userTeam.id,
|
||||||
is_active: true
|
is_active: true
|
||||||
@@ -2370,14 +2378,14 @@ export default function Teams() {
|
|||||||
size="lg"
|
size="lg"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const updatedDepartments = [...(selectedHubForDept.departments || []), newHubDepartment];
|
const updatedDepartments = [...(selectedHubForDept.departments || []), newHubDepartment];
|
||||||
await base44.entities.TeamHub.update(selectedHubForDept.id, {
|
await krowSDK.entities.TeamHub.update(selectedHubForDept.id, {
|
||||||
departments: updatedDepartments
|
departments: updatedDepartments
|
||||||
});
|
});
|
||||||
|
|
||||||
// Also add department to team's global department list
|
// Also add department to team's global department list
|
||||||
const teamDepartments = userTeam?.departments || [];
|
const teamDepartments = userTeam?.departments || [];
|
||||||
if (!teamDepartments.includes(newHubDepartment.department_name)) {
|
if (!teamDepartments.includes(newHubDepartment.department_name)) {
|
||||||
await base44.entities.Team.update(userTeam.id, {
|
await krowSDK.entities.Team.update(userTeam.id, {
|
||||||
departments: [...teamDepartments, newHubDepartment.department_name]
|
departments: [...teamDepartments, newHubDepartment.department_name]
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries({ queryKey: ['user-team', user?.id, userRole] });
|
queryClient.invalidateQueries({ queryKey: ['user-team', user?.id, userRole] });
|
||||||
|
|||||||
Reference in New Issue
Block a user