mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
fix(core): Block Public API related REST calls when Public API is not enabled (#9521)
This commit is contained in:
parent
e07de837b9
commit
ac4e0fbb47
|
@ -153,11 +153,6 @@ export const loadPublicApiVersions = async (
|
|||
};
|
||||
};
|
||||
|
||||
function isApiEnabledByLicense(): boolean {
|
||||
const license = Container.get(License);
|
||||
return !license.isAPIDisabled();
|
||||
}
|
||||
|
||||
export function isApiEnabled(): boolean {
|
||||
return !config.get('publicApi.disabled') && isApiEnabledByLicense();
|
||||
return !config.get('publicApi.disabled') && !Container.get(License).isAPIDisabled();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import validator from 'validator';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { Response } from 'express';
|
||||
import { type RequestHandler, Response } from 'express';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
import { AuthService } from '@/auth/auth.service';
|
||||
|
@ -22,6 +22,15 @@ import { ExternalHooks } from '@/ExternalHooks';
|
|||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||
import { isApiEnabled } from '@/PublicApi';
|
||||
|
||||
export const isApiEnabledMiddleware: RequestHandler = (_, res, next) => {
|
||||
if (isApiEnabled()) {
|
||||
next();
|
||||
} else {
|
||||
res.status(404).end();
|
||||
}
|
||||
};
|
||||
|
||||
@RestController('/me')
|
||||
export class MeController {
|
||||
|
@ -185,7 +194,7 @@ export class MeController {
|
|||
/**
|
||||
* Creates an API Key
|
||||
*/
|
||||
@Post('/api-key')
|
||||
@Post('/api-key', { middlewares: [isApiEnabledMiddleware] })
|
||||
async createAPIKey(req: AuthenticatedRequest) {
|
||||
const apiKey = `n8n_api_${randomBytes(40).toString('hex')}`;
|
||||
|
||||
|
@ -202,7 +211,7 @@ export class MeController {
|
|||
/**
|
||||
* Get an API Key
|
||||
*/
|
||||
@Get('/api-key')
|
||||
@Get('/api-key', { middlewares: [isApiEnabledMiddleware] })
|
||||
async getAPIKey(req: AuthenticatedRequest) {
|
||||
return { apiKey: req.user.apiKey };
|
||||
}
|
||||
|
@ -210,7 +219,7 @@ export class MeController {
|
|||
/**
|
||||
* Deletes an API Key
|
||||
*/
|
||||
@Delete('/api-key')
|
||||
@Delete('/api-key', { middlewares: [isApiEnabledMiddleware] })
|
||||
async deleteAPIKey(req: AuthenticatedRequest) {
|
||||
await this.userService.update(req.user.id, { apiKey: null });
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import type { CommunityPackagesService } from '@/services/communityPackages.serv
|
|||
import { Logger } from '@/Logger';
|
||||
import { UrlService } from './url.service';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { isApiEnabled } from '@/PublicApi';
|
||||
|
||||
@Service()
|
||||
export class FrontendService {
|
||||
|
@ -143,7 +144,7 @@ export class FrontendService {
|
|||
},
|
||||
},
|
||||
publicApi: {
|
||||
enabled: !config.get('publicApi.disabled') && !this.license.isAPIDisabled(),
|
||||
enabled: isApiEnabled(),
|
||||
latestVersion: 1,
|
||||
path: config.getEnv('publicApi.path'),
|
||||
swaggerUi: {
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import { Container } from 'typedi';
|
||||
import type { SuperAgentTest } from 'supertest';
|
||||
import { IsNull } from '@n8n/typeorm';
|
||||
import validator from 'validator';
|
||||
|
||||
import type { User } from '@db/entities/User';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { ProjectRepository } from '@db/repositories/project.repository';
|
||||
|
||||
import { SUCCESS_RESPONSE_BODY } from './shared/constants';
|
||||
import {
|
||||
randomApiKey,
|
||||
|
@ -12,15 +17,38 @@ import {
|
|||
} from './shared/random';
|
||||
import * as testDb from './shared/testDb';
|
||||
import * as utils from './shared/utils/';
|
||||
import { addApiKey, createUser, createUserShell } from './shared/db/users';
|
||||
import Container from 'typedi';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||
import { addApiKey, createOwner, createUser, createUserShell } from './shared/db/users';
|
||||
import config from '@/config';
|
||||
|
||||
const testServer = utils.setupTestServer({ endpointGroups: ['me'] });
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User']);
|
||||
config.set('publicApi.disabled', false);
|
||||
});
|
||||
|
||||
describe('When public API is disabled', () => {
|
||||
let owner: User;
|
||||
let authAgent: SuperAgentTest;
|
||||
|
||||
beforeEach(async () => {
|
||||
owner = await createOwner();
|
||||
await addApiKey(owner);
|
||||
authAgent = testServer.authAgentFor(owner);
|
||||
config.set('publicApi.disabled', true);
|
||||
});
|
||||
|
||||
test('POST /me/api-key should 404', async () => {
|
||||
await authAgent.post('/me/api-key').expect(404);
|
||||
});
|
||||
|
||||
test('GET /me/api-key should 404', async () => {
|
||||
await authAgent.get('/me/api-key').expect(404);
|
||||
});
|
||||
|
||||
test('DELETE /me/api-key should 404', async () => {
|
||||
await authAgent.delete('/me/api-key').expect(404);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Owner shell', () => {
|
||||
|
|
Loading…
Reference in a new issue