feat: improve signup middleware by adding email normalization, invite-only handling, and organization context checks for self-hosted instances
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
import { currentOrg } from '$lib/utils/store/org';
|
||||
import { authClient } from '$lib/utils/services/auth/client';
|
||||
import { page } from '$app/state';
|
||||
import { resolve } from '$app/paths';
|
||||
import { capturePosthogEvent } from '$lib/utils/services/posthog';
|
||||
import { globalStore } from '$lib/utils/store/app';
|
||||
import * as Field from '@cio/ui/base/field';
|
||||
@@ -15,7 +16,10 @@
|
||||
import { ssoApi } from '$features/org/api/sso.svelte';
|
||||
import ShieldIcon from '@lucide/svelte/icons/shield';
|
||||
|
||||
let fields = $state(Object.assign({}, LOGIN_FIELDS));
|
||||
const emailFromUrl = page.url.searchParams.get('email') ?? '';
|
||||
|
||||
let fields = $state(Object.assign({}, LOGIN_FIELDS, emailFromUrl ? { email: emailFromUrl } : {}));
|
||||
|
||||
let submitError: string | undefined = $state();
|
||||
let loading = $state(false);
|
||||
let errors = $state(Object.assign({}, LOGIN_FIELDS));
|
||||
@@ -165,8 +169,9 @@
|
||||
console.log('data', data);
|
||||
|
||||
if (error) throw error;
|
||||
} catch (error: any) {
|
||||
submitError = error.error_description || error.message;
|
||||
} catch (error) {
|
||||
const err = error as { error_description?: string; message?: string };
|
||||
submitError = err?.error_description ?? err?.message ?? '';
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
@@ -241,7 +246,7 @@
|
||||
<Field.Field>
|
||||
<div class="ui:flex ui:items-center ui:justify-between">
|
||||
<Field.Label for="password">{$t('login.password')}</Field.Label>
|
||||
<a class="ui:text-sm ui:text-primary ui:hover:underline" href="/forgot">
|
||||
<a class="ui:text-sm ui:text-primary ui:hover:underline" href={resolve('/forgot', {})}>
|
||||
{$t('login.forgot')}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
import { resolve } from '$app/paths';
|
||||
|
||||
let { data } = $props();
|
||||
let fields = $state(Object.assign({}, SIGNUP_FIELDS));
|
||||
const emailFromUrl = page.url.searchParams.get('email') ?? '';
|
||||
let fields = $state(Object.assign({}, SIGNUP_FIELDS, emailFromUrl ? { email: emailFromUrl } : {}));
|
||||
let loading = $state(false);
|
||||
let errors: {
|
||||
email?: string;
|
||||
@@ -34,11 +35,6 @@
|
||||
// Use org from store or layout data (layout data ensures org is available on self-hosted before store is set)
|
||||
const org = $derived($currentOrg?.id ? $currentOrg : (data.org ?? $currentOrg));
|
||||
|
||||
$effect(() => {
|
||||
console.log('data', data);
|
||||
console.log('org', org);
|
||||
});
|
||||
|
||||
// Invite context: allow signup when invite_token present or redirect contains invite info
|
||||
const hasInviteContext = $derived(
|
||||
!!inviteToken || (!!redirectUrl && (redirectUrl.includes('/invite/t/') || redirectUrl.includes('invite_token')))
|
||||
@@ -75,8 +71,9 @@
|
||||
loading = true;
|
||||
const name = fields.email.split('@')[0];
|
||||
|
||||
// Use org from store or layout data; required for self-hosted when orgs exist
|
||||
const orgId = org?.id;
|
||||
// if in selfhosted instance always pass org id
|
||||
// if in cloud instance, ONLY pass when on subdomain i.e student experience
|
||||
const headers = $globalStore.isOrgSite ? { 'cio-org-id': org.id } : undefined;
|
||||
|
||||
const { error } = await authClient.signUp.email(
|
||||
{
|
||||
@@ -85,9 +82,7 @@
|
||||
name: name
|
||||
},
|
||||
{
|
||||
fetchOptions: {
|
||||
headers: { 'cio-org-id': orgId }
|
||||
},
|
||||
headers,
|
||||
onSuccess: (ctx) => {
|
||||
console.log('Signup successful');
|
||||
capturePosthogEvent('user_signed_up', {
|
||||
|
||||
Reference in New Issue
Block a user