From b6b897768943855869248e6ec72d6aca3ac5ff8f Mon Sep 17 00:00:00 2001 From: Kyle Baran Date: Fri, 31 May 2024 13:37:16 -0700 Subject: [PATCH] Updated Cloudfront function to pass most things as routes (#10234) Project-defined routes were not being handled properly by the Cloudfront function; the function was not properly handling subroutes of the registered route, e.g. /newroute/subroute would throw a 403 because the CF function didn't know how to handle anything other than /newroute. Rather than make the function conditionally handle subroutes, it was determined that it would be easier to instead have /projects and /recordings paths be passed through as-is, and have everything else that wasn't a static client file be passed as if it were a route, i.e. get directed to client/index.html and let the router there determine what to do with it (or nothing, if it's not a registered route). Co-authored-by: Hanzla Mateen --- packages/client/src/route/public.tsx | 1 - .../src/media/storageprovider/s3.storage.ts | 45 +++++++------------ 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/packages/client/src/route/public.tsx b/packages/client/src/route/public.tsx index 02904d29ef..0d09b03696 100644 --- a/packages/client/src/route/public.tsx +++ b/packages/client/src/route/public.tsx @@ -32,7 +32,6 @@ import { LoadingCircle } from '@etherealengine/client-core/src/components/Loadin const $index = lazy(() => import('@etherealengine/client/src/pages')) const $offline = lazy(() => import('@etherealengine/client/src/pages/offline/offline')) -const $admin = lazy(() => import('@etherealengine/client-core/src/admin/adminRoutes')) const $studio = lazy(() => import('@etherealengine/client/src/pages/editor/editor')) const $location = lazy(() => import('@etherealengine/client/src/pages/location/location')) diff --git a/packages/server-core/src/media/storageprovider/s3.storage.ts b/packages/server-core/src/media/storageprovider/s3.storage.ts index 4a09544a72..7304c49dc6 100755 --- a/packages/server-core/src/media/storageprovider/s3.storage.ts +++ b/packages/server-core/src/media/storageprovider/s3.storage.ts @@ -92,17 +92,21 @@ const MAX_ITEMS = 1 const CFFunctionTemplate = ` function handler(event) { var request = event.request; - var routeRegexRoot = __$routeRegex$__ - var routeRegex = new RegExp(routeRegexRoot) + var projectsRegexRoot = __$projectsRegex$__ + var projectsRegex = new RegExp(projectsRegexRoot) + var recordingsRegexRoot = __$recordingsRegex$__ + var recordingsRegex = new RegExp(recordingsRegexRoot) var publicRegexRoot = __$publicRegex$__ var publicRegex = new RegExp(publicRegexRoot) - - if (routeRegex.test(request.uri)) { - request.uri = '/client/index.html' - } if (publicRegex.test(request.uri)) { request.uri = '/client' + request.uri + } else if (projectsRegex.test(request.uri) || recordingsRegex.test(request.uri)) { + // Projects and recordings paths should be passed as-is + } else { + // Anything that is not a static/public file, or a project or recording file, is assumed to be some sort + // of engine route and passed to index.html to be handled by the router + request.uri = '/client/index.html' } return request; } @@ -484,26 +488,8 @@ export class S3Provider implements StorageProviderInterface { } getFunctionCode(routes: string[]) { - let routeRegex = '' - for (const route of routes) - if (route !== '/') - switch (route) { - case '/admin': - case '/editor': - case '/studio': - routeRegex += `^${route}$$|` // String.replace will convert this to a single $ - routeRegex += `^${route}/|` - break - case '/location': - case '/auth': - case '/capture': - routeRegex += `^${route}/|` - break - default: - routeRegex += `^${route}$$|` // String.replace will convert this to a single $ - break - } - if (routes.length > 0) routeRegex = routeRegex.slice(0, routeRegex.length - 1) + const projectsRegex = '^/projects/' + const recordingsRegex = '^/recordings/' let publicRegex = '' fs.readdirSync(path.join(appRootPath.path, 'packages', 'client', 'dist'), { withFileTypes: true }).forEach( (dirent) => { @@ -520,10 +506,9 @@ export class S3Provider implements StorageProviderInterface { } ) if (publicRegex.length > 0) publicRegex = publicRegex.slice(0, publicRegex.length - 1) - return CFFunctionTemplate.replace('__$routeRegex$__', `'${routeRegex}'`).replace( - '__$publicRegex$__', - `'${publicRegex}'` - ) + return CFFunctionTemplate.replace('__$projectsRegex$__', `'${projectsRegex}'`) + .replace('__$recordingsRegex$__', `'${recordingsRegex}'`) + .replace('__$publicRegex$__', `'${publicRegex}'`) } async createFunction(functionName: string, routes: string[]) {