-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use invite page for handling redirects
Signed-off-by: Dinika Saxena <[email protected]>
- Loading branch information
Showing
7 changed files
with
163 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { ErrorBoundary } from 'react-error-boundary'; | ||
|
||
import SimpleErrorComponent from '@/components/GenericErrorFallback'; | ||
import InviteLoader from '@/components/Invites'; | ||
|
||
export default function InvitePage() { | ||
return ( | ||
<ErrorBoundary FallbackComponent={SimpleErrorComponent}> | ||
<InviteLoader /> | ||
</ErrorBoundary> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { captureException } from '@sentry/nextjs'; | ||
|
||
import { InviteResponse } from '@/types/virtual-lab/invites'; | ||
import { VlmError } from '@/types/virtual-lab/common'; | ||
import { virtualLabApi } from '@/config'; | ||
|
||
export const processInvite = async ( | ||
sessionToken: string, | ||
inviteToken: string | ||
): Promise<InviteResponse | VlmError> => { | ||
return fetch(`${virtualLabApi.url}/invites?token=${inviteToken}`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Accept: 'application/json', | ||
Authorization: `Bearer ${sessionToken}`, | ||
}, | ||
}) | ||
.then<InviteResponse | VlmError>((response) => { | ||
// Valid response or client errors (40X) | ||
return response.json(); | ||
}) | ||
.catch((err) => { | ||
// Server errors (50X) | ||
captureException( | ||
new Error(`User could not accept invite ${inviteToken} because of an unknown error`), | ||
{ extra: err } | ||
); | ||
return { error_code: 'INTERNAL_SERVER_ERROR', message: 'Vlm server is down' } as VlmError; | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
'use client'; | ||
|
||
import { LoadingOutlined } from '@ant-design/icons'; | ||
import { Spin } from 'antd'; | ||
import { useAtomValue } from 'jotai'; | ||
import { useRouter, useSearchParams } from 'next/navigation'; | ||
import { useEffect } from 'react'; | ||
import { captureException } from '@sentry/nextjs'; | ||
|
||
import { processInvite } from './api'; | ||
import { getErrorUrl, getLabUrl, getProjectUrl } from './utils'; | ||
import sessionAtom from '@/state/session'; | ||
import { isVlmInviteResponse } from '@/types/virtual-lab/invites'; | ||
|
||
export default function InviteLoader() { | ||
const session = useAtomValue(sessionAtom); | ||
const inviteToken = useSearchParams().get('token'); | ||
const router = useRouter(); | ||
|
||
useEffect(() => { | ||
if (!session?.accessToken) { | ||
return router.push(getErrorUrl(null, session?.accessToken, inviteToken)); | ||
} | ||
if (!inviteToken) { | ||
return router.push(getErrorUrl(null, session?.accessToken, inviteToken)); | ||
} | ||
|
||
processInvite(session.accessToken, inviteToken).then((response) => { | ||
if (!isVlmInviteResponse(response)) { | ||
router.push(getErrorUrl(response, session?.accessToken, inviteToken)); | ||
return; | ||
} | ||
|
||
switch (response.data.origin) { | ||
case 'Lab': | ||
router.push(getLabUrl(response.data)); | ||
return; | ||
case 'Project': | ||
router.push(getProjectUrl(response.data)); | ||
return; | ||
default: | ||
captureException( | ||
new Error( | ||
`User could not accept invite ${inviteToken} because unknown origin returned by server` | ||
), | ||
{ extra: response.data.origin } | ||
); | ||
router.push(getErrorUrl(response, session?.accessToken, inviteToken)); | ||
} | ||
}); | ||
}, [session, inviteToken, router]); | ||
|
||
return ( | ||
<div className="relative flex h-screen w-screen items-center justify-center bg-primary-8"> | ||
<Spin indicator={<LoadingOutlined style={{ color: '#fff', fontSize: 24 }} spin />} /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { captureException } from '@sentry/nextjs'; | ||
|
||
import { InviteData, InviteErrorCodes } from '@/types/virtual-lab/invites'; | ||
import { VlmError, isVlmError } from '@/types/virtual-lab/common'; | ||
|
||
const errorPath = '/'; | ||
const projectPath = (labId: string, projectId: string) => | ||
`/virtual-lab/lab/${labId}/project/${projectId!}/home`; | ||
const labPath = (labId: string) => `/virtual-lab/lab/${labId}/lab`; | ||
|
||
export const getLabUrl = (vlmData: InviteData): string => { | ||
const { status, virtual_lab_id: labId, origin } = vlmData; | ||
if (status === 'already_accepted') { | ||
return `${errorPath}?errorcode=${InviteErrorCodes.INVITE_ALREADY_ACCEPTED}&origin=${origin}&lab_id=${labId}`; | ||
} | ||
|
||
return `${labPath(labId)}?invite_accepted=true`; | ||
}; | ||
|
||
export const getProjectUrl = (vlmData: InviteData): string => { | ||
const { status, virtual_lab_id: labId, project_id: projectId, origin } = vlmData; | ||
if (status === 'already_accepted') { | ||
return `${errorPath}?errorcode=${InviteErrorCodes.INVITE_ALREADY_ACCEPTED}&origin=${origin}&lab_id=${labId}&project_id=${projectId}`; | ||
} | ||
|
||
return `${projectPath(labId, projectId!)}?invite_accepted=true`; | ||
}; | ||
|
||
export const getErrorUrl = ( | ||
response: VlmError | any, | ||
accessToken?: string, | ||
inviteToken?: string | null | ||
): string => { | ||
if (!accessToken) { | ||
return `${errorPath}?errorcode=${InviteErrorCodes.UNAUTHORIZED}`; | ||
} | ||
if (!inviteToken) { | ||
return `${errorPath}?errorcode=${InviteErrorCodes.INVALID_LINK}`; | ||
} | ||
if (isVlmError(response)) { | ||
captureException(new Error(`User invite could not be accepted because of VLM Error`), { | ||
extra: { vliError: response, invite: inviteToken }, | ||
}); | ||
|
||
if (response.error_code === 'AUTHORIZATION_ERROR') { | ||
return `${errorPath}?errorcode=${InviteErrorCodes.UNAUTHORIZED}`; | ||
} | ||
|
||
if (response.error_code === 'TOKEN_EXPIRED') { | ||
return `${errorPath}?errorcode=${InviteErrorCodes.TOKEN_EXPIRED}`; | ||
} | ||
return `${errorPath}?errorcode=${InviteErrorCodes.UNKNOWN}`; | ||
} | ||
|
||
captureException(new Error(`User invite could not be accepted because of Unknown error`), { | ||
extra: { error: response, invite: inviteToken }, | ||
}); | ||
|
||
return `${errorPath}?errorcode=${InviteErrorCodes.UNKNOWN}`; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters