@@ -58,7 +58,7 @@ export class Description {
5858 types : TypesDescription ;
5959}
6060
61- let serviceDescription : Description | null = null ;
61+ const serviceDescriptions : Map < string , Description > = new Map < string , Description > ( ) ;
6262
6363/**
6464 * Returns collection of class methods metadata even those are inherited
@@ -188,10 +188,21 @@ export abstract class IMQService {
188188 }
189189
190190 else if ( ! description . service . methods [ method ] ) {
191- response . error = IMQError (
192- 'IMQ_RPC_NO_ACCESS' ,
193- `Access to ${ this . name } .${ method } () denied!` ,
194- new Error ( ) . stack , method , args ) ;
191+ // Allow calling runtime-attached methods (own props) even if
192+ // they are not present in the exposed service description.
193+ // Deny access for prototype (class) methods not decorated with @expose.
194+ const isOwn = Object . prototype . hasOwnProperty . call ( this , method ) ;
195+ const value : any = ( this as any ) [ method ] ;
196+ const proto = Object . getPrototypeOf ( this ) ;
197+ const protoValue = proto && proto [ method ] ;
198+ const isSameAsProto = typeof protoValue === 'function' && value === protoValue ;
199+ // Allow only truly dynamic own-instance functions (not the same as prototype)
200+ if ( ! ( isOwn && typeof value === 'function' && ! isSameAsProto ) ) {
201+ response . error = IMQError (
202+ 'IMQ_RPC_NO_ACCESS' ,
203+ `Access to ${ this . name } .${ method } () denied!` ,
204+ new Error ( ) . stack , method , args ) ;
205+ }
195206 }
196207
197208 else if ( ! isValidArgsCount (
@@ -318,17 +329,21 @@ export abstract class IMQService {
318329 */
319330 @expose ( )
320331 public describe ( ) : Description {
321- if ( ! serviceDescription ) {
322- serviceDescription = {
332+ let description = serviceDescriptions . get ( this . name ) || null ;
333+
334+ if ( ! description ) {
335+ description = {
323336 service : {
324337 name : this . name ,
325338 methods : getClassMethods ( this . constructor . name )
326339 } ,
327340 types : IMQRPCDescription . typesDescription
328341 } ;
342+
343+ serviceDescriptions . set ( this . name , description ) ;
329344 }
330345
331- return serviceDescription ;
346+ return description ;
332347 }
333348
334349}
0 commit comments