From 6584a216e5a7d5f2a45822be6bfcb91c35cc2252 Mon Sep 17 00:00:00 2001 From: David Luecke Date: Mon, 14 Jun 2021 11:48:05 -0700 Subject: [PATCH] fix(core): Add list of protected methods that can not be used for custom methods (#2390) --- packages/feathers/src/application.ts | 8 +++++++- packages/feathers/src/service.ts | 13 +++++++++++- packages/feathers/test/application.test.ts | 23 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/feathers/src/application.ts b/packages/feathers/src/application.ts index dc95cf9f58..3daeaa4aef 100644 --- a/packages/feathers/src/application.ts +++ b/packages/feathers/src/application.ts @@ -4,7 +4,7 @@ import { } from './dependencies'; import { eventHook, eventMixin } from './events'; import { hookMixin } from './hooks/index'; -import { wrapService, getServiceOptions } from './service'; +import { wrapService, getServiceOptions, protectedMethods } from './service'; import { FeathersApplication, ServiceMixin, @@ -95,6 +95,12 @@ export class Feathers extends EventEmitter implements const protoService = wrapService(location, service, options); const serviceOptions = getServiceOptions(service, options); + for (const name of protectedMethods) { + if (serviceOptions.methods.includes(name)) { + throw new Error(`'${name}' on service '${location}' is not allowed as a custom method name`); + } + } + debug(`Registering new service at \`${location}\``); // Add all the mixins diff --git a/packages/feathers/src/service.ts b/packages/feathers/src/service.ts index e6bcfa91df..c9bfd021d2 100644 --- a/packages/feathers/src/service.ts +++ b/packages/feathers/src/service.ts @@ -1,4 +1,4 @@ -import { createSymbol } from './dependencies'; +import { createSymbol, EventEmitter } from './dependencies'; import { ServiceOptions } from './declarations'; export const SERVICE = createSymbol('@feathersjs/service'); @@ -21,6 +21,17 @@ export const defaultEventMap = { remove: 'removed' } +export const protectedMethods = Object.keys(Object.prototype) + .concat(Object.keys(EventEmitter.prototype)) + .concat([ + 'before', + 'after', + 'error', + 'hooks', + 'setup', + 'publish' + ]); + export function getHookMethods (service: any, options: ServiceOptions) { const { methods } = options; diff --git a/packages/feathers/test/application.test.ts b/packages/feathers/test/application.test.ts index 9a9bd13ec0..cdd7cee139 100644 --- a/packages/feathers/test/application.test.ts +++ b/packages/feathers/test/application.test.ts @@ -106,6 +106,29 @@ describe('Feathers application', () => { assert.strictEqual(data.message, 'Test message'); }); + it('can not register custom methods on a protected methods', async () => { + const dummyService = { + async create (data: any) { + return data; + }, + async removeListener (data: any) { + return data; + }, + async setup () {} + }; + + assert.throws(() => feathers().use('/dummy', dummyService, { + methods: ['create', 'removeListener'] + }), { + message: '\'removeListener\' on service \'dummy\' is not allowed as a custom method name' + }); + assert.throws(() => feathers().use('/dummy', dummyService, { + methods: ['create', 'setup'] + }), { + message: '\'setup\' on service \'dummy\' is not allowed as a custom method name' + }); + }); + it('can use a root level service', async () => { const app = feathers().use('/', { async get (id: string) {