mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 09:36:44 +00:00
fix: Put static types files behind authentication (#18660)
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import type { GlobalConfig } from '@n8n/config';
|
||||
import type { InvalidAuthTokenRepository, UserRepository } from '@n8n/db';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
|
||||
import { AuthService } from '@/auth/auth.service';
|
||||
import type { MfaService } from '@/mfa/mfa.service';
|
||||
import type { JwtService } from '@/services/jwt.service';
|
||||
import type { UrlService } from '@/services/url.service';
|
||||
|
||||
describe('AuthService Browser ID Whitelist', () => {
|
||||
let authService: AuthService;
|
||||
|
||||
beforeEach(() => {
|
||||
const globalConfig = mock<GlobalConfig>({
|
||||
endpoints: { rest: 'rest' },
|
||||
});
|
||||
const jwtService = mock<JwtService>();
|
||||
const urlService = mock<UrlService>();
|
||||
const userRepository = mock<UserRepository>();
|
||||
const invalidAuthTokenRepository = mock<InvalidAuthTokenRepository>();
|
||||
const mfaService = mock<MfaService>();
|
||||
|
||||
authService = new AuthService(
|
||||
globalConfig,
|
||||
mock(),
|
||||
mock(),
|
||||
jwtService,
|
||||
urlService,
|
||||
userRepository,
|
||||
invalidAuthTokenRepository,
|
||||
mfaService,
|
||||
);
|
||||
});
|
||||
|
||||
describe('skipBrowserIdCheckEndpoints', () => {
|
||||
it('should include type files in the skip browser ID check endpoints', () => {
|
||||
// Access the private property for testing
|
||||
const skipEndpoints = (authService as any).skipBrowserIdCheckEndpoints;
|
||||
|
||||
expect(skipEndpoints).toContain('/types/nodes.json');
|
||||
expect(skipEndpoints).toContain('/types/credentials.json');
|
||||
});
|
||||
|
||||
it('should include oauth callback urls in the skip browser ID check endpoints', () => {
|
||||
// Access the private property for testing
|
||||
const skipEndpoints = (authService as any).skipBrowserIdCheckEndpoints;
|
||||
|
||||
expect(skipEndpoints).toContain('/rest/oauth1-credential/callback');
|
||||
expect(skipEndpoints).toContain('/rest/oauth2-credential/callback');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -65,6 +65,10 @@ export class AuthService {
|
||||
// oAuth callback urls aren't called by the frontend. therefore we can't send custom header on these requests
|
||||
`/${restEndpoint}/oauth1-credential/callback`,
|
||||
`/${restEndpoint}/oauth2-credential/callback`,
|
||||
|
||||
// Skip browser ID check for type files
|
||||
'/types/nodes.json',
|
||||
'/types/credentials.json',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import { jsonParse } from 'n8n-workflow';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { AbstractServer } from '@/abstract-server';
|
||||
import { AuthService } from '@/auth/auth.service';
|
||||
import config from '@/config';
|
||||
import { CLI_DIR, EDITOR_UI_DIST_DIR, inE2ETests } from '@/constants';
|
||||
import { ControllerRegistry } from '@/controller.registry';
|
||||
@@ -318,6 +319,23 @@ export class Server extends AbstractServer {
|
||||
const maxAge = Time.days.toMilliseconds;
|
||||
const cacheOptions = inE2ETests || inDevelopment ? {} : { maxAge };
|
||||
const { staticCacheDir } = Container.get(InstanceSettings);
|
||||
|
||||
// Protect type files with authentication regardless of UI availability
|
||||
const authService = Container.get(AuthService);
|
||||
const protectedTypeFiles = ['/types/nodes.json', '/types/credentials.json'];
|
||||
protectedTypeFiles.forEach((path) => {
|
||||
this.app.get(
|
||||
path,
|
||||
authService.createAuthMiddleware(true),
|
||||
async (_, res: express.Response) => {
|
||||
res.setHeader('Cache-Control', 'no-cache, must-revalidate');
|
||||
res.sendFile(path.substring(1), {
|
||||
root: staticCacheDir,
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
if (frontendService) {
|
||||
this.app.use(
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user