Skip to content

Commit 0b9a6b1

Browse files
authored
fix(transport-commons): Handle invalid service paths on socket lookups (#3242)
1 parent 022a407 commit 0b9a6b1

File tree

4 files changed

+103
-65
lines changed

4 files changed

+103
-65
lines changed

package-lock.json

+22-22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/transport-commons/src/socket/index.ts

+63-39
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ export interface SocketOptions {
1515
getParams: (socket: any) => RealTimeConnection;
1616
}
1717

18-
export function socket ({ done, emit, socketMap, socketKey, getParams }: SocketOptions) {
18+
export function socket ({
19+
done,
20+
emit,
21+
socketMap,
22+
socketKey,
23+
getParams
24+
}: SocketOptions) {
1925
return (app: Application) => {
2026
const leaveChannels = (connection: RealTimeConnection) => {
2127
const { channels } = app;
@@ -39,53 +45,71 @@ export function socket ({ done, emit, socketMap, socketKey, getParams }: SocketO
3945
});
4046

4147
// `connection` event
42-
done.then(provider => provider.on('connection', (connection: any) =>
43-
app.emit('connection', getParams(connection)))
48+
done.then((provider) =>
49+
provider.on('connection', (connection: any) =>
50+
app.emit('connection', getParams(connection))
51+
)
4452
);
4553

4654
// `socket.emit('methodName', 'serviceName', ...args)` handlers
47-
done.then(provider => provider.on('connection', (connection: any) => {
48-
for (const method of app.methods) {
49-
connection.on(method, (...args: any[]) => {
50-
const path = args.shift();
55+
done.then((provider) =>
56+
provider.on('connection', (connection: any) => {
57+
for (const method of app.methods) {
58+
connection.on(method, (...args: any[]) => {
59+
const [path, ...rest] = args;
5160

52-
debug(`Got '${method}' call for service '${path}'`);
53-
runMethod(app, getParams(connection), path, method, args);
54-
});
55-
}
56-
57-
connection.on('authenticate', (...args: any[]) => {
58-
if (app.get('defaultAuthentication')) {
59-
debug('Got legacy authenticate event');
60-
runMethod(app, getParams(connection), app.get('defaultAuthentication'), 'create', args);
61+
runMethod(app, getParams(connection), path, method, rest);
62+
});
6163
}
62-
});
6364

64-
connection.on('logout', (callback: any) => {
65-
if (app.get('defaultAuthentication')) {
66-
debug('Got legacy authenticate event');
67-
runMethod(app, getParams(connection), app.get('defaultAuthentication'), 'remove', [ null, {}, callback ]);
68-
}
69-
});
70-
}));
65+
connection.on('authenticate', (...args: any[]) => {
66+
if (app.get('defaultAuthentication')) {
67+
debug('Got legacy authenticate event');
68+
runMethod(
69+
app,
70+
getParams(connection),
71+
app.get('defaultAuthentication'),
72+
'create',
73+
args
74+
);
75+
}
76+
});
77+
78+
connection.on('logout', (callback: any) => {
79+
if (app.get('defaultAuthentication')) {
80+
debug('Got legacy authenticate event');
81+
runMethod(
82+
app,
83+
getParams(connection),
84+
app.get('defaultAuthentication'),
85+
'remove',
86+
[null, {}, callback]
87+
);
88+
}
89+
});
90+
})
91+
);
7192

7293
// Legacy `socket.emit('serviceName::methodName', ...args)` handlers
73-
app.mixins.push((service, path) => done.then(provider => {
74-
provider.on('connection', (socket: any) => {
75-
const methods = app.methods.filter(current =>
76-
// @ts-ignore
77-
typeof service[current] === 'function'
78-
);
94+
app.mixins.push((service, path) =>
95+
done.then((provider) => {
96+
provider.on('connection', (socket: any) => {
97+
const methods = app.methods.filter(
98+
(current) =>
99+
// @ts-ignore
100+
typeof service[current] === 'function'
101+
);
79102

80-
for (const method of methods) {
81-
const eventName = `${path}::${method}`;
103+
for (const method of methods) {
104+
const eventName = `${path}::${method}`;
82105

83-
socket.on(eventName, (...args: any[]) => {
84-
debug(`Got legacy method call '${eventName}'`);
85-
runMethod(app, getParams(socket), path, method, args);
86-
});
87-
}
88-
});
89-
}));
106+
socket.on(eventName, (...args: any[]) => {
107+
debug(`Got legacy method call '${eventName}'`);
108+
runMethod(app, getParams(socket), path, method, args);
109+
});
110+
}
111+
});
112+
})
113+
);
90114
};
91115
}

packages/transport-commons/src/socket/utils.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ export function getDispatcher (emit: string, socketMap: WeakMap<RealTimeConnecti
6262
};
6363
}
6464

65-
export function runMethod (app: Application, connection: RealTimeConnection, path: string, method: string, args: any[]) {
65+
export function runMethod (app: Application, connection: RealTimeConnection, _path: string, _method: string, args: any[]) {
66+
const path = typeof _path === 'string' ? _path : null
67+
const method = typeof _method === 'string' ? _method : null
6668
const trace = `method '${method}' on service '${path}'`;
6769
const methodArgs = args.slice(0);
6870
const callback = typeof methodArgs[methodArgs.length - 1] === 'function'
@@ -81,7 +83,7 @@ export function runMethod (app: Application, connection: RealTimeConnection, pat
8183
// No valid service was found, return a 404
8284
// just like a REST route would
8385
if (lookup === null) {
84-
return Promise.reject(new errors.NotFound(`Service '${path}' not found`));
86+
return Promise.reject(new errors.NotFound(path === null ? 'Invalid service path' : `Service '${path}' not found`));
8587
}
8688

8789
const { service, params: route = {} } = lookup;

packages/transport-commons/test/socket/index.test.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,26 @@ describe('@feathersjs/transport-commons', () => {
7676
});
7777
});
7878

79-
it('.get with invalid service name and arguments', done => {
79+
it('method with invalid service name and arguments', (done) => {
8080
const socket = new EventEmitter();
8181

8282
provider.emit('connection', socket);
8383

8484
socket.emit('get', null, (error: any) => {
8585
assert.strictEqual(error.name, 'NotFound');
86-
assert.strictEqual(error.message, `Service 'null' not found`);
86+
assert.strictEqual(error.message, 'Invalid service path');
87+
done();
88+
});
89+
});
90+
91+
it('method with implicit toString errors properly', (done) => {
92+
const socket = new EventEmitter()
93+
94+
provider.emit('connection', socket)
95+
96+
socket.emit('get', { toString: '' }, (error: any) => {
97+
assert.strictEqual(error.name, 'NotFound');
98+
assert.strictEqual(error.message, 'Invalid service path');
8799
done();
88100
});
89101
});

0 commit comments

Comments
 (0)