2025-09-10 16:50:31 +01:00
|
|
|
import { currentOrg, currentOrgDomain } from '$lib/utils/store/org';
|
2024-12-26 07:23:46 +01:00
|
|
|
import { identifyPosthogUser, initPosthog } from '$lib/utils/services/posthog';
|
|
|
|
|
import { initSentry, setSentryUser } from '$lib/utils/services/sentry';
|
|
|
|
|
import { profile, user } from '$lib/utils/store/user';
|
2025-09-10 16:50:31 +01:00
|
|
|
|
|
|
|
|
import { ROLE } from '$lib/utils/constants/roles';
|
|
|
|
|
import { ROUTE } from '$lib/utils/constants/routes';
|
|
|
|
|
import { dev } from '$app/environment';
|
2024-12-26 07:23:46 +01:00
|
|
|
import { get } from 'svelte/store';
|
2025-09-10 16:50:31 +01:00
|
|
|
import { getOrganizations } from '$lib/utils/services/org';
|
|
|
|
|
import { goto } from '$app/navigation';
|
|
|
|
|
import { handleLocaleChange } from '$lib/utils/functions/translations';
|
|
|
|
|
import isEmpty from 'lodash/isEmpty';
|
|
|
|
|
import isPublicRoute from '$lib/utils/functions/routes/isPublicRoute';
|
|
|
|
|
import { page } from '$app/stores';
|
|
|
|
|
import { setTheme } from '$lib/utils/functions/theme';
|
|
|
|
|
import shouldRedirectOnAuth from '$lib/utils/functions/routes/shouldRedirectOnAuth';
|
|
|
|
|
import { supabase } from '$lib/utils/functions/supabase';
|
2024-12-26 07:23:46 +01:00
|
|
|
|
|
|
|
|
export function setupAnalytics() {
|
|
|
|
|
// Set up sentry
|
|
|
|
|
initSentry();
|
|
|
|
|
|
|
|
|
|
// Set up posthog
|
|
|
|
|
initPosthog();
|
|
|
|
|
|
|
|
|
|
// Disable umami on localhost
|
|
|
|
|
if (dev) {
|
|
|
|
|
localStorage.setItem('umami.disabled', '1');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setAnalyticsUser() {
|
|
|
|
|
const profileStore = get(profile);
|
|
|
|
|
|
|
|
|
|
if (!profileStore.id) return;
|
|
|
|
|
|
|
|
|
|
setSentryUser({
|
|
|
|
|
id: profileStore.id,
|
|
|
|
|
username: profileStore.username,
|
|
|
|
|
email: profileStore.email,
|
|
|
|
|
fullname: profileStore.fullname
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
identifyPosthogUser(profileStore.id, {
|
|
|
|
|
email: profileStore.email,
|
|
|
|
|
name: profileStore.fullname
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getProfile({
|
|
|
|
|
path,
|
|
|
|
|
queryParam,
|
|
|
|
|
isOrgSite,
|
|
|
|
|
orgSiteName
|
|
|
|
|
}: {
|
|
|
|
|
path: string;
|
|
|
|
|
queryParam: string;
|
|
|
|
|
isOrgSite: boolean;
|
|
|
|
|
orgSiteName: string;
|
|
|
|
|
}) {
|
|
|
|
|
const pageStore = get(page);
|
|
|
|
|
const profileStore = get(profile);
|
|
|
|
|
const currentOrgStore = get(currentOrg);
|
|
|
|
|
const currentOrgDomainStore = get(currentOrgDomain);
|
|
|
|
|
|
|
|
|
|
const params = new URLSearchParams(window.location.search);
|
|
|
|
|
// Get user profile
|
|
|
|
|
const {
|
|
|
|
|
data: { session }
|
|
|
|
|
} = await supabase.auth.getSession();
|
|
|
|
|
const { user: authUser } = session || {};
|
|
|
|
|
console.log('Get user', authUser);
|
|
|
|
|
|
|
|
|
|
if (!authUser && !isPublicRoute(pageStore.url?.pathname)) {
|
|
|
|
|
return goto('/login?redirect=/' + path + queryParam);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Skip refetching profile, if already in store
|
2024-12-28 23:11:55 +01:00
|
|
|
if (profileStore.id) {
|
|
|
|
|
handleLocaleChange(profileStore.locale);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-12-26 07:23:46 +01:00
|
|
|
|
|
|
|
|
// Check if user has profile
|
|
|
|
|
let {
|
|
|
|
|
data: profileData,
|
|
|
|
|
error,
|
|
|
|
|
status
|
2025-09-10 16:50:31 +01:00
|
|
|
} = await supabase.from('profile').select(`*`).eq('id', authUser?.id).single();
|
2024-12-26 07:23:46 +01:00
|
|
|
console.log('Get profile', profileData);
|
|
|
|
|
|
|
|
|
|
if (error && !profileData && status === 406 && authUser) {
|
|
|
|
|
// User wasn't found, create profile
|
|
|
|
|
console.log(`User wasn't found, create profile`);
|
|
|
|
|
|
|
|
|
|
const [regexUsernameMatch] = [...(authUser.email?.matchAll(/(.*)@/g) || [])];
|
|
|
|
|
|
|
|
|
|
const isGoogleAuth = !!authUser.app_metadata?.providers?.includes('google');
|
|
|
|
|
|
|
|
|
|
const { data: newProfileData, error } = await supabase
|
|
|
|
|
.from('profile')
|
|
|
|
|
.insert({
|
|
|
|
|
id: authUser.id,
|
|
|
|
|
username: regexUsernameMatch[1] + `${new Date().getTime()}`,
|
|
|
|
|
fullname: regexUsernameMatch[1],
|
|
|
|
|
email: authUser.email,
|
|
|
|
|
is_email_verified: isGoogleAuth,
|
|
|
|
|
verified_at: isGoogleAuth ? new Date().toDateString() : undefined
|
|
|
|
|
})
|
|
|
|
|
.select();
|
|
|
|
|
|
|
|
|
|
// Profile created, go to onboarding or lms
|
|
|
|
|
if (!error && newProfileData) {
|
2025-09-10 16:50:31 +01:00
|
|
|
console.log('newProfileData', newProfileData);
|
2024-12-26 07:23:46 +01:00
|
|
|
user.update((_user) => ({
|
|
|
|
|
..._user,
|
|
|
|
|
fetchingUser: false,
|
|
|
|
|
isLoggedIn: true,
|
|
|
|
|
currentSession: authUser
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
profile.set(newProfileData[0]);
|
|
|
|
|
|
|
|
|
|
setAnalyticsUser();
|
|
|
|
|
|
|
|
|
|
// Fetch language
|
2024-12-28 23:11:55 +01:00
|
|
|
handleLocaleChange(newProfileData[0].locale);
|
2024-12-26 07:23:46 +01:00
|
|
|
|
|
|
|
|
if (isOrgSite) {
|
2025-09-10 16:50:31 +01:00
|
|
|
console.log('isOrgSite', isOrgSite);
|
2024-12-26 07:23:46 +01:00
|
|
|
const { data, error } = await supabase
|
|
|
|
|
.from('organizationmember')
|
|
|
|
|
.insert({
|
|
|
|
|
organization_id: currentOrgStore.id,
|
|
|
|
|
profile_id: profileStore.id,
|
|
|
|
|
role_id: 3
|
|
|
|
|
})
|
|
|
|
|
.select();
|
2025-09-10 16:50:31 +01:00
|
|
|
console.log('data', data);
|
|
|
|
|
console.log('error', error);
|
2024-12-26 07:23:46 +01:00
|
|
|
if (error) {
|
|
|
|
|
console.error('Error adding user to organisation', error);
|
|
|
|
|
} else {
|
|
|
|
|
console.log('Success adding user to organisation', data);
|
|
|
|
|
const memberId = data?.[0]?.id || '';
|
|
|
|
|
|
|
|
|
|
currentOrg.update((_currentOrg) => ({
|
|
|
|
|
..._currentOrg,
|
|
|
|
|
memberId
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (params.get('redirect')) {
|
2025-09-10 16:50:31 +01:00
|
|
|
console.log('redirect', params.get('redirect'));
|
2024-12-26 07:23:46 +01:00
|
|
|
goto(params.get('redirect') || '');
|
|
|
|
|
} else {
|
2025-09-10 16:50:31 +01:00
|
|
|
console.log('redirect', '/lms');
|
2024-12-26 07:23:46 +01:00
|
|
|
goto('/lms');
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// On invite page, don't go to onboarding
|
|
|
|
|
if (!path.includes('invite')) {
|
|
|
|
|
goto(ROUTE.ONBOARDING);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
user.update((_user) => ({
|
|
|
|
|
..._user,
|
|
|
|
|
fetchingUser: false
|
|
|
|
|
}));
|
|
|
|
|
} else if (profileData) {
|
|
|
|
|
// Profile exists, go to profile page
|
|
|
|
|
user.update((_user) => ({
|
|
|
|
|
..._user,
|
|
|
|
|
fetchingUser: false,
|
|
|
|
|
isLoggedIn: true,
|
|
|
|
|
currentSession: authUser
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
profile.set(profileData);
|
|
|
|
|
|
|
|
|
|
// Set user in sentry
|
|
|
|
|
setAnalyticsUser();
|
|
|
|
|
|
2024-12-28 23:11:55 +01:00
|
|
|
handleLocaleChange(profileData.locale);
|
2024-12-26 07:23:46 +01:00
|
|
|
|
|
|
|
|
const orgRes = await getOrganizations(profileData.id, isOrgSite, orgSiteName);
|
|
|
|
|
|
|
|
|
|
const isStudentAccount = orgRes.currentOrg.role_id == ROLE.STUDENT;
|
|
|
|
|
|
|
|
|
|
// student redirect
|
|
|
|
|
if (isOrgSite) {
|
|
|
|
|
if (params.has('redirect')) {
|
|
|
|
|
goto(params.get('redirect') || '');
|
|
|
|
|
} else if (shouldRedirectOnAuth(path)) {
|
|
|
|
|
goto('/lms');
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (isStudentAccount) {
|
|
|
|
|
// Check if the student logged into the dashboard.
|
|
|
|
|
console.log('Student logged into dashboard');
|
|
|
|
|
if (dev) {
|
|
|
|
|
goto('/lms');
|
|
|
|
|
} else {
|
|
|
|
|
window.location.replace(`${currentOrgDomainStore}/lms`);
|
|
|
|
|
}
|
|
|
|
|
} else if (isEmpty(orgRes.orgs) && !path.includes('invite')) {
|
|
|
|
|
// Not on invite page or no org, go to onboarding
|
|
|
|
|
goto(ROUTE.ONBOARDING);
|
|
|
|
|
} else if (params.has('redirect')) {
|
|
|
|
|
goto(params.get('redirect') || '');
|
|
|
|
|
} else if (shouldRedirectOnAuth(path)) {
|
|
|
|
|
// By default redirect to first organization
|
|
|
|
|
goto(`/org/${orgRes.currentOrg.siteName}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setTheme(orgRes?.currentOrg?.theme);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!profileData && !isPublicRoute(pageStore.url?.pathname)) {
|
|
|
|
|
goto('/login?redirect=/' + path);
|
|
|
|
|
}
|
|
|
|
|
}
|