You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

172 lines
4.7 KiB

  1. const { routerConfig: { signatures, allowed, allowTargetId, secondaryAllowed, globalAllowed, secondaryAllowTargetId } } = require('./routerConfig');
  2. module.exports = {
  3. allowedCpn: function (msg) {
  4. const { cpn, method, data: { cpn: secondaryCpn, method: secondaryMethod, targetId } } = msg;
  5. const valid = allowed[cpn] && allowed[cpn].includes(method);
  6. if (!valid)
  7. return false;
  8. if (!secondaryCpn) {
  9. if (targetId !== undefined) {
  10. const canHaveTargetId = allowTargetId?.[cpn]?.includes(method);
  11. if (!canHaveTargetId)
  12. return false;
  13. }
  14. return true;
  15. }
  16. const secondaryValid = secondaryAllowed?.[secondaryCpn]?.includes(secondaryMethod);
  17. if (!secondaryValid)
  18. return false;
  19. if (targetId !== undefined) {
  20. const canHaveTargetId = secondaryAllowTargetId?.[secondaryCpn]?.includes(secondaryMethod);
  21. if (!canHaveTargetId)
  22. return false;
  23. }
  24. return true;
  25. },
  26. allowedGlobal: function (msg) {
  27. const result = globalAllowed[msg.module] && globalAllowed[msg.module].includes(msg.method);
  28. return result;
  29. },
  30. allowedGlobalCall: function (threadModule, method) {
  31. const result = globalAllowed[threadModule] && globalAllowed[threadModule].includes(method);
  32. return result;
  33. },
  34. keysCorrect: function (obj, keys) {
  35. const foundIncorrect = keys.some(({ key, dataType, optional, spec }) => {
  36. if (!Object.hasOwnProperty.call(obj, key)) {
  37. if (optional)
  38. return false;
  39. return true;
  40. }
  41. const value = obj[key];
  42. if (dataType === 'string' || dataType === 'boolean')
  43. return dataType !== typeof(value);
  44. else if (dataType === 'numberOrString')
  45. return (typeof(value) !== 'string' && !Number.isFinite(value));
  46. else if (dataType === 'integerOrString')
  47. return (typeof(value) !== 'string' && !Number.isInteger(value));
  48. else if (dataType === 'integer')
  49. return !Number.isInteger(value);
  50. else if (dataType === 'integerNullOrObject') {
  51. const isCorrect = (
  52. Number.isInteger(value) ||
  53. value === null ||
  54. (
  55. typeof(value) === 'object' &&
  56. this.keysCorrect(value, spec)
  57. )
  58. );
  59. return !isCorrect;
  60. } else if (dataType === 'arrayOfStrings')
  61. return (!Array.isArray(value) || value.some(v => typeof(v) !== 'string'));
  62. else if (dataType === 'arrayOfIntegers')
  63. return (!Array.isArray(value) || value.some(v => !Number.isInteger(v)));
  64. else if (dataType === 'arrayOfObjects') {
  65. if (!Array.isArray(value) || value.some(v => v === null || typeof(v) !== 'object'))
  66. return true;
  67. const foundIncorrectObject = value.some(v => !this.keysCorrect(v, spec));
  68. if (foundIncorrectObject)
  69. return true;
  70. return foundIncorrectObject;
  71. } else if (dataType === 'object') {
  72. if (typeof(value) !== 'object' || value === null)
  73. return true;
  74. if (!spec)
  75. return false;
  76. const foundIncorrectObject = !this.keysCorrect(value, spec);
  77. if (foundIncorrectObject)
  78. return true;
  79. return foundIncorrectObject;
  80. } else if (dataType === 'stringOrNull')
  81. return (typeof(value) !== 'string' && value !== null);
  82. return true;
  83. });
  84. if (foundIncorrect)
  85. return false;
  86. const foundInvalid = Object.keys(obj).some(o => !keys.some(k => k.key === o));
  87. return !foundInvalid;
  88. },
  89. signatureCorrect: function (msg, config) {
  90. if (config.callback !== 'deferred') {
  91. if (config.callback === true && !msg.callback)
  92. return false;
  93. else if (config.callback === false && !!msg.callback)
  94. return false;
  95. }
  96. const expectKeys = config.data;
  97. const keysCorrect = this.keysCorrect(msg.data, expectKeys);
  98. return keysCorrect;
  99. },
  100. isMsgValid: function (msg, source) {
  101. let signature;
  102. if (msg.module) {
  103. if (msg.threadModule !== undefined || msg.cpn !== undefined || msg.data.cpn !== undefined)
  104. return false;
  105. signature = signatures.global[msg.module]?.[msg.method];
  106. } else if (msg.threadModule) {
  107. if (msg.module !== undefined || msg.cpn !== undefined || msg.data.cpn !== undefined)
  108. return false;
  109. signature = signatures.threadGlobal[msg.threadModule]?.[msg.method];
  110. } else if (msg.cpn) {
  111. if (msg.module !== undefined || msg.threadModule !== undefined)
  112. return false;
  113. signature = signatures.cpnMethods[msg.cpn]?.[msg.method];
  114. }
  115. if (!signature)
  116. return false;
  117. const result = this.signatureCorrect(msg, signature);
  118. if (!result || msg.cpn !== 'player' || msg.method !== 'performAction') {
  119. if (result && signature.allowWhenIngame === false && source?.name !== undefined)
  120. return false;
  121. return result;
  122. }
  123. const signatureThreadMsg = signatures.threadCpnMethods[msg.data.cpn]?.[msg.data.method];
  124. if (!signatureThreadMsg)
  125. return false;
  126. const resultSub = this.signatureCorrect(msg.data, signatureThreadMsg);
  127. return resultSub;
  128. }
  129. };