intacct / intacct-sdk-js

Official repository of the Sage Intacct SDK for JavaScript in Node.js
https://developer.intacct.com/tools/sdk-node-js/
Apache License 2.0
23 stars 33 forks source link

OnlineResponse.ts line 51 - TypeError: Cannot read property 'hasOwnProperty' of undefined #68

Open jimmymcpeter opened 3 years ago

jimmymcpeter commented 3 years ago

The following code

const config = new ClientConfig();
config.senderId = "testsenderid";
config.senderPassword = "pass123!";
config.companyId = "testconsoleid|testclientid";
config.userId = "invaliduserid";
config.userPassword = "testpass";

const sessionCreds = await SessionProvider.factory(config);

Throws the following

TypeError: Cannot read property 'hasOwnProperty' of undefined
    at new ErrorMessage (src\Xml\Response\ErrorMessage.ts:34:27)
    at new OnlineResponse (src\Xml\OnlineResponse.ts:51:34)
    at C:\Users\user\WebstormProjects\intacct-sdk-js\src\Xml\RequestHandler.ts:66:20
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

In OnlineResponse.ts, this is the section throwing

if (this._authentication.status !== "success") {
    const errorMessage = new ErrorMessage(this._xml["response"]["operation"]["errormessage"]);

    throw new ResponseException("Response authentication status failure", errorMessage.errors);
}

To replicate this, the company ID must be in pipe form testconsoleid|testclientid and the user ID in the console must be invalid. For whatever reason with this combo, Web Services returns the following XML response which is completely missing any sort of errormessage element in the operation block.

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <control>
        <status>success</status>
        <senderid>testsenderid</senderid>
        <controlid>sessionProvider</controlid>
        <uniqueid>false</uniqueid>
        <dtdversion>3.0</dtdversion>
    </control>
    <operation>
        <authentication>
            <status>failure</status>
            <userid>invaliduserid</userid>
            <companyid>testconsoleid</companyid>
            <locationid></locationid>
        </authentication>
    </operation>
</response>
jimmymcpeter commented 3 years ago

Here is a unit test you can use to replicate in SessionProviderTest.ts --

    it("should execute from console login credentials to client", async () => {
        const xmlResponse = `<?xml version="1.0" encoding="UTF-8"?>
<response>
    <control>
        <status>success</status>
        <senderid>testsenderid</senderid>
        <controlid>sessionProvider</controlid>
        <uniqueid>false</uniqueid>
        <dtdversion>3.0</dtdversion>
    </control>
    <operation>
        <authentication>
            <status>failure</status>
            <userid>invaliduserid</userid>
            <companyid>testconsoleid</companyid>
            <locationid></locationid>
        </authentication>
    </operation>
</response>
`;

        const headers = {
            "Content-Type": 'text/xml; encoding="UTF-8"',
        };

        nock.disableNetConnect();
        nock("https://api.intacct.com")
            .replyContentLength()
            .post("/ia/xml/xmlgw.phtml")
            .reply(200, xmlResponse, headers);

        const config = new ClientConfig();
        config.senderId = "testsenderid";
        config.senderPassword = "pass123!";
        config.companyId = "testconsoleid|testclientid";
        config.userId = "invaliduserid";
        config.userPassword = "testpass";

        const sessionCreds = await SessionProvider.factory(config);

    });