yuken 3 лет назад
Родитель
Сommit
9e4f2ef6d6
1 измененных файлов с 41 добавлено и 46 удалено
  1. 41 46
      packages/app/src/server/util/generateApiRateLimitConfig.ts

+ 41 - 46
packages/app/src/server/util/generateApiRateLimitConfig.ts

@@ -1,65 +1,42 @@
 import { IApiRateLimitConfig } from '../interfaces/api-rate-limit-config';
 
-const getKeyByValue = (object: Record<string, string>, value: string): string | undefined => {
-  return Object.keys(object).find(key => object[key] === value);
-};
-
-const getHighPriorityKey = (key1: string, key2: string): string => {
-  const key1Target = key1.replace('API_RATE_LIMIT_', '').replace('_ENDPOINT', '');
-  const key1Priority = Number(key1Target.split('_')[0]);
-
-  const key2Target = key2.replace('API_RATE_LIMIT_', '').replace('_ENDPOINT', '');
-  const key2Priority = Number(key2Target.split('_')[0]);
+const sortApiRateEndpointKeys = (endpoints: string[]): string[] => {
+  return endpoints.sort((a, b) => {
+    const targetA = a.replace('API_RATE_LIMIT_', '').replace('_ENDPOINT', '');
+    const priorityA = Number(targetA.split('_')[0]);
 
-  if (key1Priority > key2Priority) {
-    return key1;
-  }
+    const targetB = b.replace('API_RATE_LIMIT_', '').replace('_ENDPOINT', '');
+    const priorityB = Number(targetB.split('_')[0]);
 
-  return key2;
-};
+    if (Number.isNaN(priorityA) || Number.isNaN(priorityB)) {
+      return 1;
+    }
 
-// this method is called only one server starts
-export const generateApiRateLimitConfig = (): IApiRateLimitConfig => {
-  const envVar = process.env;
+    if (priorityA > priorityB) {
+      return -1;
+    }
 
-  const apiRateEndpointKeys = Object.keys(envVar).filter((key) => {
-    const endpointRegExp = /^API_RATE_LIMIT_.*_ENDPOINT/;
-    return endpointRegExp.test(key);
+    return 1;
   });
+};
 
-  // pick up API_RATE_LIMIT_*_ENDPOINT from ENV
-  const envVarEndpoint: Record<string, string> = {};
-  apiRateEndpointKeys.forEach((key) => {
-    const value = envVar[key];
-    if (value === undefined) { return }
-    envVarEndpoint[key] = value;
-  });
+const generateApiRateLimitConfigFromEndpoint = (envVar: NodeJS.ProcessEnv, endpointKeys: string[]): IApiRateLimitConfig => {
+  const apiRateLimitConfig: IApiRateLimitConfig = {};
+  endpointKeys.forEach((key) => {
 
+    const endpoint = envVar[key];
 
-  // filter the same endpoint configs
-  const envVarEndpointFiltered: Record<string, string> = {};
-  apiRateEndpointKeys.forEach((key) => {
-    const endpointValue = envVarEndpoint[key];
-    if (endpointValue === undefined) { return }
-    if (Object.values(envVarEndpoint).includes(endpointValue)) {
-      const existingKey = getKeyByValue(envVarEndpoint, endpointValue);
-      if (existingKey === undefined) { return }
-      const highPriorityKey = getHighPriorityKey(key, existingKey);
-      envVarEndpointFiltered[highPriorityKey] = endpointValue;
+    if (endpoint === undefined || Object.keys(apiRateLimitConfig).includes(endpoint)) {
+      return;
     }
-    else {
-      envVarEndpointFiltered[key] = endpointValue;
-    }
-  });
 
-  const apiRateLimitConfig: IApiRateLimitConfig = {};
-  Object.keys(envVarEndpointFiltered).forEach((key) => {
     const target = key.replace('API_RATE_LIMIT_', '').replace('_ENDPOINT', '');
-    const endpoint = envVarEndpointFiltered[`API_RATE_LIMIT_${target}_ENDPOINT`];
     const method = envVar[`API_RATE_LIMIT_${target}_METHODS`];
     const consumePoints = Number(envVar[`API_RATE_LIMIT_${target}_CONSUME_POINTS`]);
 
-    if (endpoint === undefined || method === undefined || consumePoints === undefined) { return }
+    if (endpoint === undefined || method === undefined || consumePoints === undefined) {
+      return;
+    }
 
     const config = {
       method,
@@ -69,6 +46,24 @@ export const generateApiRateLimitConfig = (): IApiRateLimitConfig => {
     apiRateLimitConfig[endpoint] = config;
   });
 
+  return apiRateLimitConfig;
+};
+
+// this method is called only one server starts
+export const generateApiRateLimitConfig = (): IApiRateLimitConfig => {
+  const envVar = process.env;
+
+  const apiRateEndpointKeys = Object.keys(envVar).filter((key) => {
+    const endpointRegExp = /^API_RATE_LIMIT_.*_ENDPOINT/;
+    return endpointRegExp.test(key);
+  });
+
+  // sort priority
+  const apiRateEndpointKeysSorted = sortApiRateEndpointKeys(apiRateEndpointKeys);
+
+  // get config
+  const apiRateLimitConfig = generateApiRateLimitConfigFromEndpoint(envVar, apiRateEndpointKeysSorted);
+
   // default setting e.g. healthchack
   apiRateLimitConfig['/_api/v3/healthcheck'] = {
     method: 'GET',