mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
fix(core): update proxy guard middleware (#963)
update proxy guard middleware
This commit is contained in:
parent
70d34c49c8
commit
909535f4af
2 changed files with 35 additions and 36 deletions
|
@ -3,7 +3,7 @@ import { Provider } from 'oidc-provider';
|
||||||
import { MountedApps } from '@/env-set';
|
import { MountedApps } from '@/env-set';
|
||||||
import { createContextWithRouteParameters } from '@/utils/test-utils';
|
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.mock('fs/promises', () => ({
|
||||||
...jest.requireActual('fs/promises'),
|
...jest.requireActual('fs/promises'),
|
||||||
|
@ -44,16 +44,7 @@ describe('koaProxyGuard', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should not redirect if session found', async () => {
|
it(`should not redirect for path ${sessionNotFoundPath}`, 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 () => {
|
|
||||||
const provider = new Provider('');
|
const provider = new Provider('');
|
||||||
|
|
||||||
(provider.interactionDetails as jest.Mock).mockRejectedValue(new Error('session not found'));
|
(provider.interactionDetails as jest.Mock).mockRejectedValue(new Error('session not found'));
|
||||||
|
@ -64,14 +55,37 @@ describe('koaProxyGuard', () => {
|
||||||
expect(ctx.redirect).not.toBeCalled();
|
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('');
|
const provider = new Provider('');
|
||||||
|
|
||||||
(provider.interactionDetails as jest.Mock).mockRejectedValue(new Error('session not found'));
|
(provider.interactionDetails as jest.Mock).mockRejectedValue(new Error('session not found'));
|
||||||
const ctx = createContextWithRouteParameters({
|
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);
|
await koaProxyGuard(provider)(ctx, next);
|
||||||
expect(ctx.redirect).toBeCalled();
|
expect(ctx.redirect).toBeCalled();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import fs from 'fs/promises';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
import { MiddlewareType } from 'koa';
|
import { MiddlewareType } from 'koa';
|
||||||
import { IRouterParamContext } from 'koa-router';
|
import { IRouterParamContext } from 'koa-router';
|
||||||
import { Provider } from 'oidc-provider';
|
import { Provider } from 'oidc-provider';
|
||||||
|
|
||||||
import { MountedApps } from '@/env-set';
|
import { MountedApps } from '@/env-set';
|
||||||
import { fromRoot } from '@/env-set/parameters';
|
|
||||||
|
|
||||||
|
// Need To Align With UI
|
||||||
export const sessionNotFoundPath = '/unknown-session';
|
export const sessionNotFoundPath = '/unknown-session';
|
||||||
|
export const guardedPath = ['/sign-in', '/register', '/social-register'];
|
||||||
|
|
||||||
export default function koaSpaSessionGuard<
|
export default function koaSpaSessionGuard<
|
||||||
StateT,
|
StateT,
|
||||||
|
@ -17,8 +15,6 @@ export default function koaSpaSessionGuard<
|
||||||
>(provider: Provider): MiddlewareType<StateT, ContextT, ResponseBodyT> {
|
>(provider: Provider): MiddlewareType<StateT, ContextT, ResponseBodyT> {
|
||||||
return async (ctx, next) => {
|
return async (ctx, next) => {
|
||||||
const requestPath = ctx.request.path;
|
const requestPath = ctx.request.path;
|
||||||
const packagesPath = fromRoot ? 'packages/' : '..';
|
|
||||||
const clientPath = path.join(packagesPath, 'ui', 'dist');
|
|
||||||
|
|
||||||
// Empty path Redirect
|
// Empty path Redirect
|
||||||
if (requestPath === '/') {
|
if (requestPath === '/') {
|
||||||
|
@ -27,22 +23,11 @@ export default function koaSpaSessionGuard<
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check client routes session status only
|
// Session guard
|
||||||
if (Object.values(MountedApps).some((app) => requestPath.startsWith(`/${app}`))) {
|
if (guardedPath.some((path) => requestPath.startsWith(path))) {
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client session guard
|
|
||||||
try {
|
try {
|
||||||
await provider.interactionDetails(ctx.req, ctx.res);
|
await provider.interactionDetails(ctx.req, ctx.res);
|
||||||
} catch {
|
} 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);
|
ctx.redirect(sessionNotFoundPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue