diff --git a/apps/client-ts/src/app/(Dashboard)/api-keys/page.tsx b/apps/client-ts/src/app/(Dashboard)/api-keys/page.tsx index 0e35dbe7d..12fd14c88 100644 --- a/apps/client-ts/src/app/(Dashboard)/api-keys/page.tsx +++ b/apps/client-ts/src/app/(Dashboard)/api-keys/page.tsx @@ -36,7 +36,7 @@ import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { DataTableLoading } from "@/components/shared/data-table-loading"; import { Heading } from "@/components/ui/heading"; - +import Cookies from 'js-cookie'; const formSchema = z.object({ apiKeyIdentifier: z.string().min(2, { @@ -54,11 +54,13 @@ export default function Page() { const [open,setOpen] = useState(false) const [tsApiKeys,setTSApiKeys] = useState([]) - const { data: apiKeys, isLoading, error } = useApiKeys(); + const {idProject} = useProjectStore(); + const {profile} = useProfileStore(); + + const { data: apiKeys, isLoading, error } = useApiKeys(idProject); const { mutate } = useApiKeyMutation(); useEffect(() => { - const temp_tsApiKeys = apiKeys?.map((key) => ({ name: key.name || "", token: key.api_key_hash, @@ -69,8 +71,7 @@ export default function Page() { },[apiKeys]) - const {idProject} = useProjectStore(); - const {profile} = useProfileStore(); + const posthog = usePostHog() diff --git a/apps/client-ts/src/app/(Dashboard)/configuration/page.tsx b/apps/client-ts/src/app/(Dashboard)/configuration/page.tsx index af682001c..77afcc08d 100644 --- a/apps/client-ts/src/app/(Dashboard)/configuration/page.tsx +++ b/apps/client-ts/src/app/(Dashboard)/configuration/page.tsx @@ -46,8 +46,8 @@ import { Heading } from "@/components/ui/heading"; export default function Page() { const {idProject} = useProjectStore(); - const { data: linkedUsers, isLoading, error } = useLinkedUsers(); - const { data: webhooks, isLoading: isWebhooksLoading, error: isWebhooksError } = useWebhooks(); + const { data: linkedUsers, isLoading, error } = useLinkedUsers(idProject); + const { data: webhooks, isLoading: isWebhooksLoading, error: isWebhooksError } = useWebhooks(idProject); const {data: ConnectionStrategies, isLoading: isConnectionStrategiesLoading,error: isConnectionStategiesError} = useConnectionStrategies(idProject) const { data: mappings, isLoading: isFieldMappingsLoading, error: isFieldMappingsError } = useFieldMappings(); diff --git a/apps/client-ts/src/app/b2c/login/page.tsx b/apps/client-ts/src/app/b2c/login/page.tsx index 34f943715..fe12e7715 100644 --- a/apps/client-ts/src/app/b2c/login/page.tsx +++ b/apps/client-ts/src/app/b2c/login/page.tsx @@ -1,17 +1,6 @@ 'use client'; import CreateUserForm from "@/components/Auth/CustomLoginComponent/CreateUserForm"; import LoginUserForm from "@/components/Auth/CustomLoginComponent/LoginUserForm"; -import { Button } from "@/components/ui/button" -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "@/components/ui/card" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" import { Tabs, TabsContent, @@ -24,8 +13,6 @@ import Cookies from 'js-cookie'; import useProfileStore from "@/state/profileStore"; import useFetchUserMutation from "@/hooks/mutations/useFetchUserMutation"; - - export default function Page() { const [userInitialized,setUserInitialized] = useState(true) diff --git a/apps/client-ts/src/components/Configuration/AddAuthCredentials.tsx b/apps/client-ts/src/components/Configuration/AddAuthCredentials.tsx index e9da1879a..de02cc4ab 100644 --- a/apps/client-ts/src/components/Configuration/AddAuthCredentials.tsx +++ b/apps/client-ts/src/components/Configuration/AddAuthCredentials.tsx @@ -15,28 +15,19 @@ import { cn } from "@/lib/utils" import { usePostHog } from 'posthog-js/react' import config from "@/lib/config" -// import { toast } from "@/components/ui/use-toast" import AddAuthCredentialsForm from "./AddAuthCredentialsForm" - - - const AddAuthCredentials = () => { - const [open, setOpen] = useState(false); - const posthog = usePostHog() - const {idProject} = useProjectStore(); - - - + const [open, setOpen] = useState(false); + const posthog = usePostHog() + const {idProject} = useProjectStore(); - const handleOpenChange = (open: boolean) => { - setOpen(open) - // form.reset() - }; + const handleOpenChange = (open: boolean) => { + setOpen(open) + // form.reset() + }; - - return ( diff --git a/apps/client-ts/src/components/Configuration/AddAuthCredentialsForm.tsx b/apps/client-ts/src/components/Configuration/AddAuthCredentialsForm.tsx index 30f2c2406..abaa26d4c 100644 --- a/apps/client-ts/src/components/Configuration/AddAuthCredentialsForm.tsx +++ b/apps/client-ts/src/components/Configuration/AddAuthCredentialsForm.tsx @@ -35,20 +35,13 @@ import { import { Form, FormControl, - FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, - } from "@/components/ui/tooltip" import {PasswordInput} from '@/components/ui/password-input' -import { ALL_PROVIDERS,getLogoURL,getProviderVertical,providerToType,AuthStrategy } from "@panora/shared" +import { ALL_PROVIDERS,getLogoURL,providerToType,AuthStrategy } from "@panora/shared" import * as z from "zod" import { cn } from "@/lib/utils" import useProjectStore from "@/state/projectStore" @@ -103,17 +96,13 @@ const formSchema = z.object({ // api_key?:string, // username?:string, // secret?:string, - - } } const AddAuthCredentialsForm = (prop : propType) => { - const [copied, setCopied] = useState(false); const [popoverOpen,setPopOverOpen] = useState(false); - // const [olddata,setOldData] = useState(prop.data) const {idProject} = useProjectStore() const {mutate : createCS} = useConnectionStrategyMutation(); const {mutate :updateCS} = useUpdateConnectionStrategyMutation() @@ -134,8 +123,6 @@ const AddAuthCredentialsForm = (prop : propType) => { }) - - const posthog = usePostHog() useEffect(() => { @@ -181,10 +168,6 @@ const AddAuthCredentialsForm = (prop : propType) => { },[]) - - - - const handlePopOverClose = () => { setPopOverOpen(false); } @@ -203,8 +186,6 @@ const AddAuthCredentialsForm = (prop : propType) => { const Watch = form.watch() - - function onSubmit(values: z.infer) { diff --git a/apps/client-ts/src/components/Configuration/AddWebhook.tsx b/apps/client-ts/src/components/Configuration/AddWebhook.tsx index aad79b60b..b58c9d962 100644 --- a/apps/client-ts/src/components/Configuration/AddWebhook.tsx +++ b/apps/client-ts/src/components/Configuration/AddWebhook.tsx @@ -59,7 +59,6 @@ const AddWebhook = () => { const handleClose = () => { setOpen(false); }; - //const [secret, setSecret] = useState(''); const posthog = usePostHog() const {idProject} = useProjectStore(); diff --git a/apps/client-ts/src/components/Configuration/FieldMappingModal.tsx b/apps/client-ts/src/components/Configuration/FieldMappingModal.tsx index a13c0090b..59b1fbeec 100644 --- a/apps/client-ts/src/components/Configuration/FieldMappingModal.tsx +++ b/apps/client-ts/src/components/Configuration/FieldMappingModal.tsx @@ -109,7 +109,7 @@ export function FModal({ onClose }: {onClose: () => void}) { const { data: mappings } = useFieldMappings(); const { mutate: mutateDefineField } = useDefineFieldMutation(); const { mutate: mutateMapField } = useMapFieldMutation(); - const { data: linkedUsers } = useLinkedUsers(); + const { data: linkedUsers } = useLinkedUsers(idProject); const { data: sourceCustomFields, error, isLoading } = useProviderProperties(linkedUserId,sourceProvider); const posthog = usePostHog() diff --git a/apps/client-ts/src/components/Connection/ConnectionTable.tsx b/apps/client-ts/src/components/Connection/ConnectionTable.tsx index 9cd911554..bd75c50ec 100644 --- a/apps/client-ts/src/components/Connection/ConnectionTable.tsx +++ b/apps/client-ts/src/components/Connection/ConnectionTable.tsx @@ -21,16 +21,18 @@ import useMagicLinkStore from "@/state/magicLinkStore"; import useOrganisationStore from "@/state/organisationStore"; import { usePostHog } from 'posthog-js/react' import useProjectStore from "@/state/projectStore"; +import Cookies from 'js-cookie'; export default function ConnectionTable() { - const { data: connections, isLoading, error } = useConnections(); + + const {idProject} = useProjectStore(); + const { data: connections, isLoading, error } = useConnections(idProject); const [isGenerated, setIsGenerated] = useState(false); const posthog = usePostHog() const {uniqueLink} = useMagicLinkStore(); const {nameOrg} = useOrganisationStore(); - const {idProject} = useProjectStore(); if(isLoading){ return ( diff --git a/apps/client-ts/src/components/Events/EventsTable.tsx b/apps/client-ts/src/components/Events/EventsTable.tsx index ce6186719..5fc3285ff 100644 --- a/apps/client-ts/src/components/Events/EventsTable.tsx +++ b/apps/client-ts/src/components/Events/EventsTable.tsx @@ -5,11 +5,13 @@ import { DataTableLoading } from "../shared/data-table-loading"; import { events as Event } from "api"; import { useEventsCount } from '@/hooks/useEventsCount'; import { useQueryPagination } from '@/hooks/useQueryPagination'; +import useProjectStore from "@/state/projectStore"; export default function EventsTable() { const { data: eventsCount } = useEventsCount(); const pagination = useQueryPagination({ totalItems: eventsCount }); + const {idProject} = useProjectStore(); const { data: events, @@ -19,7 +21,7 @@ export default function EventsTable() { } = useEvents({ page: pagination.page, pageSize: pagination.pageSize, - }); + }, idProject); //TODO const transformedEvents = events?.map((event: Event) => ({ diff --git a/apps/client-ts/src/components/Nav/user-nav.tsx b/apps/client-ts/src/components/Nav/user-nav.tsx index bbe7b3bdf..996d0a269 100644 --- a/apps/client-ts/src/components/Nav/user-nav.tsx +++ b/apps/client-ts/src/components/Nav/user-nav.tsx @@ -13,41 +13,20 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" -import { Skeleton } from "@/components/ui/skeleton"; -import useProfile from "@/hooks/useProfile"; import useProfileStore from "@/state/profileStore"; import { useRouter } from "next/navigation"; import Link from "next/link"; -import { useEffect } from "react"; import Cookies from 'js-cookie'; import useProjectStore from "@/state/projectStore" import { useQueryClient } from '@tanstack/react-query'; export function UserNav() { - // const stytch = useStytch(); - // const { user } = useStytchUser(); const router = useRouter(); - //const {data, isLoading, isError, error} = useProfile(user?.user_id!); const { profile, setProfile } = useProfileStore(); const { idProject, setIdProject } = useProjectStore(); const queryClient = useQueryClient(); - - - /*useEffect(()=> { - if(data){ - console.log("data is "+ JSON.stringify(data)); - setProfile({ - id_user: data.id_user, - email: data.email!, - first_name: data.first_name, - last_name: data.last_name, - //id_organization: data.id_organization as string, - }) - } - }, [data, setProfile]);*/ - const onLogout = () => { router.push('/b2c/login') Cookies.remove("access_token") diff --git a/apps/client-ts/src/components/RootLayout/index.tsx b/apps/client-ts/src/components/RootLayout/index.tsx index b09507c53..f2c254d34 100644 --- a/apps/client-ts/src/components/RootLayout/index.tsx +++ b/apps/client-ts/src/components/RootLayout/index.tsx @@ -1,6 +1,6 @@ 'use client' -import { useState, useEffect } from 'react'; +import { useEffect } from 'react'; import { MainNav } from '@/components/Nav/main-nav'; import { SmallNav } from '@/components/Nav/main-nav-sm'; import { UserNav } from '@/components/Nav/user-nav'; @@ -11,18 +11,7 @@ import { cn } from "@/lib/utils"; import useProfileStore from '@/state/profileStore'; import useProjectStore from '@/state/projectStore'; import { ThemeToggle } from '@/components/Nav/theme-toggle'; -import { projects as Project } from 'api'; -import useFetchUserMutation from "@/hooks/mutations/useFetchUserMutation"; -import useProjectsByUser from '@/hooks/useProjectsByUser'; - - -type User = { - id_user: string; - email: string; - first_name: string; - last_name: string; - id_organization?: string; -} +import useProjects from '@/hooks/useProjects'; export const RootLayout = ({children}:{children:React.ReactNode}) => { const router = useRouter() @@ -30,7 +19,7 @@ export const RootLayout = ({children}:{children:React.ReactNode}) => { const {profile} = useProfileStore() - const {data : projectsData} = useProjectsByUser(profile?.id_user) + const {data : projectsData} = useProjects(); const { idProject, setIdProject } = useProjectStore(); diff --git a/apps/client-ts/src/hooks/mutations/useApiKeyMutation.tsx b/apps/client-ts/src/hooks/mutations/useApiKeyMutation.tsx index 85d52e345..2254fa036 100644 --- a/apps/client-ts/src/hooks/mutations/useApiKeyMutation.tsx +++ b/apps/client-ts/src/hooks/mutations/useApiKeyMutation.tsx @@ -12,21 +12,6 @@ const useApiKeyMutation = () => { const queryClient = useQueryClient(); const addApiKey = async (data: IApiKeyDto) => { - //TODO: in cloud environment this step must be done when user logs in directly inside his dashboard - // Fetch the token - // const loginResponse = await fetch(`${config.API_URL}/auth/login`, { - // method: 'POST', - // body: JSON.stringify({ id_user: data.userId.trim(), password_hash: 'my_password' }), - // headers: { - // 'Content-Type': 'application/json', - // }, - // }); - - // if (!loginResponse.ok) { - // throw new Error('Failed to login'); - // } - // const { access_token } = await loginResponse.json(); - const response = await fetch(`${config.API_URL}/auth/generate-apikey`, { method: 'POST', body: JSON.stringify(data), @@ -35,7 +20,7 @@ const useApiKeyMutation = () => { 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); - + if (!response.ok) { throw new Error('Failed to add api key'); } diff --git a/apps/client-ts/src/hooks/mutations/useConnectionStrategy.tsx b/apps/client-ts/src/hooks/mutations/useConnectionStrategy.tsx index e8f485c49..c8795d783 100644 --- a/apps/client-ts/src/hooks/mutations/useConnectionStrategy.tsx +++ b/apps/client-ts/src/hooks/mutations/useConnectionStrategy.tsx @@ -1,6 +1,7 @@ import config from '@/lib/config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; interface IConnectionStrategyDto { projectId: string, @@ -27,6 +28,7 @@ const useConnectionStrategyMutation = () => { body: JSON.stringify(connectionStrategyData), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useConnectionStrategyAuthCredentials.tsx b/apps/client-ts/src/hooks/mutations/useConnectionStrategyAuthCredentials.tsx index f2fbec772..304a41c83 100644 --- a/apps/client-ts/src/hooks/mutations/useConnectionStrategyAuthCredentials.tsx +++ b/apps/client-ts/src/hooks/mutations/useConnectionStrategyAuthCredentials.tsx @@ -1,6 +1,7 @@ import config from '@/lib/config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; interface IFetchedData { authValues:string[] @@ -22,6 +23,7 @@ const useConnectionStrategyAuthCredentialsMutation = () => { body: JSON.stringify(GetCSCredentialsData), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }) if (!response.ok) { diff --git a/apps/client-ts/src/hooks/mutations/useDefineFieldMutation.tsx b/apps/client-ts/src/hooks/mutations/useDefineFieldMutation.tsx index 3d355da33..a813acf02 100644 --- a/apps/client-ts/src/hooks/mutations/useDefineFieldMutation.tsx +++ b/apps/client-ts/src/hooks/mutations/useDefineFieldMutation.tsx @@ -1,6 +1,7 @@ import config from '@/lib/config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; interface IDefineTargetFieldDto{ object_type_owner: string; @@ -18,6 +19,7 @@ const useDefineFieldMutation = () => { body: JSON.stringify(data), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useDeleteConnectionStrategy.tsx b/apps/client-ts/src/hooks/mutations/useDeleteConnectionStrategy.tsx index c67f21211..8e6d91c8e 100644 --- a/apps/client-ts/src/hooks/mutations/useDeleteConnectionStrategy.tsx +++ b/apps/client-ts/src/hooks/mutations/useDeleteConnectionStrategy.tsx @@ -2,6 +2,7 @@ import config from '@/lib/config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from "sonner" import { connection_strategies as ConnectionStrategies } from 'api'; +import Cookies from 'js-cookie'; interface IDeleteConnectionStrategyDto { id_cs: string @@ -21,6 +22,7 @@ const useDeleteConnectionStrategyMutation = () => { body: JSON.stringify({id:connectionStrategyData.id_cs}), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useMagicLinkMutation.tsx b/apps/client-ts/src/hooks/mutations/useMagicLinkMutation.tsx index e08cd5593..f894cd22f 100644 --- a/apps/client-ts/src/hooks/mutations/useMagicLinkMutation.tsx +++ b/apps/client-ts/src/hooks/mutations/useMagicLinkMutation.tsx @@ -2,6 +2,7 @@ import useMagicLinkStore from '@/state/magicLinkStore'; import config from '@/lib/config'; import { useMutation } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; interface ILinkDto { email: string; @@ -17,6 +18,7 @@ const useMagicLinkMutation = () => { body: JSON.stringify(data), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useMapFieldMutation.tsx b/apps/client-ts/src/hooks/mutations/useMapFieldMutation.tsx index 13dd29b8d..0fb996f11 100644 --- a/apps/client-ts/src/hooks/mutations/useMapFieldMutation.tsx +++ b/apps/client-ts/src/hooks/mutations/useMapFieldMutation.tsx @@ -1,6 +1,8 @@ import config from '@/lib/config'; import { useMutation } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; + interface IMapTargetFieldDto { attributeId: string; source_custom_field_id: string; @@ -15,6 +17,7 @@ const useMapFieldMutation = () => { body: JSON.stringify(data), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useProjectMutation.tsx b/apps/client-ts/src/hooks/mutations/useProjectMutation.tsx index 42c01a4bc..556e0c628 100644 --- a/apps/client-ts/src/hooks/mutations/useProjectMutation.tsx +++ b/apps/client-ts/src/hooks/mutations/useProjectMutation.tsx @@ -1,6 +1,7 @@ import config from '@/lib/config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; interface IProDto { name: string; @@ -16,6 +17,7 @@ const useProjectMutation = () => { body: JSON.stringify(data), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useUpdateConnectionStrategy.tsx b/apps/client-ts/src/hooks/mutations/useUpdateConnectionStrategy.tsx index 7749b2861..569243b78 100644 --- a/apps/client-ts/src/hooks/mutations/useUpdateConnectionStrategy.tsx +++ b/apps/client-ts/src/hooks/mutations/useUpdateConnectionStrategy.tsx @@ -2,6 +2,7 @@ import config from '@/lib/config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from "sonner" import { connection_strategies as ConnectionStrategies } from 'api'; +import Cookies from 'js-cookie'; interface IUpdateConnectionStrategyDto { id_cs?: string @@ -27,6 +28,7 @@ const useUpdateConnectionStrategyMutation = () => { body: JSON.stringify({id_cs:connectionStrategyData.id_cs}), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useWebhookMutation.tsx b/apps/client-ts/src/hooks/mutations/useWebhookMutation.tsx index bf6b9744c..f90b9461b 100644 --- a/apps/client-ts/src/hooks/mutations/useWebhookMutation.tsx +++ b/apps/client-ts/src/hooks/mutations/useWebhookMutation.tsx @@ -1,6 +1,7 @@ import config from '@/lib/config'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; interface IWebhookDto { url: string; @@ -16,6 +17,7 @@ const useWebhookMutation = () => { body: JSON.stringify(data), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/mutations/useWebhookUpdate.tsx b/apps/client-ts/src/hooks/mutations/useWebhookUpdate.tsx index 19eb3520e..df3d9eaa6 100644 --- a/apps/client-ts/src/hooks/mutations/useWebhookUpdate.tsx +++ b/apps/client-ts/src/hooks/mutations/useWebhookUpdate.tsx @@ -1,6 +1,7 @@ import config from '@/lib/config'; import { useMutation } from '@tanstack/react-query'; import { toast } from "sonner" +import Cookies from 'js-cookie'; interface IWebhookUpdateDto { id: string; @@ -13,6 +14,7 @@ const useWebhookStatusMutation = () => { body: JSON.stringify({active: data.active}), headers: { 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, }, }); diff --git a/apps/client-ts/src/hooks/useApiKeys.tsx b/apps/client-ts/src/hooks/useApiKeys.tsx index 1250d127b..e814d2ef2 100644 --- a/apps/client-ts/src/hooks/useApiKeys.tsx +++ b/apps/client-ts/src/hooks/useApiKeys.tsx @@ -1,16 +1,24 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { api_keys as ApiKey } from 'api'; +import Cookies from 'js-cookie'; -const useApiKeys = () => { +const useApiKeys = (project_id: string) => { return useQuery({ queryKey: ['api-keys'], queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/auth/api-keys`); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); + const response = await fetch(`${config.API_URL}/auth/api-keys?project_id=${project_id}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); } }); }; diff --git a/apps/client-ts/src/hooks/useApiRequests.tsx b/apps/client-ts/src/hooks/useApiRequests.tsx deleted file mode 100644 index d9bd6022a..000000000 --- a/apps/client-ts/src/hooks/useApiRequests.tsx +++ /dev/null @@ -1 +0,0 @@ -//import { useQuery } from '@tanstack/react-query'; diff --git a/apps/client-ts/src/hooks/useConnectionStrategies.tsx b/apps/client-ts/src/hooks/useConnectionStrategies.tsx index f524f46ba..3adfc0899 100644 --- a/apps/client-ts/src/hooks/useConnectionStrategies.tsx +++ b/apps/client-ts/src/hooks/useConnectionStrategies.tsx @@ -1,12 +1,20 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { connection_strategies as ConnectionStrategies } from 'api'; +import Cookies from 'js-cookie'; const useConnectionStrategies = (projectId : string) => { return useQuery({ queryKey: ['connection-strategies'], queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/connections-strategies/GetConnectionStrategiesForProject?projectId=${projectId}`); + const response = await fetch(`${config.API_URL}/connections-strategies/getConnectionStrategiesForProject?projectId=${projectId}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/apps/client-ts/src/hooks/useConnections.tsx b/apps/client-ts/src/hooks/useConnections.tsx index 58e5fa632..15e6f607a 100644 --- a/apps/client-ts/src/hooks/useConnections.tsx +++ b/apps/client-ts/src/hooks/useConnections.tsx @@ -1,17 +1,24 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { connections as Connection } from 'api'; +import Cookies from 'js-cookie'; -const useConnections = () => { +const useConnections = (project_id: string) => { return useQuery({ queryKey: ['connections'], queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/connections`); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); + const response = await fetch(`${config.API_URL}/connections?project_id=${project_id}`,{ + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); } }); }; diff --git a/apps/client-ts/src/hooks/useEvents.tsx b/apps/client-ts/src/hooks/useEvents.tsx index 5bed0b829..84f02c130 100644 --- a/apps/client-ts/src/hooks/useEvents.tsx +++ b/apps/client-ts/src/hooks/useEvents.tsx @@ -2,14 +2,22 @@ import { PaginationParams } from '@/lib/types'; import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { events as Event } from 'api'; +import Cookies from 'js-cookie'; -const fetchEvents = async (params: PaginationParams): Promise => { +const fetchEvents = async (params: PaginationParams, project_id: string): Promise => { const searchParams = new URLSearchParams({ page: params.page.toString(), pageSize: params.pageSize.toString(), }); - const response = await fetch(`${config.API_URL}/events?${searchParams.toString()}`); + const response = await fetch(`${config.API_URL}/events?project_id=${project_id}&${searchParams.toString()}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); @@ -17,10 +25,10 @@ const fetchEvents = async (params: PaginationParams): Promise => { return response.json(); }; -const useEvents = (params: PaginationParams) => { +const useEvents = (params: PaginationParams, project_id: string) => { return useQuery({ queryKey: ['events', { page: params.page, pageSize: params.pageSize }], - queryFn: () => fetchEvents(params), + queryFn: () => fetchEvents(params, project_id), }); }; diff --git a/apps/client-ts/src/hooks/useFieldMapping.tsx b/apps/client-ts/src/hooks/useFieldMapping.tsx deleted file mode 100644 index e5e230f1a..000000000 --- a/apps/client-ts/src/hooks/useFieldMapping.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; -import config from '@/lib/config'; -import { attribute as Attribute } from 'api'; - -export const useFieldMapping = (id: string) => { - return useQuery({ - queryKey: ['mapping', id], - queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/field-mapping/attribute/${id}`); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return await response.json(); - }, - enabled: !!id, // This query will not run until an 'id' is provided - }); -}; diff --git a/apps/client-ts/src/hooks/useFieldMappings.tsx b/apps/client-ts/src/hooks/useFieldMappings.tsx index fe751c797..794b47096 100644 --- a/apps/client-ts/src/hooks/useFieldMappings.tsx +++ b/apps/client-ts/src/hooks/useFieldMappings.tsx @@ -1,10 +1,18 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { attribute as Attribute } from 'api'; +import Cookies from 'js-cookie'; const useFieldMappings = () => { return useQuery({queryKey: ['mappings'], queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/field-mapping/attribute`); + const response = await fetch(`${config.API_URL}/field-mapping/attribute`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/apps/client-ts/src/hooks/useLinkedUsers.tsx b/apps/client-ts/src/hooks/useLinkedUsers.tsx index 6d1c6f1d7..54a062044 100644 --- a/apps/client-ts/src/hooks/useLinkedUsers.tsx +++ b/apps/client-ts/src/hooks/useLinkedUsers.tsx @@ -1,12 +1,20 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { linked_users as LinkedUser } from 'api'; +import Cookies from 'js-cookie'; -const useLinkedUsers = () => { +const useLinkedUsers = (project_id: string) => { return useQuery({ queryKey: ['linked-users'], queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/linked-users`); + const response = await fetch(`${config.API_URL}/linked-users?project_id=${project_id}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/apps/client-ts/src/hooks/useProfile.tsx b/apps/client-ts/src/hooks/useProfile.tsx deleted file mode 100644 index b1f0a67d0..000000000 --- a/apps/client-ts/src/hooks/useProfile.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import config from '@/lib/config'; -import { useQuery } from '@tanstack/react-query'; -import { users as User } from 'api'; -import { projects as Project } from 'api'; - -const useProfile = (stytchUserId: string) => { - return useQuery({ - queryKey: ['profile', stytchUserId], - queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/auth/users/${stytchUserId}`); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - } - }); -}; -export default useProfile; diff --git a/apps/client-ts/src/hooks/useProjects.tsx b/apps/client-ts/src/hooks/useProjects.tsx index fd7dfcf63..1d65335be 100644 --- a/apps/client-ts/src/hooks/useProjects.tsx +++ b/apps/client-ts/src/hooks/useProjects.tsx @@ -1,13 +1,21 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { projects as Project } from 'api'; +import Cookies from 'js-cookie'; const useProjects = () => { return useQuery({ queryKey: ['projects'], queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/projects`); + const response = await fetch(`${config.API_URL}/projects`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/apps/client-ts/src/hooks/useProjectsByUser.tsx b/apps/client-ts/src/hooks/useProjectsByUser.tsx deleted file mode 100644 index 24a2a5d93..000000000 --- a/apps/client-ts/src/hooks/useProjectsByUser.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import config from '@/lib/config'; -import { useQuery } from '@tanstack/react-query'; -import { projects as Project } from 'api'; - - -const useProjectsByUser = (userId: string | undefined) => { - return useQuery({ - queryKey: ['projects'], - enabled: userId!==undefined, - queryFn: async (): Promise => { - if(userId === "" || !userId){ - return []; - } - const response = await fetch(`${config.API_URL}/projects/${userId}`); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - } - }); -}; - -export default useProjectsByUser; diff --git a/apps/client-ts/src/hooks/useProviderProperties.tsx b/apps/client-ts/src/hooks/useProviderProperties.tsx index 8e5c3c63e..0661740fa 100644 --- a/apps/client-ts/src/hooks/useProviderProperties.tsx +++ b/apps/client-ts/src/hooks/useProviderProperties.tsx @@ -1,11 +1,19 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; - +import Cookies from 'js-cookie'; + const useProviderProperties = (linkedUserId: string, providerId: string) => { return useQuery({ queryKey: ['providerProperties', linkedUserId, providerId], queryFn: async () => { - const response = await fetch(`${config.API_URL}/field-mapping/properties?linkedUserId=${linkedUserId}&providerId=${providerId}`); + const response = await fetch(`${config.API_URL}/field-mapping/properties?linkedUserId=${linkedUserId}&providerId=${providerId}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/apps/client-ts/src/hooks/useStandardObjects.tsx b/apps/client-ts/src/hooks/useStandardObjects.tsx index 32f82699f..cb3f6c0a6 100644 --- a/apps/client-ts/src/hooks/useStandardObjects.tsx +++ b/apps/client-ts/src/hooks/useStandardObjects.tsx @@ -1,10 +1,18 @@ import { useQuery } from '@tanstack/react-query'; import config from '@/lib/config'; import { entity as Entity } from 'api'; +import Cookies from 'js-cookie'; export const useStandardObjects = () => { return useQuery({queryKey: ['standardObjects'], queryFn: async (): Promise => { - const response = await fetch(`${config.API_URL}/field-mapping/entities`); + const response = await fetch(`${config.API_URL}/field-mapping/entities`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/apps/client-ts/src/hooks/useWebhooks.tsx b/apps/client-ts/src/hooks/useWebhooks.tsx index 2cd9e26c6..636c7172f 100644 --- a/apps/client-ts/src/hooks/useWebhooks.tsx +++ b/apps/client-ts/src/hooks/useWebhooks.tsx @@ -1,13 +1,21 @@ import config from '@/lib/config'; import { useQuery } from '@tanstack/react-query'; import { webhook_endpoints as Webhook } from 'api'; +import Cookies from 'js-cookie'; -const useWebhooks = () => { +const useWebhooks = (project_id: string) => { return useQuery({ queryKey: ['webhooks'], queryFn: async (): Promise => { console.log("Webhook mutation called") - const response = await fetch(`${config.API_URL}/webhook`); + const response = await fetch(`${config.API_URL}/webhook?project_id=${project_id}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${Cookies.get('access_token')}`, + }, + }); if (!response.ok) { throw new Error('Network response was not ok'); } diff --git a/packages/api/src/@core/auth/auth.controller.ts b/packages/api/src/@core/auth/auth.controller.ts index 6a14ec74f..6f34af10f 100644 --- a/packages/api/src/@core/auth/auth.controller.ts +++ b/packages/api/src/@core/auth/auth.controller.ts @@ -4,12 +4,9 @@ import { Body, Get, UseGuards, - Query, - Res, Request, - Param, + Query, } from '@nestjs/common'; -import { Response } from 'express'; import { CreateUserDto } from './dto/create-user.dto'; import { AuthService } from './auth.service'; import { JwtAuthGuard } from './guards/jwt-auth.guard'; @@ -17,7 +14,7 @@ import { LoggerService } from '@@core/logger/logger.service'; import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ApiKeyDto } from './dto/api-key.dto'; import { LoginDto } from './dto/login.dto'; -import { ApiKeyAuthGuard } from './guards/api-key.guard'; +import { ValidateUserGuard } from '@@core/utils/guards/validate-user.guard'; @ApiTags('auth') @Controller('auth') @@ -53,6 +50,7 @@ export class AuthController { return this.authService.login(user); } + // todo: admin only @ApiOperation({ operationId: 'getUsers', summary: 'Get users' }) @ApiResponse({ status: 200 }) @Get('users') @@ -60,30 +58,6 @@ export class AuthController { return this.authService.getUsers(); } - // @ApiOperation({ - // operationId: 'getUser', - // summary: 'Get a specific user by ID', - // }) - // @ApiResponse({ status: 200, description: 'Returns the user data.' }) - // @ApiResponse({ status: 404, description: 'User not found.' }) - // @Get('users/:stytchId') - // async getUser(@Param('stytchId') stytchId: string) { - // return this.authService.getUserByStytchId(stytchId); - // } - - // @ApiOperation({ operationId: 'generateApiKey', summary: 'Create API Key' }) - // @ApiBody({ type: ApiKeyDto }) - // @ApiResponse({ status: 201 }) - // @UseGuards(JwtAuthGuard) - // @Get('users/currentUser') - // async getCurrentUser(@Body() data: ApiKeyDto): Promise<{ api_key: string }> { - // return this.authService.generateApiKeyForUser( - // data.userId, - // data.projectId, - // data.keyName, - // ); - // } - @ApiResponse({ status: 201 }) @UseGuards(JwtAuthGuard) @Get('profile') @@ -93,9 +67,14 @@ export class AuthController { @ApiOperation({ operationId: 'getApiKeys', summary: 'Retrieve API Keys' }) @ApiResponse({ status: 200 }) + @UseGuards(JwtAuthGuard, ValidateUserGuard) @Get('api-keys') - async apiKeys() { - return this.authService.getApiKeys(); + async getApiKeys( + @Request() req: any, + @Query('project_id') project_id: string, + ) { + const id_user = req.user.id_user; // Extracted from JWT payload + return this.authService.getApiKeys(id_user, project_id); } @ApiOperation({ operationId: 'generateApiKey', summary: 'Create API Key' }) diff --git a/packages/api/src/@core/auth/auth.module.ts b/packages/api/src/@core/auth/auth.module.ts index 9ef03c5ae..655b6ffbc 100644 --- a/packages/api/src/@core/auth/auth.module.ts +++ b/packages/api/src/@core/auth/auth.module.ts @@ -8,6 +8,7 @@ import { PrismaService } from '../prisma/prisma.service'; import { ConfigService } from '@nestjs/config'; import { LoggerService } from '@@core/logger/logger.service'; import { AuthController } from './auth.controller'; +import { ValidateUserService } from '@@core/utils/services/validateUser.service'; @Module({ controllers: [AuthController], @@ -19,6 +20,7 @@ import { AuthController } from './auth.controller'; PrismaService, ConfigService, LoggerService, + ValidateUserService, ], imports: [ PassportModule, diff --git a/packages/api/src/@core/auth/auth.service.ts b/packages/api/src/@core/auth/auth.service.ts index ac7d05491..30a89aa9e 100644 --- a/packages/api/src/@core/auth/auth.service.ts +++ b/packages/api/src/@core/auth/auth.service.ts @@ -60,9 +60,14 @@ export class AuthService { } } - async getApiKeys() { + async getApiKeys(user_id: string, project_id: string) { try { - return await this.prisma.api_keys.findMany(); + return await this.prisma.api_keys.findMany({ + where: { + id_user: user_id, + id_project: project_id, + }, + }); } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/@core/auth/guards/jwt-auth.guard.ts b/packages/api/src/@core/auth/guards/jwt-auth.guard.ts index 6844da61b..db027fc9e 100644 --- a/packages/api/src/@core/auth/guards/jwt-auth.guard.ts +++ b/packages/api/src/@core/auth/guards/jwt-auth.guard.ts @@ -1,22 +1,29 @@ import { - ExecutionContext, - Injectable, - UnauthorizedException, + ExecutionContext, + Injectable, + UnauthorizedException, } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { Observable } from 'rxjs'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { + canActivate( + context: ExecutionContext, + ): boolean | Promise | Observable { + return super.canActivate(context); + } - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return super.canActivate(context); + handleRequest( + err: any, + user: any, + _info: any, + _context: ExecutionContext, + _status?: any, + ): TUser { + if (err || !user) { + throw err || new UnauthorizedException(); } - - handleRequest(err: any, user: any, _info: any, _context: ExecutionContext, _status?: any): TUser { - if (err || !user) { - throw err || new UnauthorizedException(); - } - return user; - } -} \ No newline at end of file + return user; + } +} diff --git a/packages/api/src/@core/auth/strategies/jwt.strategy.ts b/packages/api/src/@core/auth/strategies/jwt.strategy.ts index 76b6abf75..c75ff6529 100644 --- a/packages/api/src/@core/auth/strategies/jwt.strategy.ts +++ b/packages/api/src/@core/auth/strategies/jwt.strategy.ts @@ -15,6 +15,11 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { } async validate(payload: any) { - return { id_user: payload.sub, email: payload.email, first_name: payload.first_name, last_name: payload.last_name }; + return { + id_user: payload.sub, + email: payload.email, + first_name: payload.first_name, + last_name: payload.last_name, + }; } } diff --git a/packages/api/src/@core/connections-strategies/connections-strategies.controller.ts b/packages/api/src/@core/connections-strategies/connections-strategies.controller.ts index dbef1e87c..68eb39b6b 100644 --- a/packages/api/src/@core/connections-strategies/connections-strategies.controller.ts +++ b/packages/api/src/@core/connections-strategies/connections-strategies.controller.ts @@ -1,19 +1,14 @@ -import { Body, Controller, Get, Post, Query, Res } from '@nestjs/common'; +import { Body, Controller, Get, Post, Query, UseGuards } from '@nestjs/common'; import { LoggerService } from '@@core/logger/logger.service'; -import { - ApiBody, - ApiOperation, - ApiQuery, - ApiResponse, - ApiTags, -} from '@nestjs/swagger'; +import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ConnectionsStrategiesService } from './connections-strategies.service'; import { CreateConnectionStrategyDto } from './dto/create-connections-strategies.dto'; import { ToggleStrategyDto } from './dto/toggle.dto'; -import { GetConnectionStrategyDto } from './dto/get-connections.dto'; import { DeleteCSDto } from './dto/delete-cs.dto'; import { UpdateCSDto } from './dto/update-cs.dto'; import { ConnectionStrategyCredentials } from './dto/get-connection-cs-credentials.dto'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; +import { ValidateUserGuard } from '@@core/utils/guards/validate-user.guard'; @ApiTags('connections-strategies') @Controller('connections-strategies') @@ -25,34 +20,19 @@ export class ConnectionsStrategiesController { this.logger.setContext(ConnectionsStrategiesController.name); } - /*@ApiOperation({ - operationId: 'isCustomCredentials', - summary: - 'Fetch info on whether the customer uses custom credentials for connections', - }) - @ApiResponse({ status: 200 }) - @Get('isCustomCredentials') - async isCustomCredentials( - @Query('projectId') projectId: string, - @Query('type') type: string, - ) { - return await this.connectionsStrategiesService.isCustomCredentials( - projectId, - type, - ); - }*/ - @ApiOperation({ operationId: 'createConnectionStrategy', summary: 'Create Connection Strategy', }) @ApiBody({ type: CreateConnectionStrategyDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('create') async createConnectionStrategy( @Body() connectionStrategyCreateDto: CreateConnectionStrategyDto, ) { const { projectId, type, attributes, values } = connectionStrategyCreateDto; + // validate user against project_id return await this.connectionsStrategiesService.createConnectionStrategy( projectId, type, @@ -61,32 +41,16 @@ export class ConnectionsStrategiesController { ); } - /*@ApiOperation({ - operationId: 'getConnectionStrategyData', - summary: 'Get Connection Strategy Data', - }) - @ApiBody({ type: GetConnectionStrategyDto }) - @ApiResponse({ status: 201 }) - @Post('get') - async getConnectionStrategyData( - @Body() connectionStrategyCreateDto: GetConnectionStrategyDto, - ) { - const { projectId, type, attributes } = connectionStrategyCreateDto; - return await this.connectionsStrategiesService.getConnectionStrategyData( - projectId, - type, - attributes, - ); - }*/ - @ApiOperation({ operationId: 'toggleConnectionStrategy', summary: 'Activate/Deactivate Connection Strategy', }) @ApiBody({ type: ToggleStrategyDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('toggle') async toggleConnectionStrategy(@Body() data: ToggleStrategyDto) { + // validate user against project_id return await this.connectionsStrategiesService.toggle(data.id_cs); } @@ -96,8 +60,10 @@ export class ConnectionsStrategiesController { }) @ApiBody({ type: DeleteCSDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('delete') async deleteConnectionStrategy(@Body() data: DeleteCSDto) { + // validate user against project_id return await this.connectionsStrategiesService.deleteConnectionStrategy( data.id, ); @@ -109,9 +75,11 @@ export class ConnectionsStrategiesController { }) @ApiBody({ type: UpdateCSDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('update') async updateConnectionStrategy(@Body() updateData: UpdateCSDto) { const { attributes, id_cs, status, values } = updateData; + // validate user against project_id return await this.connectionsStrategiesService.updateConnectionStrategy( id_cs, status, @@ -126,10 +94,12 @@ export class ConnectionsStrategiesController { }) @ApiBody({ type: ConnectionStrategyCredentials }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('credentials') async getConnectionStrategyCredential( @Body() data: ConnectionStrategyCredentials, ) { + // validate user against project_id const { attributes, projectId, type } = data; return await this.connectionsStrategiesService.getConnectionStrategyData( projectId, @@ -138,11 +108,13 @@ export class ConnectionsStrategiesController { ); } + //todo: ADMIN @ApiOperation({ operationId: 'getCredentials', summary: 'Fetch credentials info needed for connections', }) @ApiResponse({ status: 200 }) + //@UseGuards(JwtAuthGuard) @Get('getCredentials') async getCredentials( @Query('projectId') projectId: string, @@ -159,7 +131,8 @@ export class ConnectionsStrategiesController { summary: 'Fetch All Connection Strategies for Project', }) @ApiResponse({ status: 200 }) - @Get('GetConnectionStrategiesForProject') + @UseGuards(JwtAuthGuard, ValidateUserGuard) + @Get('getConnectionStrategiesForProject') async getConnectionStrategiesForProject( @Query('projectId') projectId: string, ) { diff --git a/packages/api/src/@core/connections-strategies/connections-strategies.module.ts b/packages/api/src/@core/connections-strategies/connections-strategies.module.ts index 8c72bcebd..1282a9fb0 100644 --- a/packages/api/src/@core/connections-strategies/connections-strategies.module.ts +++ b/packages/api/src/@core/connections-strategies/connections-strategies.module.ts @@ -4,6 +4,7 @@ import { PrismaService } from '@@core/prisma/prisma.service'; import { ConnectionsStrategiesController } from './connections-strategies.controller'; import { ConnectionsStrategiesService } from './connections-strategies.service'; import { ConfigService } from '@nestjs/config'; +import { ValidateUserService } from '@@core/utils/services/validateUser.service'; @Module({ controllers: [ConnectionsStrategiesController], @@ -12,6 +13,7 @@ import { ConfigService } from '@nestjs/config'; PrismaService, ConnectionsStrategiesService, ConfigService, + ValidateUserService, ], }) export class ConnectionsStrategiesModule {} diff --git a/packages/api/src/@core/connections/connections.controller.ts b/packages/api/src/@core/connections/connections.controller.ts index cbe8f3088..84be76817 100644 --- a/packages/api/src/@core/connections/connections.controller.ts +++ b/packages/api/src/@core/connections/connections.controller.ts @@ -1,4 +1,12 @@ -import { Controller, Get, Query, Res, Param } from '@nestjs/common'; +import { + Controller, + Get, + Param, + Query, + Res, + UseGuards, + Request, +} from '@nestjs/common'; import { Response } from 'express'; import { CrmConnectionsService } from './crm/services/crm.connection.service'; import { LoggerService } from '@@core/logger/logger.service'; @@ -9,6 +17,8 @@ import { TicketingConnectionsService } from './ticketing/services/ticketing.conn import { ProviderVertical } from '@panora/shared'; import { AccountingConnectionsService } from './accounting/services/accounting.connection.service'; import { MarketingAutomationConnectionsService } from './marketingautomation/services/marketingautomation.connection.service'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; +import { ValidateUserGuard } from '@@core/utils/guards/validate-user.guard'; export type StateDataType = { projectId: string; @@ -135,24 +145,16 @@ export class ConnectionsController { summary: 'List Connections', }) @ApiResponse({ status: 200 }) + @UseGuards(JwtAuthGuard, ValidateUserGuard) @Get() - async getConnections() { - return await this.prisma.connections.findMany(); + async getConnections( + @Request() req: any, + @Query('projectId') projectId: string, + ) { + return await this.prisma.connections.findMany({ + where: { + id_project: projectId, + }, + }); } - - // @ApiOperation({ - // operationId: 'getConnectionsByUser', - // summary: 'Retrieve connections by user', - // }) - // @ApiResponse({ status: 200 }) - // @Get(':userId') - // getProjectsByUser(@Param('userId') userId: string) { - // return this.prisma.connections.findMany( - // { - // where: { - // id - // } - // } - // ); - // } } diff --git a/packages/api/src/@core/connections/connections.module.ts b/packages/api/src/@core/connections/connections.module.ts index bab08627d..a37be7b2d 100644 --- a/packages/api/src/@core/connections/connections.module.ts +++ b/packages/api/src/@core/connections/connections.module.ts @@ -6,6 +6,7 @@ import { PrismaService } from '@@core/prisma/prisma.service'; import { TicketingConnectionModule } from './ticketing/ticketing.connection.module'; import { AccountingConnectionModule } from './accounting/accounting.connection.module'; import { MarketingAutomationConnectionsModule } from './marketingautomation/marketingautomation.connection.module'; +import { ValidateUserService } from '@@core/utils/services/validateUser.service'; @Module({ controllers: [ConnectionsController], @@ -15,7 +16,7 @@ import { MarketingAutomationConnectionsModule } from './marketingautomation/mark AccountingConnectionModule, MarketingAutomationConnectionsModule, ], - providers: [LoggerService, PrismaService], + providers: [LoggerService, PrismaService, ValidateUserService], exports: [ CrmConnectionModule, TicketingConnectionModule, diff --git a/packages/api/src/@core/events/events.controller.ts b/packages/api/src/@core/events/events.controller.ts index fc541c7cd..758410fa9 100644 --- a/packages/api/src/@core/events/events.controller.ts +++ b/packages/api/src/@core/events/events.controller.ts @@ -2,6 +2,7 @@ import { Controller, Get, Query, + UseGuards, UsePipes, ValidationPipe, } from '@nestjs/common'; @@ -9,6 +10,8 @@ import { EventsService } from './events.service'; import { LoggerService } from '@@core/logger/logger.service'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { PaginationDto } from '@@core/utils/dtos/pagination.dto'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; +import { ValidateUserGuard } from '@@core/utils/guards/validate-user.guard'; @ApiTags('events') @Controller('events') @@ -31,16 +34,22 @@ export class EventsController { }, }), ) + @UseGuards(JwtAuthGuard, ValidateUserGuard) @Get() - async getEvents(@Query() dto: PaginationDto) { - return await this.eventsService.findEvents(dto); + async getEvents( + @Query() dto: PaginationDto, + @Query('project_id') project_id: string, + ) { + return await this.eventsService.findEvents(dto, project_id); } + // todo @ApiOperation({ operationId: 'getEventsCount', summary: 'Retrieve Events Count', }) @Get('count') + @UseGuards(JwtAuthGuard) async getEventsCount() { return await this.eventsService.getEventsCount(); } diff --git a/packages/api/src/@core/events/events.module.ts b/packages/api/src/@core/events/events.module.ts index e00f25980..444e862d3 100644 --- a/packages/api/src/@core/events/events.module.ts +++ b/packages/api/src/@core/events/events.module.ts @@ -3,9 +3,10 @@ import { EventsService } from './events.service'; import { EventsController } from './events.controller'; import { LoggerService } from '@@core/logger/logger.service'; import { PrismaService } from '@@core/prisma/prisma.service'; +import { ValidateUserService } from '@@core/utils/services/validateUser.service'; @Module({ - providers: [EventsService, LoggerService, PrismaService], + providers: [EventsService, LoggerService, PrismaService, ValidateUserService], controllers: [EventsController], }) export class EventsModule {} diff --git a/packages/api/src/@core/events/events.service.ts b/packages/api/src/@core/events/events.service.ts index 0d2b0b171..bab3e5126 100644 --- a/packages/api/src/@core/events/events.service.ts +++ b/packages/api/src/@core/events/events.service.ts @@ -9,12 +9,31 @@ export class EventsService { constructor(private prisma: PrismaService, private logger: LoggerService) { this.logger.setContext(EventsService.name); } - async findEvents(dto: PaginationDto) { + async findEvents(dto: PaginationDto, project_id: string) { try { + // First, fetch the linked_users related to the project_id + const linkedUsers = await this.prisma.linked_users.findMany({ + where: { + id_project: project_id, + }, + select: { + id_linked_user: true, + }, + }); + + // Extract the ids of the linked_users + const linkedUserIds = linkedUsers.map((user) => user.id_linked_user); + + // Then, use those ids to filter the events return await this.prisma.events.findMany({ orderBy: { timestamp: 'desc' }, skip: (dto.page - 1) * dto.pageSize, take: dto.pageSize, + where: { + id_linked_user: { + in: linkedUserIds, + }, + }, }); } catch (error) { handleServiceError(error, this.logger); diff --git a/packages/api/src/@core/field-mapping/field-mapping.controller.ts b/packages/api/src/@core/field-mapping/field-mapping.controller.ts index 6e9f64c8d..a9532bf44 100644 --- a/packages/api/src/@core/field-mapping/field-mapping.controller.ts +++ b/packages/api/src/@core/field-mapping/field-mapping.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Get, Post, Query } from '@nestjs/common'; +import { Body, Controller, Get, Post, Query, UseGuards } from '@nestjs/common'; import { LoggerService } from '../logger/logger.service'; import { FieldMappingService } from './field-mapping.service'; import { @@ -6,6 +6,7 @@ import { MapFieldToProviderDto, } from './dto/create-custom-field.dto'; import { ApiResponse, ApiTags, ApiBody, ApiOperation } from '@nestjs/swagger'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; @ApiTags('field-mapping') @Controller('field-mapping') @@ -22,6 +23,7 @@ export class FieldMappingController { summary: 'Retrieve field mapping entities', }) @ApiResponse({ status: 200 }) + @UseGuards(JwtAuthGuard) @Get('entities') getEntities() { return this.fieldMappingService.getEntities(); @@ -33,6 +35,7 @@ export class FieldMappingController { }) @ApiResponse({ status: 200 }) @Get('attribute') + @UseGuards(JwtAuthGuard) getAttributes() { return this.fieldMappingService.getAttributes(); } @@ -43,6 +46,7 @@ export class FieldMappingController { }) @ApiResponse({ status: 200 }) @Get('value') + @UseGuards(JwtAuthGuard) getValues() { return this.fieldMappingService.getValues(); } @@ -55,6 +59,7 @@ export class FieldMappingController { @ApiResponse({ status: 201 }) //define target field on our unified model @Post('define') + @UseGuards(JwtAuthGuard) defineTargetField(@Body() defineTargetFieldDto: DefineTargetFieldDto) { return this.fieldMappingService.defineTargetField(defineTargetFieldDto); } @@ -62,6 +67,7 @@ export class FieldMappingController { @ApiOperation({ operationId: 'mapField', summary: 'Map Custom Field' }) @ApiBody({ type: MapFieldToProviderDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('map') mapFieldToProvider(@Body() mapFieldToProviderDto: MapFieldToProviderDto) { return this.fieldMappingService.mapFieldToProvider(mapFieldToProviderDto); @@ -72,6 +78,7 @@ export class FieldMappingController { summary: 'Retrieve Custom Properties', }) @ApiResponse({ status: 200 }) + @UseGuards(JwtAuthGuard) @Get('properties') getCustomProperties( @Query('linkedUserId') linkedUserId: string, diff --git a/packages/api/src/@core/linked-users/linked-users.controller.ts b/packages/api/src/@core/linked-users/linked-users.controller.ts index 70d43758b..acd605dc3 100644 --- a/packages/api/src/@core/linked-users/linked-users.controller.ts +++ b/packages/api/src/@core/linked-users/linked-users.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Get, Post, Query } from '@nestjs/common'; +import { Body, Controller, Get, Post, Query, UseGuards } from '@nestjs/common'; import { LinkedUsersService } from './linked-users.service'; import { LoggerService } from '../logger/logger.service'; import { CreateLinkedUserDto } from './dto/create-linked-user.dto'; @@ -9,6 +9,8 @@ import { ApiResponse, ApiTags, } from '@nestjs/swagger'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; +import { ValidateUserGuard } from '@@core/utils/guards/validate-user.guard'; @ApiTags('linked-users') @Controller('linked-users') @@ -23,8 +25,10 @@ export class LinkedUsersController { @ApiOperation({ operationId: 'addLinkedUser', summary: 'Add Linked User' }) @ApiBody({ type: CreateLinkedUserDto }) @ApiResponse({ status: 201 }) + //@UseGuards(JwtAuthGuard) @Post('create') addLinkedUser(@Body() linkedUserCreateDto: CreateLinkedUserDto) { + // validate project_id against user return this.linkedUsersService.addLinkedUser(linkedUserCreateDto); } @@ -33,9 +37,10 @@ export class LinkedUsersController { summary: 'Retrieve Linked Users', }) @ApiResponse({ status: 200 }) + @UseGuards(JwtAuthGuard, ValidateUserGuard) @Get() - getLinkedUsers() { - return this.linkedUsersService.getLinkedUsers(); + getLinkedUsers(@Query('project_id') project_id: string) { + return this.linkedUsersService.getLinkedUsers(project_id); } @ApiOperation({ @@ -44,8 +49,10 @@ export class LinkedUsersController { }) @ApiQuery({ name: 'id', required: true, type: String }) @ApiResponse({ status: 200 }) + //@UseGuards(JwtAuthGuard) @Get('single') getLinkedUser(@Query('id') id: string) { + // validate project_id against user return this.linkedUsersService.getLinkedUser(id); } @@ -55,8 +62,10 @@ export class LinkedUsersController { }) @ApiQuery({ name: 'originId', required: true, type: String }) @ApiResponse({ status: 200 }) + //@UseGuards(JwtAuthGuard) @Get('single') getLinkedUserV2(@Query('originId') id: string) { + // validate project_id against user return this.linkedUsersService.getLinkedUserV2(id); } } diff --git a/packages/api/src/@core/linked-users/linked-users.module.ts b/packages/api/src/@core/linked-users/linked-users.module.ts index bca65f48e..6da66331c 100644 --- a/packages/api/src/@core/linked-users/linked-users.module.ts +++ b/packages/api/src/@core/linked-users/linked-users.module.ts @@ -3,9 +3,15 @@ import { LinkedUsersService } from './linked-users.service'; import { LinkedUsersController } from './linked-users.controller'; import { LoggerService } from '../logger/logger.service'; import { PrismaService } from '../prisma/prisma.service'; +import { ValidateUserService } from '@@core/utils/services/validateUser.service'; @Module({ - providers: [LinkedUsersService, LoggerService, PrismaService], + providers: [ + LinkedUsersService, + LoggerService, + PrismaService, + ValidateUserService, + ], controllers: [LinkedUsersController], }) export class LinkedUsersModule {} diff --git a/packages/api/src/@core/linked-users/linked-users.service.ts b/packages/api/src/@core/linked-users/linked-users.service.ts index 5d42193fd..66589fc89 100644 --- a/packages/api/src/@core/linked-users/linked-users.service.ts +++ b/packages/api/src/@core/linked-users/linked-users.service.ts @@ -10,9 +10,13 @@ export class LinkedUsersService { constructor(private prisma: PrismaService, private logger: LoggerService) { this.logger.setContext(LinkedUsersService.name); } - async getLinkedUsers() { + async getLinkedUsers(project_id: string) { try { - return await this.prisma.linked_users.findMany(); + return await this.prisma.linked_users.findMany({ + where: { + id_project: project_id, + }, + }); } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/src/@core/magic-link/magic-link.controller.ts b/packages/api/src/@core/magic-link/magic-link.controller.ts index afbb095ac..dcddb689a 100644 --- a/packages/api/src/@core/magic-link/magic-link.controller.ts +++ b/packages/api/src/@core/magic-link/magic-link.controller.ts @@ -1,5 +1,5 @@ import { LoggerService } from '@@core/logger/logger.service'; -import { Body, Controller, Get, Post, Query } from '@nestjs/common'; +import { Body, Controller, Get, Post, Query, UseGuards } from '@nestjs/common'; import { MagicLinkService } from './magic-link.service'; import { CreateMagicLinkDto } from './dto/create-magic-link.dto'; import { @@ -9,7 +9,7 @@ import { ApiResponse, ApiTags, } from '@nestjs/swagger'; -import { invite_links as MagicLink } from '@prisma/client'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; @ApiTags('magic-link') @Controller('magic-link') export class MagicLinkController { @@ -26,11 +26,13 @@ export class MagicLinkController { }) @ApiBody({ type: CreateMagicLinkDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('create') createLink(@Body() data: CreateMagicLinkDto) { return this.magicLinkService.createUniqueLink(data); } + // todo: only admin @ApiOperation({ operationId: 'getMagicLinks', summary: 'Retrieve Magic Links', @@ -41,6 +43,7 @@ export class MagicLinkController { return this.magicLinkService.getMagicLinks(); } + // admin @ApiOperation({ operationId: 'getMagicLink', summary: 'Retrieve a Magic Link', @@ -49,6 +52,7 @@ export class MagicLinkController { @ApiResponse({ status: 200 }) @Get('single') getMagicLink(@Query('id') id: string) { + // validate project_id against user return this.magicLinkService.getMagicLink(id); } } diff --git a/packages/api/src/@core/magic-link/magic-link.module.ts b/packages/api/src/@core/magic-link/magic-link.module.ts index 9d1cd18a0..bb2b1e34a 100644 --- a/packages/api/src/@core/magic-link/magic-link.module.ts +++ b/packages/api/src/@core/magic-link/magic-link.module.ts @@ -3,9 +3,10 @@ import { MagicLinkController } from './magic-link.controller'; import { MagicLinkService } from './magic-link.service'; import { LoggerService } from '@@core/logger/logger.service'; import { PrismaService } from '@@core/prisma/prisma.service'; +import { JwtService } from '@nestjs/jwt'; @Module({ controllers: [MagicLinkController], - providers: [MagicLinkService, PrismaService, LoggerService], + providers: [MagicLinkService, PrismaService, LoggerService, JwtService], }) export class MagicLinkModule {} diff --git a/packages/api/src/@core/projects/projects.controller.ts b/packages/api/src/@core/projects/projects.controller.ts index 9c0dd7827..cc4e11c42 100644 --- a/packages/api/src/@core/projects/projects.controller.ts +++ b/packages/api/src/@core/projects/projects.controller.ts @@ -1,8 +1,17 @@ -import { Body, Controller, Get, Param, Post } from '@nestjs/common'; +import { + Body, + Controller, + Get, + Param, + Post, + UseGuards, + Request, +} from '@nestjs/common'; import { ProjectsService } from './projects.service'; import { LoggerService } from '../logger/logger.service'; import { CreateProjectDto } from './dto/create-project.dto'; import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; @ApiTags('projects') @Controller('projects') @@ -16,24 +25,17 @@ export class ProjectsController { @ApiOperation({ operationId: 'getProjects', summary: 'Retrieve projects' }) @ApiResponse({ status: 200 }) + @UseGuards(JwtAuthGuard) @Get() - getProjects() { - return this.projectsService.getProjects(); - } - - @ApiOperation({ - operationId: 'getProjectsByUser', - summary: 'Retrieve projects by user', - }) - @ApiResponse({ status: 200 }) - @Get(':userId') - getProjectsByUser(@Param('userId') userId: string) { - return this.projectsService.getProjectsByUser(userId); + getProjects(@Request() req: any) { + const user_id = req.user.id_user; + return this.projectsService.getProjectsByUser(user_id); } @ApiOperation({ operationId: 'createProject', summary: 'Create a project' }) @ApiBody({ type: CreateProjectDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post('create') createProject(@Body() projectCreateDto: CreateProjectDto) { return this.projectsService.createProject(projectCreateDto); diff --git a/packages/api/src/@core/utils/guards/validate-user.guard.ts b/packages/api/src/@core/utils/guards/validate-user.guard.ts new file mode 100644 index 000000000..efdf4921f --- /dev/null +++ b/packages/api/src/@core/utils/guards/validate-user.guard.ts @@ -0,0 +1,24 @@ +// validate-user.guard.ts +import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; +import { Observable } from 'rxjs'; +import { ValidateUserService } from '../services/validateUser.service'; + +@Injectable() +export class ValidateUserGuard implements CanActivate { + constructor(private readonly validateUserService: ValidateUserService) {} + + canActivate( + context: ExecutionContext, + ): boolean | Promise | Observable { + const request = context.switchToHttp().getRequest(); + const { id_user } = request.user; + const project_id = request.query.project_id; // Extract project_id from the query parameters + + // Ensure project_id is provided and is a string + if (!project_id || typeof project_id !== 'string') { + return false; + } + + return this.validateUserService.validate(id_user, project_id); + } +} diff --git a/packages/api/src/@core/utils/services/validateUser.service.ts b/packages/api/src/@core/utils/services/validateUser.service.ts new file mode 100644 index 000000000..47b65ac8c --- /dev/null +++ b/packages/api/src/@core/utils/services/validateUser.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '@@core/prisma/prisma.service'; +import { LoggerService } from '@@core/logger/logger.service'; +import { handleServiceError } from '@@core/utils/errors'; + +@Injectable() +export class ValidateUserService { + constructor(private prisma: PrismaService, private logger: LoggerService) {} + + async validate(user_id: string, project_id: string) { + try { + const project = await this.prisma.projects.findUnique({ + where: { + id_project: project_id, + }, + }); + if (project.id_user !== user_id) { + throw new Error('Unauthorized call from sender'); + } + return true; + } catch (error) { + handleServiceError(error, this.logger); + } + } +} diff --git a/packages/api/src/@core/webhook/webhook.controller.ts b/packages/api/src/@core/webhook/webhook.controller.ts index 216c42c6d..6a208e04f 100644 --- a/packages/api/src/@core/webhook/webhook.controller.ts +++ b/packages/api/src/@core/webhook/webhook.controller.ts @@ -1,8 +1,20 @@ -import { Body, Controller, Get, Post, Put, Param } from '@nestjs/common'; +import { + Body, + Controller, + Get, + Post, + Put, + Param, + UseGuards, + Request, + Query, +} from '@nestjs/common'; import { LoggerService } from '@@core/logger/logger.service'; import { ApiBody, ApiResponse, ApiTags, ApiOperation } from '@nestjs/swagger'; import { WebhookService } from './webhook.service'; import { WebhookDto } from './dto/webhook.dto'; +import { JwtAuthGuard } from '@@core/auth/guards/jwt-auth.guard'; +import { ValidateUserGuard } from '@@core/utils/guards/validate-user.guard'; @ApiTags('webhook') @Controller('webhook') @@ -19,20 +31,24 @@ export class WebhookController { summary: 'Retrieve webhooks metadata ', }) @ApiResponse({ status: 200 }) + @UseGuards(JwtAuthGuard, ValidateUserGuard) @Get() - getWebhooks() { - return this.webhookService.getWebhookEndpoints(); + getWebhooks(@Query('project_id') project_id: string) { + return this.webhookService.getWebhookEndpoints(project_id); } @ApiOperation({ operationId: 'updateWebhookStatus', summary: 'Update webhook status', }) + @UseGuards(JwtAuthGuard) @Put(':id') async updateWebhookStatus( @Param('id') id: string, @Body('active') active: boolean, + @Request() req: any, ) { + // verify id of webhook belongs to user from req return this.webhookService.updateStatusWebhookEndpoint(id, active); } @@ -42,8 +58,10 @@ export class WebhookController { }) @ApiBody({ type: WebhookDto }) @ApiResponse({ status: 201 }) + @UseGuards(JwtAuthGuard) @Post() async addWebhook(@Body() data: WebhookDto) { + // verify project id of user is same from data return this.webhookService.createWebhookEndpoint(data); } } diff --git a/packages/api/src/@core/webhook/webhook.module.ts b/packages/api/src/@core/webhook/webhook.module.ts index 972697518..769841b45 100644 --- a/packages/api/src/@core/webhook/webhook.module.ts +++ b/packages/api/src/@core/webhook/webhook.module.ts @@ -5,6 +5,7 @@ import { PrismaService } from '@@core/prisma/prisma.service'; import { LoggerService } from '@@core/logger/logger.service'; import { WebhookProcessor } from './webhook.processor'; import { WebhookController } from './webhook.controller'; +import { ValidateUserService } from '@@core/utils/services/validateUser.service'; @Module({ imports: [ @@ -18,6 +19,12 @@ import { WebhookController } from './webhook.controller'; name: 'webhookDelivery', }), ], - providers: [WebhookService, PrismaService, LoggerService, WebhookProcessor], + providers: [ + WebhookService, + PrismaService, + LoggerService, + WebhookProcessor, + ValidateUserService, + ], }) export class WebhookModule {} diff --git a/packages/api/src/@core/webhook/webhook.service.ts b/packages/api/src/@core/webhook/webhook.service.ts index fafd0d7ba..4fd092b52 100644 --- a/packages/api/src/@core/webhook/webhook.service.ts +++ b/packages/api/src/@core/webhook/webhook.service.ts @@ -18,9 +18,13 @@ export class WebhookService { this.logger.setContext(WebhookService.name); } - async getWebhookEndpoints() { + async getWebhookEndpoints(project_id: string) { try { - return await this.prisma.webhook_endpoints.findMany(); + return await this.prisma.webhook_endpoints.findMany({ + where: { + id_project: project_id, + }, + }); } catch (error) { handleServiceError(error, this.logger); } diff --git a/packages/api/swagger/swagger-spec.json b/packages/api/swagger/swagger-spec.json index b1874aed1..8a93f3700 100644 --- a/packages/api/swagger/swagger-spec.json +++ b/packages/api/swagger/swagger-spec.json @@ -176,7 +176,16 @@ "get": { "operationId": "getApiKeys", "summary": "Retrieve API Keys", - "parameters": [], + "parameters": [ + { + "name": "project_id", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "" @@ -327,7 +336,16 @@ "get": { "operationId": "getConnections", "summary": "List Connections", - "parameters": [], + "parameters": [ + { + "name": "projectId", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "" @@ -342,7 +360,16 @@ "get": { "operationId": "getWebhooksMetadata", "summary": "Retrieve webhooks metadata ", - "parameters": [], + "parameters": [ + { + "name": "project_id", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "" @@ -429,7 +456,16 @@ "get": { "operationId": "getLinkedUsers", "summary": "Retrieve Linked Users", - "parameters": [], + "parameters": [ + { + "name": "project_id", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "" @@ -519,30 +555,6 @@ ] } }, - "/projects/{userId}": { - "get": { - "operationId": "getProjectsByUser", - "summary": "Retrieve projects by user", - "parameters": [ - { - "name": "userId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "" - } - }, - "tags": [ - "projects" - ] - } - }, "/projects/create": { "post": { "operationId": "createProject", @@ -727,6 +739,14 @@ "default": 10, "type": "number" } + }, + { + "name": "project_id", + "required": true, + "in": "query", + "schema": { + "type": "string" + } } ], "responses": { @@ -1049,7 +1069,7 @@ ] } }, - "/connections-strategies/GetConnectionStrategiesForProject": { + "/connections-strategies/getConnectionStrategiesForProject": { "get": { "operationId": "getConnectionStrategiesForProject", "summary": "Fetch All Connection Strategies for Project",