feat: migrate auth from supabase to better auth (#596)
* feat: add README for @cio/db package and remove existingAccounts.json * load session, load profile and organization, add create profile hook * chore: cache session request The trick was passing all the cookies to the backend. Previously I was only passing the better-auth.session_token and not better-auth.session_data. Read about the difference here https://www.better-auth.com/docs/concepts/cookies#custom-cookies * feat: login, logout, onboarding, verify email, reset password. * feat: complete change email and email verification * feat: standardise how we make rpc calls and create org endpoints * fix ui errors * fix: handle potential undefined customerId and standardize avatar URL property * refactor: standardize custom domain handling and update telegram chat ID references * chore: add tailwind prefix to @cio/ui this fixed the media query issues because @cio/ui classes were overriding this dashboard tailwind build * chore: clean up org sidebar * chore: persist mode state * feat: implement order breadcrumbs * chore: upgrade to better auth 1.4 * chore: address common auth flow bugs and setup app for others to setup locally.
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import type { OnboardingField, OnboardingStep } from '../utils/types';
|
||||
import { currentOrg, orgs } from '$lib/utils/store/org';
|
||||
|
||||
import { ONBOARDING_STEPS } from '../utils/constants';
|
||||
import { BaseApiWithErrors, classroomio } from '$lib/utils/services/api';
|
||||
import { goto } from '$app/navigation';
|
||||
import { handleLocaleChange } from '$lib/utils/functions/translations';
|
||||
import { onboardingValidation } from '../utils/validations';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { resolve } from '$app/paths';
|
||||
import { snackbar } from '$lib/components/Snackbar/store';
|
||||
|
||||
export class OnboardingApi extends BaseApiWithErrors {
|
||||
step: OnboardingStep = $state(ONBOARDING_STEPS.ORG_SETUP);
|
||||
|
||||
async submit(data: OnboardingField) {
|
||||
if (this.step === ONBOARDING_STEPS.ORG_SETUP) {
|
||||
return this.submitOrgSetup(data);
|
||||
}
|
||||
|
||||
if (this.step === ONBOARDING_STEPS.USER_METADATA) {
|
||||
return this.submitUserMetada(data);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async submitOrgSetup(data: OnboardingField) {
|
||||
const errors = onboardingValidation(data, ONBOARDING_STEPS.ORG_SETUP);
|
||||
if (errors) {
|
||||
this.errors = errors;
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.execute<typeof classroomio.onboarding.step1.$post>({
|
||||
requestFn: () => classroomio.onboarding.step1.$post({ json: data }),
|
||||
logContext: 'submitting organization setup',
|
||||
onSuccess: (result) => {
|
||||
const { organizations } = result.data;
|
||||
|
||||
orgs.set(organizations);
|
||||
currentOrg.set(organizations[0]);
|
||||
|
||||
this.errors = {};
|
||||
this.step = ONBOARDING_STEPS.USER_METADATA;
|
||||
},
|
||||
onError: (result) => {
|
||||
if (typeof result === 'string') {
|
||||
snackbar.error(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if ('message' in result) {
|
||||
snackbar.error(result.message);
|
||||
return;
|
||||
}
|
||||
|
||||
// map api validation back to frontend fields
|
||||
if ('error' in result) {
|
||||
this.handleValidationError(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async submitUserMetada(data: OnboardingField) {
|
||||
const errors = onboardingValidation(data, ONBOARDING_STEPS.USER_METADATA);
|
||||
if (errors) {
|
||||
this.errors = errors;
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.execute<typeof classroomio.onboarding.step2.$post>({
|
||||
requestFn: () => classroomio.onboarding.step2.$post({ json: data }),
|
||||
logContext: 'submitting organization setup',
|
||||
onSuccess: (result) => {
|
||||
profile.set(result.data);
|
||||
handleLocaleChange(result.data.locale ?? 'en');
|
||||
|
||||
const welcomePopup = `${result.data.isEmailVerified}`;
|
||||
|
||||
return goto(resolve(`/org/${data.siteName}?welcomePopup=${welcomePopup}`, {}));
|
||||
},
|
||||
onError: (result) => {
|
||||
if (typeof result === 'string') {
|
||||
snackbar.error(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if ('message' in result) {
|
||||
snackbar.error(result.message);
|
||||
return;
|
||||
}
|
||||
|
||||
// map api validation back to frontend fields
|
||||
if ('error' in result) {
|
||||
this.handleValidationError(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
override reset() {
|
||||
super.reset();
|
||||
}
|
||||
}
|
||||
|
||||
export const onboardingApi = new OnboardingApi();
|
||||
Reference in New Issue
Block a user