bluehalo / node-fhir-server-core

An Open Source secure REST implementation for the HL7 FHIR Specification. For API documentation, please see https://github.com/Asymmetrik/node-fhir-server-core/wiki.
https://asymmetrik.com/healthcare
MIT License
391 stars 120 forks source link

[feat] Prevent js file use from server configuration object #212

Closed Ahryman40k closed 4 years ago

Ahryman40k commented 4 years ago

Hi,

I would like to propose a new feature to the node-fhir-server-core.

Documentation describe how a config object should be constructed and provided to asymmetrik server initialization

let config = {
    profiles: {
        composition: {
            service: `${__dirname}/services/composition.service.js`,
            versions: [
                '4_0_0'
            ],
            metadata: `${__dirname}/metadata/composition.metadata.js`
        }
    }
};
let server = asymmetrik.initialize(config);

As we are using typescript, providing a Javascript file path can be a difficult task, mainly in tests where code isn't transpiled. So I would like to provide improvements regarding the configuration object. Because I were doing experiments with configuration, I saw an error was thrown when 'service' path in configuration object is empty. Exception occurs in method 'verifyAndLoadProfiles' from 'server.js' file. With the following code:

try {
    profiles[name].serviceModule = typeof service === 'string' ? require(path.resolve(service)) : service;
} catch (err) {
    message = `Invalid ${name} configuration. ${err.message}`;
}

I noticed that if type of 'service' isn't a string then object is stored in serviceModule property instead of loading a module from its path. Because metadata isn't a required property the same mechanism doesn't happen during the validation process.

So I was wondering if the same behaviour exists for 'metadata' property. In the file params.utils.js, method 'getSearchParameters' load our metadata module from the provided path. We can see these few lines of code:

if (customArgsModule) {
       let paramsAsArray = require(String(customArgsModule)).makeResource(
            Object.assign({}, { base_version: version, key: lowercaseProfileName }),
        logger,
    ).searchParam;
   [...]

Provided metadata module is loaded from its path then call the 'makeResource' method. So If I understood clearly the logic here, I could test type of 'customArgsModule' then load module if it's a path else simply use object ? I mean something like:

const makeResourceFn = typeof customArgsModule === 'string' ? require(String(customArgsModule)).makeResource : customArgsModule.makeResource;

let paramsAsArray = makeResourceFn(
    Object.assign({}, { base_version: version, key: lowercaseProfileName }),
    logger,
).searchParam;
    [...]

Do you agree with my analysis ? Are you ok to add surch feature ? If so can I create a Pull request ?

Best regards, Ahry

michelekorell commented 4 years ago

It is very useful, mostly when it is used inside a TypeScript project!

zeevo commented 4 years ago

See https://github.com/Asymmetrik/node-fhir-server-core/pull/213#issuecomment-562153154