0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -05:00

fix(core): update proxy guard middleware (#963)

update proxy guard middleware
This commit is contained in:
simeng-li 2022-05-26 16:54:40 +08:00 committed by GitHub
parent 70d34c49c8
commit 909535f4af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 36 deletions

View file

@ -3,7 +3,7 @@ import { Provider } from 'oidc-provider';
import { MountedApps } from '@/env-set';
import { createContextWithRouteParameters } from '@/utils/test-utils';
import koaProxyGuard, { sessionNotFoundPath } from './koa-proxy-guard';
import koaProxyGuard, { sessionNotFoundPath, guardedPath } from './koa-proxy-guard';
jest.mock('fs/promises', () => ({
...jest.requireActual('fs/promises'),
@ -44,16 +44,7 @@ describe('koaProxyGuard', () => {
});
}
it('should not redirect if session found', async () => {
const provider = new Provider('');
const ctx = createContextWithRouteParameters({
url: `/sign-in`,
});
await koaProxyGuard(provider)(ctx, next);
expect(ctx.redirect).not.toBeCalled();
});
it('should not redirect if path is sessionNotFoundPath', async () => {
it(`should not redirect for path ${sessionNotFoundPath}`, async () => {
const provider = new Provider('');
(provider.interactionDetails as jest.Mock).mockRejectedValue(new Error('session not found'));
@ -64,14 +55,37 @@ describe('koaProxyGuard', () => {
expect(ctx.redirect).not.toBeCalled();
});
it('should redirect if session not found', async () => {
it(`should not redirect for path /callback`, async () => {
const provider = new Provider('');
(provider.interactionDetails as jest.Mock).mockRejectedValue(new Error('session not found'));
const ctx = createContextWithRouteParameters({
url: '/sign-in',
url: '/callback/github',
});
await koaProxyGuard(provider)(ctx, next);
expect(ctx.redirect).not.toBeCalled();
});
it('should not redirect if session found', async () => {
const provider = new Provider('');
const ctx = createContextWithRouteParameters({
url: `/sign-in`,
});
await koaProxyGuard(provider)(ctx, next);
expect(ctx.redirect).not.toBeCalled();
});
for (const path of guardedPath) {
// eslint-disable-next-line @typescript-eslint/no-loop-func
it(`should redirect if session not found for ${path}`, async () => {
const provider = new Provider('');
(provider.interactionDetails as jest.Mock).mockRejectedValue(new Error('session not found'));
const ctx = createContextWithRouteParameters({
url: `${path}/foo`,
});
await koaProxyGuard(provider)(ctx, next);
expect(ctx.redirect).toBeCalled();
});
}
});

View file

@ -1,14 +1,12 @@
import fs from 'fs/promises';
import path from 'path';
import { MiddlewareType } from 'koa';
import { IRouterParamContext } from 'koa-router';
import { Provider } from 'oidc-provider';
import { MountedApps } from '@/env-set';
import { fromRoot } from '@/env-set/parameters';
// Need To Align With UI
export const sessionNotFoundPath = '/unknown-session';
export const guardedPath = ['/sign-in', '/register', '/social-register'];
export default function koaSpaSessionGuard<
StateT,
@ -17,8 +15,6 @@ export default function koaSpaSessionGuard<
>(provider: Provider): MiddlewareType<StateT, ContextT, ResponseBodyT> {
return async (ctx, next) => {
const requestPath = ctx.request.path;
const packagesPath = fromRoot ? 'packages/' : '..';
const clientPath = path.join(packagesPath, 'ui', 'dist');
// Empty path Redirect
if (requestPath === '/') {
@ -27,22 +23,11 @@ export default function koaSpaSessionGuard<
return next();
}
// Check client routes session status only
if (Object.values(MountedApps).some((app) => requestPath.startsWith(`/${app}`))) {
return next();
}
// Client session guard
// Session guard
if (guardedPath.some((path) => requestPath.startsWith(path))) {
try {
await provider.interactionDetails(ctx.req, ctx.res);
} catch {
const spaDistFiles = await fs.readdir(clientPath);
if (
!spaDistFiles.some((file) => requestPath.startsWith('/' + file)) &&
!ctx.request.path.endsWith(sessionNotFoundPath) &&
!ctx.request.URL.searchParams.get('preview') // Should not check session on preview mode
) {
ctx.redirect(sessionNotFoundPath);
}
}