You can start off by removing the repeat inputArray.indexOf() calls - it makes everything harder to read. It's simpler to check these once only:
const hasCreate = inputArray.indexOf(CREATE) > -1;
const hasUpdate = inputArray.indexOf(UPDATE) > -1;
const hasRead = inputArray.indexOf(READ) > -1;
Second, the rules you set up show that you have three access properties - read, update, and create, each one may imply another. Looking at those, it becomes clear that you have the following relationships:
read => read
update => update, read
create => create, read
Thus, update and create are actually compound. This means that the initial check can be modified to account for these:
const hasCreate = inputArray.indexOf(CREATE) > -1;
const hasUpdate = inputArray.indexOf(UPDATE) > -1;
const hasRead = hasCreate || hasUpdate || inputArray.indexOf(READ) > -1;
This avoids having the checks for if somebody has read or update.
As an extra note, you can just use Array#includes instead of checking the index.
With that said, the read right is pretty much inconsequential. It matters if it's the only one available, in all other cases it's pretty much ignored or assumed to be present. Still, it's useful to model the implied rules - perhaps this can change in the future.
Finally, the logic is too complex. There are only four possible final states and as mentioned above, read is not even used for most of them. Here is the updated code that does all the checks. I've added another state called "None" for the case when there are no permissions at all. Even if it's not possible for this to happen, I find it easier to just have it and it be unused than omit it:
const caluclateAcess = (inputArray) => {
const hasCreate = inputArray.includes('create');
const hasUpdate = inputArray.includes('update');
const hasRead = hasCreate || hasUpdate || inputArray.includes('read');
if (hasCreate === true && hasUpdate === true) return "ALL";
if (hasCreate) return "CreateAndRead";
if (hasUpdate) return "UpdateAndRead";
if (hasRead) return "Read";
return "None";
};
console.log("create =>", caluclateAcess(["create"]) );
console.log("read =>", caluclateAcess(["read"]) );
console.log("update =>", caluclateAcess(["update"]) );
console.log("create, read =>", caluclateAcess(["create", "read"]) );
console.log("update, read=>", caluclateAcess(["update", "read"]) );
console.log("create, update =>", caluclateAcess(["create", "update"]) );
console.log("create, read, update =>", caluclateAcess(["create", "read", "update"]));
console.log("<nothing> =>", caluclateAcess([]) );
The READ, CREATE, and UPDATE variables are not needed, since they are only used once, so I inlined them to shorten the code even more.
However, if there really is no possibility for an empty array of access properties, then that implies that the read access is completely inconsequential. It's impossible to not have it. So, checking for it can be entirely skipped and the default return value of the function can be changed from "None" to "Read". However, my personal preference is to keep the check - it doesn't hurt any of the functionality and the implementation produces no deviation from the specs. If the specs change in the future, or there is some sort of bug, it's probably better to not automatically grant read access.