0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

fix(core): fix custom UI not triggered bug (#6563)

fix custom UI not triggered on legacy-experience bug
This commit is contained in:
simeng-li 2024-09-10 14:37:01 +08:00 committed by GitHub
parent fae8725a44
commit 862d27dee4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 26 deletions

View file

@ -1,3 +1,5 @@
import path from 'node:path';
import { pickDefault, createMockUtils } from '@logto/shared/esm';
import Sinon from 'sinon';
@ -12,13 +14,14 @@ const mockProxyMiddleware = jest.fn();
const mockStaticMiddleware = jest.fn();
const mockCustomUiAssetsMiddleware = jest.fn();
const mountedApps = Object.values(UserApps);
const mockStaticMiddlewareFactory = jest.fn(() => mockStaticMiddleware);
mockEsmDefault('node:fs/promises', () => ({
readdir: jest.fn().mockResolvedValue(['sign-in']),
}));
mockEsmDefault('koa-proxies', () => jest.fn(() => mockProxyMiddleware));
mockEsmDefault('#src/middleware/koa-serve-static.js', () => jest.fn(() => mockStaticMiddleware));
mockEsmDefault('#src/middleware/koa-serve-static.js', () => mockStaticMiddlewareFactory);
mockEsmDefault('#src/middleware/koa-serve-custom-ui-assets.js', () =>
jest.fn(() => mockCustomUiAssetsMiddleware)
);
@ -83,32 +86,49 @@ describe('koaSpaProxy middleware', () => {
stub.restore();
});
it('production env should call the static middleware if path hit the ui file directory', async () => {
const stub = Sinon.stub(EnvSet, 'values').value({
...EnvSet.values,
isProduction: true,
});
it.each([true, false])(
'production env should call the proxy middleware if path does not hit the ui file directory: devFeatureEnabled %p',
async (isDevFeaturesEnabled) => {
const stub = Sinon.stub(EnvSet, 'values').value({
...EnvSet.values,
isProduction: true,
isDevFeaturesEnabled,
});
const ctx = createContextWithRouteParameters({
url: '/sign-in',
});
const ctx = createContextWithRouteParameters({
url: '/sign-in',
});
await koaSpaProxy({ mountedApps, queries })(ctx, next);
expect(mockStaticMiddleware).toBeCalled();
stub.restore();
});
await koaSpaProxy({ mountedApps, queries })(ctx, next);
it('should serve custom UI assets if user uploaded them', async () => {
const customUiAssets = { id: 'custom-ui-assets', createdAt: Date.now() };
mockFindDefaultSignInExperience.mockResolvedValue({ customUiAssets });
const packagePath = isDevFeaturesEnabled ? 'experience' : 'experience-legacy';
const distributionPath = path.join('node_modules/@logto', packagePath, 'dist');
const ctx = createContextWithRouteParameters({
url: '/sign-in',
});
expect(mockStaticMiddlewareFactory).toBeCalledWith(distributionPath);
stub.restore();
}
);
await koaSpaProxy({ mountedApps, queries })(ctx, next);
expect(mockCustomUiAssetsMiddleware).toBeCalled();
expect(mockStaticMiddleware).not.toBeCalled();
expect(mockProxyMiddleware).not.toBeCalled();
});
it.each([true, false])(
'should serve custom UI assets if user uploaded them: : devFeatureEnabled %p',
async (isDevFeaturesEnabled) => {
const stub = Sinon.stub(EnvSet, 'values').value({
...EnvSet.values,
isDevFeaturesEnabled,
});
const customUiAssets = { id: 'custom-ui-assets', createdAt: Date.now() };
mockFindDefaultSignInExperience.mockResolvedValue({ customUiAssets });
const ctx = createContextWithRouteParameters({
url: '/sign-in',
});
await koaSpaProxy({ mountedApps, queries })(ctx, next);
expect(mockCustomUiAssetsMiddleware).toBeCalled();
expect(mockStaticMiddleware).not.toBeCalled();
expect(mockProxyMiddleware).not.toBeCalled();
stub.restore();
}
);
});

View file

@ -20,16 +20,27 @@ type Properties = {
readonly prefix?: string;
};
const getDistributionPath = (packagePath: string) => {
if (packagePath === 'experience') {
// Use the new experience package if dev features are enabled
const moduleName = EnvSet.values.isDevFeaturesEnabled ? 'experience' : 'experience-legacy';
return path.join('node_modules/@logto', moduleName, 'dist');
}
return path.join('node_modules/@logto', packagePath, 'dist');
};
export default function koaSpaProxy<StateT, ContextT extends IRouterParamContext, ResponseBodyT>({
mountedApps,
packagePath = EnvSet.values.isDevFeaturesEnabled ? 'experience' : 'experience-legacy',
packagePath = 'experience',
port = 5001,
prefix = '',
queries,
}: Properties): MiddlewareType<StateT, ContextT, ResponseBodyT> {
type Middleware = MiddlewareType<StateT, ContextT, ResponseBodyT>;
const distributionPath = path.join('node_modules/@logto', packagePath, 'dist');
const distributionPath = getDistributionPath(packagePath);
const spaProxy: Middleware = EnvSet.values.isProduction
? serveStatic(distributionPath)
@ -58,6 +69,7 @@ export default function koaSpaProxy<StateT, ContextT extends IRouterParamContext
}
const { customUiAssets } = await queries.signInExperiences.findDefaultSignInExperience();
// If user has uploaded custom UI assets, serve them instead of native experience UI
if (customUiAssets && packagePath === 'experience') {
const serve = serveCustomUiAssets(customUiAssets.id);