Skip to content

Commit

Permalink
botcom: redirect to intended room when signing in (tldraw#4725)
Browse files Browse the repository at this point in the history
also, fixes up the not authenticated/forbidden error msg (was always
sending down forbidden accidentally)

### Change type

- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
  • Loading branch information
mimecuvalo authored Oct 21, 2024
1 parent 9894eb4 commit d1ff2ff
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ClerkProvider, useClerk } from '@clerk/clerk-react'

export default function LoginRedirectPage() {
// @ts-ignore this is fine
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

if (!PUBLISHABLE_KEY) {
throw new Error('Missing VITE_CLERK_PUBLISHABLE_KEY in .env.local')
}

return (
<ClerkProvider publishableKey={PUBLISHABLE_KEY}>
<LoginRedirectPageInner />
</ClerkProvider>
)
}

function LoginRedirectPageInner() {
const clerk = useClerk()

const signInUrl = clerk.buildSignInUrl({ signInForceRedirectUrl: window.location.href })
window.location.href = signInUrl

return null
}
10 changes: 7 additions & 3 deletions apps/dotcom/client/src/components/StoreErrorScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { TLRemoteSyncError, TLSyncErrorCloseEventReason } from '@tldraw/sync-core'
import { ErrorPage } from './ErrorPage/ErrorPage'
import LoginRedirectPage from './LoginRedirectPage/LoginRedirectPage'

export function StoreErrorScreen({ error }: { error: Error }) {
let header = 'Could not connect to server.'
let message = ''

if (error instanceof TLRemoteSyncError) {
switch (error.reason) {
case TLSyncErrorCloseEventReason.CLIENT_TOO_OLD: {
Expand Down Expand Up @@ -41,10 +43,12 @@ export function StoreErrorScreen({ error }: { error: Error }) {
message = 'The room you are trying to connect to does not exist.'
break
}
case TLSyncErrorCloseEventReason.NOT_AUTHENTICATED:
case TLSyncErrorCloseEventReason.NOT_AUTHENTICATED: {
return <LoginRedirectPage />
}
case TLSyncErrorCloseEventReason.FORBIDDEN: {
header = 'Unauthorized'
message = 'You need to be authorized to view this room.'
header = 'Forbidden'
message = 'You are forbidden to view this room.'
break
}
default: {
Expand Down
50 changes: 18 additions & 32 deletions apps/dotcom/client/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import {
SNAPSHOT_PREFIX,
} from '@tldraw/dotcom-shared'
import { TLRemoteSyncError, TLSyncErrorCloseEventReason } from '@tldraw/sync-core'
import { useEffect } from 'react'
import { Link, Route, createRoutesFromElements, useRouteError } from 'react-router-dom'
import { Suspense, lazy, useEffect } from 'react'
import { Route, createRoutesFromElements, useRouteError } from 'react-router-dom'
import { DefaultErrorFallback } from './components/DefaultErrorFallback/DefaultErrorFallback'
import { ErrorPage } from './components/ErrorPage/ErrorPage'

const LoginRedirectPage = lazy(() => import('./components/LoginRedirectPage/LoginRedirectPage'))

export const router = createRoutesFromElements(
<Route
ErrorBoundary={() => {
Expand All @@ -19,52 +21,36 @@ export const router = createRoutesFromElements(
captureException(error)
}, [error])

let header = 'Something went wrong'
let para1 =
'Please try refreshing the page. Still having trouble? Let us know at [email protected].'
if (error instanceof TLRemoteSyncError) {
switch (error.reason) {
case TLSyncErrorCloseEventReason.NOT_FOUND: {
return (
<ErrorPage
messages={{
header: 'Not found',
para1: 'The file you are looking for does not exist.',
}}
/>
)
header = 'Not found'
para1 = 'The file you are looking for does not exist.'
break
}
case TLSyncErrorCloseEventReason.NOT_AUTHENTICATED: {
return (
<ErrorPage
messages={{
header: 'Unauthorized',
para1: 'You need to be signed in to view this file.',
}}
/>
<Suspense>
<LoginRedirectPage />
</Suspense>
)
}
case TLSyncErrorCloseEventReason.FORBIDDEN: {
return (
<ErrorPage
messages={{
header: 'Unauthorized',
para1: 'You need to be authorized to view this file.',
}}
cta={
<Link to={'/q'} target={'_self'}>
{'Back to tldraw.'}
</Link>
}
/>
)
header = 'Forbidden'
para1 = 'You are forbidden to view this file.'
break
}
}
}

return (
<ErrorPage
messages={{
header: 'Something went wrong',
para1:
'Please try refreshing the page. Still having trouble? Let us know at [email protected].',
header,
para1,
}}
/>
)
Expand Down
3 changes: 3 additions & 0 deletions apps/dotcom/sync-worker/src/TLDrawDurableObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ export class TLDrawDurableObject extends DurableObject {
const ownerId = await this.getOwnerId()

if (ownerId) {
if (!auth) {
return closeSocket(TLSyncErrorCloseEventReason.NOT_AUTHENTICATED)
}
if (ownerId !== TldrawAppUserRecordType.createId(auth?.userId)) {
const ownerDurableObject = this.env.TLAPP_DO.get(this.env.TLAPP_DO.idFromName(APP_ID))
const shareType = await ownerDurableObject.getFileShareType(
Expand Down
2 changes: 1 addition & 1 deletion packages/sync/src/useSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export function useSync(opts: UseSyncOptions & TLStoreSchemaOptions): RemoteTLSt
track?.(MULTIPLAYER_EVENT_NAME, { name: 'room-not-found', roomId })
break
case TLSyncErrorCloseEventReason.FORBIDDEN:
track?.(MULTIPLAYER_EVENT_NAME, { name: 'not-authorized', roomId })
track?.(MULTIPLAYER_EVENT_NAME, { name: 'forbidden', roomId })
break
case TLSyncErrorCloseEventReason.NOT_AUTHENTICATED:
track?.(MULTIPLAYER_EVENT_NAME, { name: 'not-authenticated', roomId })
Expand Down

0 comments on commit d1ff2ff

Please sign in to comment.