diff --git a/flowsint-api/app/__pycache__/__init__.cpython-311.pyc b/flowsint-api/app/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 2d127c6..0000000 Binary files a/flowsint-api/app/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/flowsint-api/app/core/__pycache__/celery.cpython-311.pyc b/flowsint-api/app/core/__pycache__/celery.cpython-311.pyc deleted file mode 100644 index 1a22136..0000000 Binary files a/flowsint-api/app/core/__pycache__/celery.cpython-311.pyc and /dev/null differ diff --git a/flowsint-api/app/core/__pycache__/db.cpython-311.pyc b/flowsint-api/app/core/__pycache__/db.cpython-311.pyc deleted file mode 100644 index b3db0d0..0000000 Binary files a/flowsint-api/app/core/__pycache__/db.cpython-311.pyc and /dev/null differ diff --git a/flowsint-api/app/tasks/__pycache__/__init__.cpython-311.pyc b/flowsint-api/app/tasks/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 686b13a..0000000 Binary files a/flowsint-api/app/tasks/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/flowsint-api/app/tasks/__pycache__/email_scanner.cpython-311.pyc b/flowsint-api/app/tasks/__pycache__/email_scanner.cpython-311.pyc deleted file mode 100644 index 1160ab7..0000000 Binary files a/flowsint-api/app/tasks/__pycache__/email_scanner.cpython-311.pyc and /dev/null differ diff --git a/flowsint-api/app/workers/__pycache__/__init__.cpython-311.pyc b/flowsint-api/app/workers/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 4e9e13d..0000000 Binary files a/flowsint-api/app/workers/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/flowsint-api/app/workers/__pycache__/email_scanner.cpython-311.pyc b/flowsint-api/app/workers/__pycache__/email_scanner.cpython-311.pyc deleted file mode 100644 index adbcbda..0000000 Binary files a/flowsint-api/app/workers/__pycache__/email_scanner.cpython-311.pyc and /dev/null differ diff --git a/flowsint-web/lib/utils.ts b/flowsint-web/lib/utils.ts deleted file mode 100644 index bd0c391..0000000 --- a/flowsint-web/lib/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { clsx, type ClassValue } from "clsx" -import { twMerge } from "tailwind-merge" - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} diff --git a/flowsint-web/src/components/dashboard/new-project.tsx b/flowsint-web/src/components/dashboard/new-project.tsx index d8c9a91..5875fe0 100644 --- a/flowsint-web/src/components/dashboard/new-project.tsx +++ b/flowsint-web/src/components/dashboard/new-project.tsx @@ -4,7 +4,7 @@ import type React from "react" import { useState } from "react" import { useRouter } from "next/navigation" -import { createNewProject } from "@/lib/actions/project" +import { createNewProject } from "@/lib/actions/projects" import { Button } from "@/components/ui/button" import { Dialog, diff --git a/flowsint-web/src/lib/actions/auth.ts b/flowsint-web/src/lib/actions/auth.ts deleted file mode 100644 index f8d780f..0000000 --- a/flowsint-web/src/lib/actions/auth.ts +++ /dev/null @@ -1,70 +0,0 @@ -'use server' - -import { revalidatePath } from 'next/cache' -import { redirect } from 'next/navigation' -import { createClient } from '@/lib/supabase/server' - -export async function signInWithGithub() { - const supabase = await createClient() - const { data } = await supabase.auth.signInWithOAuth({ - provider: 'github', - options: { - redirectTo: process.env.NEXT_PUBLIC_AUTH_REDIRECT, - }, - }) - if (data.url) { - redirect(data.url) - } -} - -export async function login(formData: FormData) { - const supabase = await createClient() - - // type-casting here for convenience - // in practice, you should validate your inputs - const data = { - email: formData.get('email') as string, - password: formData.get('password') as string, - } - - const { error } = await supabase.auth.signInWithPassword(data) - - if (error) { - redirect('/error') - } - // revalidatePath('/', 'layout') - // redirect('/') -} - -export async function signup(formData: FormData) { - const supabase = await createClient() - - // type-casting here for convenience - // in practice, you should validate your inputs - const data = { - email: formData.get('email') as string, - password: formData.get('password') as string, - } - - const { error } = await supabase.auth.signUp(data) - - if (error) { - redirect('/error') - } - - revalidatePath('/', 'layout') - redirect('/') -} - -export async function logout() { - const supabase = await createClient() - - const { error } = await supabase.auth.signOut() - - if (error) { - redirect('/error') - } - - revalidatePath('/', 'layout') - redirect('/login') -} \ No newline at end of file diff --git a/flowsint-web/src/lib/actions/investigations.ts b/flowsint-web/src/lib/actions/investigations.ts deleted file mode 100644 index dde1898..0000000 --- a/flowsint-web/src/lib/actions/investigations.ts +++ /dev/null @@ -1,25 +0,0 @@ -"use server" -import { createClient } from "../supabase/server" -import { redirect } from "next/navigation" -import { revalidatePath } from "next/cache" - -export async function createNewCase(formData: FormData, project_id: string) { - const supabase = await createClient() - const { data: session, error: userError } = await supabase.auth.getUser() - if (userError || !session?.user) { - redirect('/login') - } - const data = { - title: formData.get("title"), - description: formData.get("description"), - } - try { - const { data: investigation, error } = await supabase.from("investigations").insert({ ...data, owner_id: session?.user?.id, project_id }).select("id").single() - if (error) throw error - revalidatePath("/") - return { success: true, id: investigation.id } - } catch (error) { - console.error("Error creating new case:", error) - return { success: false, error: "Failed to create new case" } - } -} diff --git a/flowsint-web/src/lib/actions/search.ts b/flowsint-web/src/lib/actions/search.ts deleted file mode 100644 index 9f567fd..0000000 --- a/flowsint-web/src/lib/actions/search.ts +++ /dev/null @@ -1,77 +0,0 @@ -'use server' -import { createClient } from "../supabase/server"; - -export async function checkEmail(email: string, investigation_id: string) { - const url = `${process.env.NEXT_PUBLIC_DOCKER_FLOWSINT_API}/scan/`; - const response = await fetch(url, { - method: 'POST', - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - "email": email, - "investigation_id": investigation_id - }) - }, - ); - return response.json(); -} - -async function checkBreachedAccount(account: string | number | boolean, apiKey: string, appName: string) { - const url = `https://haveibeenpwned.com/api/v3/breachedaccount/${encodeURIComponent(account)}?truncateResponse=false`; - const supabase = await createClient() - try { - const response = await fetch(url, { - method: 'GET', - headers: { - 'hibp-api-key': apiKey, - 'user-agent': appName - } - }); - - if (response.ok) { - const data = await response.json() as any[]; - for (const breach of data) { - // insert a new breach if not exist - const { error } = await supabase.from('breaches').upsert({ - name: breach.Name, description: breach.Description, raw_content: breach - }, { onConflict: 'name' }) - if (error) return error - // then get the breach and upsert a new relation with account - const { data: br, error: breachError } = await supabase.from('breaches') - .select('id') - .eq("name", breach.Name).single() - if (breachError) return breachError - if (br) { - // finally insert new relation between account and breach - const { error: relationError } = await supabase.from('accounts_breaches').upsert({ - account: account, breach_id: br.id - }, { - onConflict: 'account,breach_id' - }) - if (relationError) return relationError - } - - } - return data; - } else if (response.status === 404) { - return `Good news! Account ${account} hasn't been found in any breaches.`; - } else { - return `Error: ${response.status} - ${response.statusText}`; - } - } catch (error) { - console.error('An error occurred:', error); - return null; - } -} - -const apiKey = process.env.HIBP_API_KEY || "" -const appName = 'MyHIBPChecker'; - -export async function investigateHIBPwd(username: string) { - if (!username) { - throw new Error("Malformed query.") - } - return checkBreachedAccount(username, apiKey, appName); - -} \ No newline at end of file diff --git a/flowsint-web/src/lib/hooks/individuals/use-emails-breaches.ts b/flowsint-web/src/lib/hooks/individuals/use-emails-breaches.ts deleted file mode 100644 index 245b26b..0000000 --- a/flowsint-web/src/lib/hooks/individuals/use-emails-breaches.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { supabase } from "@/lib/supabase/client" -import { useQuery } from "@supabase-cache-helpers/postgrest-swr" - -export function useEmailsAndBreaches(individualId: string | null | undefined) { - const { data: emails, error } = useQuery( - individualId ? supabase.from("individuals").select(`*, emails(*)`).eq("id", individualId).single() : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - }, - ) - - const emailAddresses = emails?.emails?.map(({ email }: { email: string }) => email) || [] - - const { data: breaches, error: breachesError, mutate } = useQuery( - emailAddresses.length > 0 - ? supabase.from("accounts_breaches").select(`account, breach:breach_id(raw_content)`).in("account", emailAddresses) - : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - }, - ) - - const formattedData = emailAddresses.map((email: string) => ({ - email, - breaches: breaches?.filter((breach: any) => breach.account === email).map((breach: any) => breach.breach.raw_content) || [], - })) - - const isLoading = !emails && !error - - return { - emails: formattedData, - isLoading, - refetch: mutate, - error: error || breachesError, - } -} - diff --git a/flowsint-web/src/lib/hooks/individuals/use-individual.ts b/flowsint-web/src/lib/hooks/individuals/use-individual.ts deleted file mode 100644 index 03d9dcb..0000000 --- a/flowsint-web/src/lib/hooks/individuals/use-individual.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useIndividual(individualId: string | null | undefined) { - const { data: individual, mutate, isLoading, error } = useQuery(Boolean(individualId) ? - supabase - .from('individuals') - .select(` - *, - ip_addresses(*), - phone_numbers(*), - social_accounts(*), - emails(*) - `) - .eq("id", individualId) - .single() : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - return { - individual: individual || null, - isLoading, - refetch: mutate, - error: error - }; -} - diff --git a/flowsint-web/src/lib/hooks/individuals/use-relations.ts b/flowsint-web/src/lib/hooks/individuals/use-relations.ts deleted file mode 100644 index e05c590..0000000 --- a/flowsint-web/src/lib/hooks/individuals/use-relations.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useRelations(individualId: string | null | undefined) { - const { data: individuals, mutate, isLoading, error } = useQuery( - Boolean(individualId) - ? supabase - .from("relationships") - .select(` - id, - individual_a(id, full_name, image_url), - individual_b(id, full_name, image_url), - relation_type, - confidence_level - `) - .or(`individual_a.eq.${individualId},individual_b.eq.${individualId}`) - : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - const relations = individuals - ? individuals.map((rel: { individual_a: any, individual_b: any, relation_type: string }) => { - return rel.individual_a?.id === individualId - ? { ...rel.individual_b, relation_type: rel.relation_type } - : { ...rel.individual_a, relation_type: rel.relation_type } - }).filter(Boolean) - : []; - return { - relations, - isLoading, - refetch: mutate, - error - }; -} diff --git a/flowsint-web/src/lib/hooks/investigation/investigation.ts b/flowsint-web/src/lib/hooks/investigation/investigation.ts deleted file mode 100644 index 78df521..0000000 --- a/flowsint-web/src/lib/hooks/investigation/investigation.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useInvestigations(project_id: string) { - const { data: investigations, count, mutate, isLoading, error } = useQuery( - supabase - .from('investigations') - .select('id, title, description') - .eq("project_id", project_id) - .order("last_updated_at", { ascending: false }), - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - - return { investigations, count, isLoading, refetch: mutate, error }; -} - -export function useInvestigation(investigationId: string | string[] | undefined) { - if (!investigationId) return { investigation: null } - const { data: investigation, mutate, isLoading, error } = useQuery( - supabase - .from('investigations') - .select('id, title, description') - .eq("id", investigationId) - .single(), - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - return { investigation: investigation ?? null, isLoading, refetch: mutate, error }; -} \ No newline at end of file diff --git a/flowsint-web/src/lib/hooks/investigation/use-emails.tsx b/flowsint-web/src/lib/hooks/investigation/use-emails.tsx deleted file mode 100644 index 872b70b..0000000 --- a/flowsint-web/src/lib/hooks/investigation/use-emails.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useEmails(investigationId: string | null | undefined) { - const { data: emails, mutate, isLoading, error } = useQuery(Boolean(investigationId) ? - supabase - .from('emails') - .select(` - * - `) - .eq("investigation_id", investigationId) - : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - return { - emails: emails || null, - isLoading, - refetch: mutate, - error: error - }; -} - diff --git a/flowsint-web/src/lib/hooks/investigation/use-individuals.tsx b/flowsint-web/src/lib/hooks/investigation/use-individuals.tsx deleted file mode 100644 index e74a1cb..0000000 --- a/flowsint-web/src/lib/hooks/investigation/use-individuals.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useIndividuals(investigationId: string | null | undefined) { - const { data: individuals, mutate, isLoading, error } = useQuery(Boolean(investigationId) ? - supabase - .from('individuals') - .select(` - * - `) - .eq("investigation_id", investigationId) - : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - return { - individuals: individuals || null, - isLoading, - refetch: mutate, - error: error - }; -} - diff --git a/flowsint-web/src/lib/hooks/investigation/use-phones.tsx b/flowsint-web/src/lib/hooks/investigation/use-phones.tsx deleted file mode 100644 index 36cc49d..0000000 --- a/flowsint-web/src/lib/hooks/investigation/use-phones.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function usePhones(investigationId: string | null | undefined) { - const { data: phones, mutate, isLoading, error } = useQuery(Boolean(investigationId) ? - supabase - .from('phone_numbers') - .select(` - * - `) - .eq("investigation_id", investigationId) - : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - return { - phones: phones || null, - isLoading, - refetch: mutate, - error: error - }; -} - diff --git a/flowsint-web/src/lib/hooks/investigation/use-search-results.tsx b/flowsint-web/src/lib/hooks/investigation/use-search-results.tsx deleted file mode 100644 index 56bc29b..0000000 --- a/flowsint-web/src/lib/hooks/investigation/use-search-results.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useSearchResults(search: string | undefined, investigationId: string | string[] | undefined) { - const { data: results, count, mutate, isLoading, error } = useQuery(search ? - supabase - .from('individuals') - .select('*') - .eq("investigation_id", investigationId) - .ilike('full_name', `%${search}%`) : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - if (error) throw error - - return { results, count, isLoading, refetch: mutate, error }; -} \ No newline at end of file diff --git a/flowsint-web/src/lib/hooks/investigation/use-socials.ts b/flowsint-web/src/lib/hooks/investigation/use-socials.ts deleted file mode 100644 index f3afe6a..0000000 --- a/flowsint-web/src/lib/hooks/investigation/use-socials.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useSocials(investigationId: string | null | undefined) { - const { data: socials, mutate, isLoading, error } = useQuery(Boolean(investigationId) ? - supabase - .from('social_accounts') - .select(` - * - `) - .eq("investigation_id", investigationId) - : null, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - return { - socials: socials || null, - isLoading, - refetch: mutate, - error: error - }; -} - diff --git a/flowsint-web/src/lib/hooks/investigation/usernames.tsx b/flowsint-web/src/lib/hooks/investigation/usernames.tsx deleted file mode 100644 index 6d383c9..0000000 --- a/flowsint-web/src/lib/hooks/investigation/usernames.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { supabase } from "@/lib/supabase/client"; -import { useQuery } from "@supabase-cache-helpers/postgrest-swr"; - -export function useUsernames(investigationId: string | string[] | undefined) { - if (!investigationId) return { usernames: [] } - const { data: usernames, count, mutate, isLoading, error } = useQuery( - supabase - .from('social_accounts') - .select('id, username') - .eq("investigation_id", investigationId) - .not('username', 'is', null) - .neq('username', ''), - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - } - ); - if (error) throw error - - return { usernames, count, isLoading, refetch: mutate, error }; -} \ No newline at end of file diff --git a/flowsint-web/src/lib/hooks/use-local-storage.ts b/flowsint-web/src/lib/hooks/use-local-storage.ts deleted file mode 100644 index ee49f09..0000000 --- a/flowsint-web/src/lib/hooks/use-local-storage.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; - -export default function useLocalStorage(key: string, initialValue: T): [T, Dispatch>] { - const [storedValue, setStoredValue] = useState(initialValue); - const [firstLoadDone, setFirstLoadDone] = useState(false); - - useEffect(() => { - const fromLocal = () => { - if (typeof window === 'undefined') { - return initialValue; - } - try { - const item = window.localStorage.getItem(key); - return item ? JSON.parse(item) as T : initialValue; - } catch (error) { - console.error(error); - return initialValue; - } - }; - - // Only set stored value if it hasn't been set yet (on initial load) - if (!firstLoadDone) { - setStoredValue(fromLocal()); - setFirstLoadDone(true); - } - }, [firstLoadDone, initialValue, key]); // Only run when first load is done, initialValue, or key change - - useEffect(() => { - - if (!firstLoadDone) return; - - try { - if (typeof window !== 'undefined') { - window.localStorage.setItem(key, JSON.stringify(storedValue)); - } - } catch (error) { - console.log(error); - } - }, [storedValue, firstLoadDone, key]); // Update localStorage when storedValue changes - - return [storedValue, setStoredValue]; -} \ No newline at end of file diff --git a/flowsint-web/src/lib/hooks/use-platform-icons.tsx b/flowsint-web/src/lib/hooks/use-platform-icons.tsx deleted file mode 100644 index e0485c0..0000000 --- a/flowsint-web/src/lib/hooks/use-platform-icons.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { useMemo } from "react" -import { CameraIcon, FacebookIcon, GithubIcon, InstagramIcon, MessageCircleDashedIcon, SendIcon } from 'lucide-react'; - -export const usePlatformIcons = (size = "small") => { - const className = size === "small" ? 'h-3 w-3' : 'h-5 w-5' - const platformsIcons = useMemo(() => ({ - "facebook": { - icon: , color: "indigo" - }, - "instagram": { - icon: , color: "plum" - }, - "telegram": { - icon: , color: "cyan" - }, - "signal": { - icon: , color: "blue" - }, - "snapchat": { - icon: , color: "yellow" - }, - "github": { - icon: , color: "gray" - }, - }), []) - return platformsIcons -} \ No newline at end of file diff --git a/flowsint-web/src/lib/supabase/client.ts b/flowsint-web/src/lib/supabase/client.ts deleted file mode 100644 index e823222..0000000 --- a/flowsint-web/src/lib/supabase/client.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { createBrowserClient } from '@supabase/ssr' - -if (!process.env.NEXT_PUBLIC_SUPABASE_URL || !process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) { - throw new Error('Missing Supabase environment variables'); -} - -export const supabase = createBrowserClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) \ No newline at end of file diff --git a/flowsint-web/src/lib/supabase/middleware.ts b/flowsint-web/src/lib/supabase/middleware.ts deleted file mode 100644 index 21a5df1..0000000 --- a/flowsint-web/src/lib/supabase/middleware.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { createServerClient } from '@supabase/ssr' -import { NextResponse, type NextRequest } from 'next/server' - -export async function updateSession(request: NextRequest) { - let supabaseResponse = NextResponse.next({ - request, - }) - const supabase = createServerClient( - process.env.NEXT_PUBLIC_DOCKER_SUPABASE_URL!, - process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, - { - cookies: { - getAll() { - return request.cookies.getAll() - }, - setAll(cookiesToSet) { - cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value)) - supabaseResponse = NextResponse.next({ - request, - }) - cookiesToSet.forEach(({ name, value, options }) => - supabaseResponse.cookies.set(name, value, options) - ) - }, - }, - } - ) - - // Do not run code between createServerClient and - // supabase.auth.getUser(). A simple mistake could make it very hard to debug - // issues with users being randomly logged out. - - // IMPORTANT: DO NOT REMOVE auth.getUser() - - const { - data: { user }, - } = await supabase.auth.getUser() - - if ( - !user && - !request.nextUrl.pathname.startsWith('/login') && - !request.nextUrl.pathname.startsWith('/auth') && - !request.nextUrl.pathname.startsWith('/api') - ) { - // no user, potentially respond by redirecting the user to the login page - const url = request.nextUrl.clone() - url.pathname = '/login' - return NextResponse.redirect(url) - } - - // IMPORTANT: You *must* return the supabaseResponse object as it is. - // If you're creating a new response object with NextResponse.next() make sure to: - // 1. Pass the request in it, like so: - // const myNewResponse = NextResponse.next({ request }) - // 2. Copy over the cookies, like so: - // myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll()) - // 3. Change the myNewResponse object to fit your needs, but avoid changing - // the cookies! - // 4. Finally: - // return myNewResponse - // If this is not done, you may be causing the browser and server to go out - // of sync and terminate the user's session prematurely! - - return supabaseResponse -} \ No newline at end of file diff --git a/flowsint-web/src/lib/supabase/server.ts b/flowsint-web/src/lib/supabase/server.ts deleted file mode 100644 index cbbb6d7..0000000 --- a/flowsint-web/src/lib/supabase/server.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createServerClient } from '@supabase/ssr' -import { cookies } from 'next/headers' - -export async function createClient() { - const cookieStore = await cookies() - const supabaseToken = cookieStore.get('sb-token')?.value - - return createServerClient( - process.env.NEXT_PUBLIC_DOCKER_SUPABASE_URL!, - process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, - { - auth: { - persistSession: false, - // Add the token if it exists - ...(supabaseToken && { - autoRefreshToken: false, - detectSessionInUrl: false, - storage: { - getItem: () => supabaseToken, - setItem: () => { }, - removeItem: () => { }, - }, - }), - }, - cookies: { - getAll() { - return cookieStore.getAll() - }, - setAll(cookiesToSet) { - try { - cookiesToSet.forEach(({ name, value, options }) => - cookieStore.set(name, value, options) - ) - } catch { - // The `setAll` method was called from a Server Component. - // This can be ignored if you have middleware refreshing - // user sessions. - } - }, - }, - } - ) -} \ No newline at end of file diff --git a/flowsint-web/src/lib/utils.ts b/flowsint-web/src/lib/utils.ts deleted file mode 100644 index c2d4678..0000000 --- a/flowsint-web/src/lib/utils.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { clsx, type ClassValue } from "clsx" -import { twMerge } from "tailwind-merge" -//@ts-ignore -import * as d3 from "d3-force" - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} - -export const zoomSelector = (s: { transform: number[]; }) => s.transform[2] >= 0.6; - -import { Position, MarkerType } from '@xyflow/react'; -import { AppNode } from "@/store/flow-store"; - -// this helper function returns the intersection point -// of the line between the center of the intersectionNode and the target node -function getNodeIntersection(intersectionNode: { measured: { width: any; height: any; }; internals: { positionAbsolute: any; }; }, targetNode: { internals: { positionAbsolute: any; }; measured: { width: number; height: number; }; }) { - // https://math.stackexchange.com/questions/1724792/an-algorithm-for-finding-the-intersection-point-between-a-center-of-vision-and-a - const { width: intersectionNodeWidth, height: intersectionNodeHeight } = - intersectionNode.measured; - const intersectionNodePosition = intersectionNode.internals.positionAbsolute; - const targetPosition = targetNode.internals.positionAbsolute; - - const w = intersectionNodeWidth / 2; - const h = intersectionNodeHeight / 2; - - const x2 = intersectionNodePosition.x + w; - const y2 = intersectionNodePosition.y + h; - const x1 = targetPosition.x + targetNode.measured.width / 2; - const y1 = targetPosition.y + targetNode.measured.height / 2; - - const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h); - const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h); - const a = 1 / (Math.abs(xx1) + Math.abs(yy1)); - const xx3 = a * xx1; - const yy3 = a * yy1; - const x = w * (xx3 + yy3) + x2; - const y = h * (-xx3 + yy3) + y2; - - return { x, y }; -} - -// returns the position (top,right,bottom or right) passed node compared to the intersection point -function getEdgePosition(node: { internals: { positionAbsolute: any; }; }, intersectionPoint: { x: any; y: any; }) { - const n = { ...node.internals.positionAbsolute, ...node }; - const nx = Math.round(n.x); - const ny = Math.round(n.y); - const px = Math.round(intersectionPoint.x); - const py = Math.round(intersectionPoint.y); - - if (px <= nx + 1) { - return Position.Left; - } - if (px >= nx + n.measured.width - 1) { - return Position.Right; - } - if (py <= ny + 1) { - return Position.Top; - } - if (py >= n.y + n.measured.height - 1) { - return Position.Bottom; - } - - return Position.Top; -} - -// returns the parameters (sx, sy, tx, ty, sourcePos, targetPos) you need to create an edge -export function getEdgeParams(source: any, target: any) { - const sourceIntersectionPoint = getNodeIntersection(source, target); - const targetIntersectionPoint = getNodeIntersection(target, source); - - const sourcePos = getEdgePosition(source, sourceIntersectionPoint); - const targetPos = getEdgePosition(target, targetIntersectionPoint); - - return { - sx: sourceIntersectionPoint.x, - sy: sourceIntersectionPoint.y, - tx: targetIntersectionPoint.x, - ty: targetIntersectionPoint.y, - sourcePos, - targetPos, - }; -} - -export function initialElements() { - const nodes = []; - const edges = []; - const center = { x: window.innerWidth / 2, y: window.innerHeight / 2 }; - - nodes.push({ id: 'target', data: { label: 'Target' }, position: center }); - - for (let i = 0; i < 8; i++) { - const degrees = i * (360 / 8); - const radians = degrees * (Math.PI / 180); - const x = 250 * Math.cos(radians) + center.x; - const y = 250 * Math.sin(radians) + center.y; - - nodes.push({ id: `${i}`, data: { label: 'Source' }, position: { x, y } }); - - edges.push({ - id: `edge-${i}`, - target: 'target', - source: `${i}`, - type: 'floating', - markerEnd: { - type: MarkerType.Arrow, - }, - }); - } - - return { nodes, edges }; -} - -interface Node { - id: string - position?: { x: number; y: number } - measured?: { width: number; height: number } - [key: string]: any -} - -interface Edge { - source: string - target: string - [key: string]: any -} - -interface LayoutOptions { - direction?: string - strength?: number - distance?: number - iterations?: number -} - -export const getLayoutedElements = ( - nodes: AppNode[], - edges: Edge[], - options: LayoutOptions = { - direction: "LR", - strength: -300, - distance: 100, - iterations: 300, - }, -) => { - // Create a map of node IDs to indices for the simulation - const nodeMap = new Map(nodes.map((node, i) => [node.id, i])) - - // Create a copy of nodes with positions for the simulation - const nodesCopy = nodes.map((node) => ({ - ...node, - x: node.position?.x || Math.random() * 500, - y: node.position?.y || Math.random() * 500, - width: node.measured?.width || 0, - height: node.measured?.height || 0, - })) - - // Create links for the simulation using indices - const links = edges.map((edge) => ({ - source: nodeMap.get(edge.source), - target: nodeMap.get(edge.target), - original: edge, - })) - - // Create the simulation - const simulation = d3 - .forceSimulation(nodesCopy) - .force( - "link", - d3.forceLink(links).id((d: any) => nodeMap.get(d.id)), - ) - .force("charge", d3.forceManyBody().strength(options.strength || -300)) - .force("center", d3.forceCenter(250, 250)) - .force( - "collision", - d3.forceCollide().radius((d: any) => Math.max(d.width, d.height) / 2 + 10), - ) - - // If direction is horizontal, adjust forces - if (options.direction === "LR") { - simulation.force("x", d3.forceX(250).strength(0.1)) - simulation.force("y", d3.forceY(250).strength(0.05)) - } else { - simulation.force("x", d3.forceX(250).strength(0.05)) - simulation.force("y", d3.forceY(250).strength(0.1)) - } - - // Run the simulation synchronously - simulation.stop() - for (let i = 0; i < (options.iterations || 300); i++) { - simulation.tick() - } - - // Update node positions based on simulation results - const updatedNodes = nodesCopy.map((node) => ({ - ...node, - position: { - x: node.x - node.width / 2, - y: node.y - node.height / 2, - }, - })) - - return { - nodes: updatedNodes, - edges, - } -} - - -export const sanitize = (name: string) => { - return name - .normalize("NFKD") // Decompose special characters (e.g., accents) - .replace(/[\u0300-\u036f]/g, "") // Remove accent marks - .replace(/[^a-zA-Z0-9.\-_]/g, "_") // Replace invalid characters with underscores - .replace(/_{2,}/g, "_") // Replace multiple underscores with a single one - .replace(/^_|_$/g, "") // Trim leading or trailing underscores - .toLowerCase(); // Convert to lowercase for consistency -}; - -export const formatFileSize = (bytes: number) => { - if (bytes < 1024) return bytes + " B" - else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + " KB" - else return (bytes / 1048576).toFixed(1) + " MB" -} - -export const nodesTypes = { - emails: { table: "emails", type: "email", fields: ["email"] }, - individuals: { table: "individuals", type: "individual", fields: ["full_name"] }, - phone_numbers: { table: "phone_numbers", type: "phone", fields: ["phone_number"] }, - ip_addresses: { table: "ip_addresses", type: "ip", fields: ["ip_address"] }, - social_accounts_facebook: { - table: "social_accounts", - type: "social", - fields: ["profile_url", "username", "platform:facebook"], - }, - social_accounts_instagram: { - table: "social_accounts", - type: "social", - fields: ["profile_url", "username", "platform:instagram"], - }, - social_accounts_telegram: { - table: "social_accounts", - type: "social", - fields: ["profile_url", "username", "platform:telegram"], - }, - social_accounts_snapchat: { - table: "social_accounts", - type: "social", - fields: ["profile_url", "username", "platform:snapchat"], - }, - social_accounts_signal: { - table: "social_accounts", - type: "social", - fields: ["profile_url", "username", "platform:signal"], - }, - social_accounts_github: { - table: "social_accounts", - type: "social", - fields: ["profile_url", "username", "platform:github"], - }, - physical_addresses: { table: "physical_addresses", type: "address", fields: ["address", "city", "country", "zip"] }, -} \ No newline at end of file