feat: auto enroll into org as student and oauth improvements
This commit is contained in:
+19
-1
@@ -86,7 +86,25 @@ export const app = new Hono()
|
||||
})
|
||||
)
|
||||
.use('/api/auth/sign-up/*', signupGuard)
|
||||
.on(['POST', 'GET'], '/api/auth/*', (c) => auth.handler(c.req.raw))
|
||||
.on(['POST', 'GET'], '/api/auth/*', (c) => {
|
||||
// Behind the Cloudflare Worker proxy the raw Request URL points at the
|
||||
// upstream `.onrender.com` host. Better Auth (and the oauth-proxy plugin)
|
||||
// need the original tenant/admin host to construct correct OAuth callback
|
||||
// URLs and to decide whether to engage the proxy flow. Rebuild from
|
||||
// X-Forwarded-Host / X-Forwarded-Proto when present.
|
||||
let request = c.req.raw;
|
||||
const fwdHost = c.req.header('x-forwarded-host');
|
||||
const fwdProto = c.req.header('x-forwarded-proto');
|
||||
if (fwdHost) {
|
||||
const url = new URL(request.url);
|
||||
url.host = fwdHost;
|
||||
if (fwdProto === 'https' || fwdProto === 'http') {
|
||||
url.protocol = `${fwdProto}:`;
|
||||
}
|
||||
request = new Request(url, request);
|
||||
}
|
||||
return auth.handler(request);
|
||||
})
|
||||
.get('/session', async (c) => {
|
||||
const session = c.get('session');
|
||||
const user = c.get('user');
|
||||
|
||||
@@ -3,6 +3,7 @@ import { getActiveOrganizationPlan, getOrganizationById } from '@cio/db/queries/
|
||||
import { getCourseTagsByCourseIdsForOrganization, getTagGroupsWithTags } from '@cio/db/queries/tag';
|
||||
import { listWidgetCourses } from '@cio/db/queries/widget';
|
||||
import { PLAN } from '@cio/utils/plans';
|
||||
import { TENANT_ROOT_DOMAIN } from '@cio/utils/constants';
|
||||
import {
|
||||
buildWidgetPayload as buildWidgetPayloadShared,
|
||||
normalizeWidgetConfig,
|
||||
@@ -148,7 +149,7 @@ export function getCourseBaseUrl(siteName: string, customDomain?: string | null)
|
||||
return `https://${customDomain}`;
|
||||
}
|
||||
|
||||
return siteName ? `https://${siteName}.classroomio.com` : DEFAULT_WIDGET_APP_BASE_URL;
|
||||
return siteName ? `https://${siteName}.${TENANT_ROOT_DOMAIN}` : DEFAULT_WIDGET_APP_BASE_URL;
|
||||
}
|
||||
|
||||
export function getCourseWidgetScriptUrl(): string {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { newOrgModal } from '../new-org-modal-store';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
import { orgApi } from '$features/org/api/org.svelte';
|
||||
import { TENANT_ROOT_DOMAIN } from '@cio/utils/constants';
|
||||
|
||||
let orgName = $state('');
|
||||
let siteName = $derived(generateSitename(orgName));
|
||||
@@ -52,7 +53,7 @@
|
||||
|
||||
<Field.Field>
|
||||
<Field.Label>{$t('add_org.org_sitename')}</Field.Label>
|
||||
<DomainInput bind:value={siteName} placeholder="myschool" prefix="https://" suffix=".classroomio.com" />
|
||||
<DomainInput bind:value={siteName} placeholder="myschool" prefix="https://" suffix=".{TENANT_ROOT_DOMAIN}" />
|
||||
{#if orgApi.errors.siteName || orgApi.errors.general}
|
||||
<Field.Error>{orgApi.errors.siteName || orgApi.errors.general}</Field.Error>
|
||||
{/if}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import { copyToClipboard } from '$lib/utils/functions/formatYoutubeVideo';
|
||||
import { updateOrgSiteNameValidation } from '$lib/utils/functions/validator';
|
||||
import { sanitizeDomain, sendDomainRequest } from '$lib/utils/functions/domain';
|
||||
import { BRAND_ROOT_DOMAIN, TENANT_ROOT_DOMAIN } from '@cio/utils/constants';
|
||||
|
||||
import { Badge } from '@cio/ui/base/badge';
|
||||
import { Button } from '@cio/ui/base/button';
|
||||
@@ -164,7 +165,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (sanitizedDomain.includes('classroomio.com')) {
|
||||
if (sanitizedDomain.includes(BRAND_ROOT_DOMAIN) || sanitizedDomain.includes(TENANT_ROOT_DOMAIN)) {
|
||||
errors.customDomain = $t('components.settings.domains.custom_domain_not_classroomio');
|
||||
return;
|
||||
}
|
||||
@@ -284,7 +285,7 @@
|
||||
onchange={(e) => (siteName = (e.target as HTMLInputElement)?.value ?? '')}
|
||||
placeholder="myschool"
|
||||
prefix="https://"
|
||||
suffix=".classroomio.com"
|
||||
suffix=".{TENANT_ROOT_DOMAIN}"
|
||||
/>
|
||||
{#if errors.siteName}
|
||||
<Field.Error>{errors.siteName}</Field.Error>
|
||||
|
||||
@@ -4,8 +4,13 @@
|
||||
import { currentOrg } from '$lib/utils/store/org';
|
||||
import { Badge } from '@cio/ui/base/badge';
|
||||
import { PLAN_NAMES, PLAN } from '@cio/utils/plans';
|
||||
import { BRAND_ROOT_DOMAIN, TENANT_ROOT_DOMAIN } from '@cio/utils/constants';
|
||||
|
||||
const plan = $derived($currentOrg.plans?.[0]?.planName || PLAN.BASIC);
|
||||
const utmSource = $derived(
|
||||
$currentOrg.customDomain ||
|
||||
($currentOrg.siteName ? `${$currentOrg.siteName}.${TENANT_ROOT_DOMAIN}` : BRAND_ROOT_DOMAIN)
|
||||
);
|
||||
</script>
|
||||
|
||||
<Sidebar.Menu>
|
||||
@@ -16,7 +21,7 @@
|
||||
>
|
||||
{#snippet child({ props })}
|
||||
<a
|
||||
href="https://classroomio.com?utm_source={$currentOrg.siteName}.classroomio.com"
|
||||
href="https://{BRAND_ROOT_DOMAIN}?utm_source={utmSource}"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
{...props}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script>
|
||||
import { Badge } from '@cio/ui/base/badge';
|
||||
import { TENANT_ROOT_DOMAIN } from '@cio/utils/constants';
|
||||
</script>
|
||||
|
||||
<section id="student-dashboard" class="bg-black px-3 py-[10%] text-center text-white lg:px-0">
|
||||
<Badge class="px-4! py-2! text-sm! underline">yourorg.classroomio.com</Badge>
|
||||
<Badge class="px-4! py-2! text-sm! underline">yourorg.{TENANT_ROOT_DOMAIN}</Badge>
|
||||
<h1 class="mx-auto flex flex-col items-center gap-4 text-3xl leading-[1.5] font-normal md:text-4xl lg:text-6xl">
|
||||
Your Student Dashboard
|
||||
</h1>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<PageHeader className="flex flex-col items-center justify-center bg-[#F5F8FE] text-center pb-8">
|
||||
<PageHeader className="flex flex-col items-center justify-center text-center pb-8">
|
||||
<div class="mb-2 flex w-full items-center justify-center">
|
||||
<span
|
||||
class="rounded-full border-2 border-[#C2D2FF] bg-[#DCE5FF] px-4 py-1 text-sm font-medium text-blue-700"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<PageHeader className="flex flex-col items-center justify-center bg-[#F5F8FE] text-center pb-8">
|
||||
<PageHeader className="flex flex-col items-center justify-center text-center pb-8">
|
||||
<div class="mb-2 flex w-full items-center justify-center">
|
||||
<span
|
||||
class="rounded-full border-2 border-[#C2D2FF] bg-[#DCE5FF] px-4 py-1 text-sm font-medium text-blue-700"
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
class="flex w-full rounded-md border shadow-sm transition-all ease-in-out hover:scale-95 md:max-w-[370px]"
|
||||
>
|
||||
<img class="w-[30%] rounded-l-md" src={tool.src} alt="" />
|
||||
<div class="w-[70%] rounded-r-md bg-[#F5F8FE] p-5">
|
||||
<div class="w-[70%] rounded-r-md p-5">
|
||||
<h1 class="text-sm md:text-base">{tool.title}</h1>
|
||||
<p class="mt-1.5 text-xs text-gray-600">
|
||||
{tool.subText}
|
||||
|
||||
Reference in New Issue
Block a user