diff --git a/apps/dashboard/src/lib/features/course/utils/course-preview.ts b/apps/dashboard/src/lib/features/course/utils/course-preview.ts index a32a6f9e..023be090 100644 --- a/apps/dashboard/src/lib/features/course/utils/course-preview.ts +++ b/apps/dashboard/src/lib/features/course/utils/course-preview.ts @@ -1,7 +1,9 @@ +import { get } from 'svelte/store'; import { goto } from '$app/navigation'; import { resolve } from '$app/paths'; import { snackbar } from '$features/ui/snackbar/store'; import { accountApi } from '$features/account/api/account.svelte'; +import { currentOrg, getOrgPublicOrigin } from '$lib/utils/store/org'; interface OpenCoursePreviewOptions { courseId: string; @@ -21,7 +23,7 @@ export function getPublicCoursePageUrl(courseSlug: string, currentOrgDomain = '' } const trimmedDomain = currentOrgDomain?.trim(); - const origin = trimmedDomain || window.location.origin; + const origin = trimmedDomain || getOrgPublicOrigin(get(currentOrg)); return new URL(resolve(`/course/${courseSlug}`, {}), origin).toString(); } @@ -73,7 +75,7 @@ export async function viewAsStudent({ courseId, currentOrgDomain = '' }: ViewAsS 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); loginLinkUrl.searchParams.set('token', token); loginLinkUrl.searchParams.set('redirect', `/courses/${courseId}/lessons?next=true`); diff --git a/apps/dashboard/src/lib/utils/store/org.ts b/apps/dashboard/src/lib/utils/store/org.ts index 2c5f758d..2fdf0349 100644 --- a/apps/dashboard/src/lib/utils/store/org.ts +++ b/apps/dashboard/src/lib/utils/store/org.ts @@ -77,19 +77,34 @@ export const currentOrgPath = derived(currentOrg, ($currentOrg) => $currentOrg.siteName ? `/org/${$currentOrg.siteName}` : '#' ); -export const currentOrgDomain = derived(currentOrg, ($currentOrg) => { - if (PUBLIC_IS_SELFHOSTED === 'true') return window.location.origin; +type OrgPublicOrigin = Pick; - 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 - ? browserOrigin - : $currentOrg.customDomain && $currentOrg.isCustomDomainVerified - ? `https://${$currentOrg.customDomain}` - : $currentOrg.siteName - ? `https://${$currentOrg.siteName}.${TENANT_ROOT_DOMAIN}` - : ''; -}); + if (org.customDomain && org.isCustomDomainVerified) { + return `https://${org.customDomain}`; + } + + if (dev && browser) { + 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) => { if (!$currentOrg.id || PUBLIC_IS_SELFHOSTED === 'true') return false;