fix(dashboard): use verified custom domain for view-as-student handoff (#677)
* fix(dashboard): use verified custom domain for view-as-student handoff Prefer the org's verified custom domain over window.location.origin when resolving the public tenant host. This prevents admin URLs like app.example.com from being used for the student login-link handoff when the org's public site is example.com. Co-authored-by: Rotimi Best <[email protected]> * fix(dashboard): keep self-hosted org origin on window.location Self-hosted deployments serve admin and LMS from the same URL, so getOrgPublicOrigin should always return window.location.origin there rather than preferring a configured custom domain. Co-authored-by: Rotimi Best <[email protected]> --------- Co-authored-by: Cursor Agent <[email protected]> Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
Cursor Agent
parent
0a6db37566
commit
5320f1eb44
@@ -1,7 +1,9 @@
|
|||||||
|
import { get } from 'svelte/store';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
import { snackbar } from '$features/ui/snackbar/store';
|
import { snackbar } from '$features/ui/snackbar/store';
|
||||||
import { accountApi } from '$features/account/api/account.svelte';
|
import { accountApi } from '$features/account/api/account.svelte';
|
||||||
|
import { currentOrg, getOrgPublicOrigin } from '$lib/utils/store/org';
|
||||||
|
|
||||||
interface OpenCoursePreviewOptions {
|
interface OpenCoursePreviewOptions {
|
||||||
courseId: string;
|
courseId: string;
|
||||||
@@ -21,7 +23,7 @@ export function getPublicCoursePageUrl(courseSlug: string, currentOrgDomain = ''
|
|||||||
}
|
}
|
||||||
|
|
||||||
const trimmedDomain = currentOrgDomain?.trim();
|
const trimmedDomain = currentOrgDomain?.trim();
|
||||||
const origin = trimmedDomain || window.location.origin;
|
const origin = trimmedDomain || getOrgPublicOrigin(get(currentOrg));
|
||||||
|
|
||||||
return new URL(resolve(`/course/${courseSlug}`, {}), origin).toString();
|
return new URL(resolve(`/course/${courseSlug}`, {}), origin).toString();
|
||||||
}
|
}
|
||||||
@@ -73,7 +75,7 @@ export async function viewAsStudent({ courseId, currentOrgDomain = '' }: ViewAsS
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const origin = currentOrgDomain?.trim() || window.location.origin;
|
const origin = currentOrgDomain?.trim() || getOrgPublicOrigin(get(currentOrg));
|
||||||
const loginLinkUrl = new URL('/api/auth/login-link', origin);
|
const loginLinkUrl = new URL('/api/auth/login-link', origin);
|
||||||
loginLinkUrl.searchParams.set('token', token);
|
loginLinkUrl.searchParams.set('token', token);
|
||||||
loginLinkUrl.searchParams.set('redirect', `/courses/${courseId}/lessons?next=true`);
|
loginLinkUrl.searchParams.set('redirect', `/courses/${courseId}/lessons?next=true`);
|
||||||
|
|||||||
@@ -77,19 +77,34 @@ export const currentOrgPath = derived(currentOrg, ($currentOrg) =>
|
|||||||
$currentOrg.siteName ? `/org/${$currentOrg.siteName}` : '#'
|
$currentOrg.siteName ? `/org/${$currentOrg.siteName}` : '#'
|
||||||
);
|
);
|
||||||
|
|
||||||
export const currentOrgDomain = derived(currentOrg, ($currentOrg) => {
|
type OrgPublicOrigin = Pick<AccountOrg, 'customDomain' | 'isCustomDomainVerified' | 'siteName'>;
|
||||||
if (PUBLIC_IS_SELFHOSTED === 'true') return window.location.origin;
|
|
||||||
|
|
||||||
const browserOrigin = dev && browser && window.location.origin;
|
/**
|
||||||
|
* Public origin for an org's tenant site (student LMS, public course pages, login-link handoff).
|
||||||
|
* Self-hosted uses the current deployment URL. On cloud, verified custom domains win over the
|
||||||
|
* admin host so `app.classroomio.com` still hands off to the org's `example.com` tenant site.
|
||||||
|
*/
|
||||||
|
export function getOrgPublicOrigin(org: OrgPublicOrigin): string {
|
||||||
|
if (PUBLIC_IS_SELFHOSTED === 'true') {
|
||||||
|
return browser ? window.location.origin : '';
|
||||||
|
}
|
||||||
|
|
||||||
return browserOrigin
|
if (org.customDomain && org.isCustomDomainVerified) {
|
||||||
? browserOrigin
|
return `https://${org.customDomain}`;
|
||||||
: $currentOrg.customDomain && $currentOrg.isCustomDomainVerified
|
}
|
||||||
? `https://${$currentOrg.customDomain}`
|
|
||||||
: $currentOrg.siteName
|
if (dev && browser) {
|
||||||
? `https://${$currentOrg.siteName}.${TENANT_ROOT_DOMAIN}`
|
return window.location.origin;
|
||||||
: '';
|
}
|
||||||
});
|
|
||||||
|
if (org.siteName) {
|
||||||
|
return `https://${org.siteName}.${TENANT_ROOT_DOMAIN}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return browser ? window.location.origin : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const currentOrgDomain = derived(currentOrg, ($currentOrg) => getOrgPublicOrigin($currentOrg));
|
||||||
|
|
||||||
export const isFreePlan = derived(currentOrg, ($currentOrg) => {
|
export const isFreePlan = derived(currentOrg, ($currentOrg) => {
|
||||||
if (!$currentOrg.id || PUBLIC_IS_SELFHOSTED === 'true') return false;
|
if (!$currentOrg.id || PUBLIC_IS_SELFHOSTED === 'true') return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user