From 82296d0f2df48e5d153a5bc41c5b951d636d16316876b666ff9407849a69fa1b Mon Sep 17 00:00:00 2001
From: Philipp Schweizer <Philipp.Schw@directbox.com>
Date: Tue, 31 Dec 2024 16:14:02 +0100
Subject: [PATCH 1/3] feat: wigle proxy call added

---
 server/.env.template      |  5 +++-
 server/src/proxy/wigle.ts | 61 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 server/src/proxy/wigle.ts

diff --git a/server/.env.template b/server/.env.template
index b9b73cf..16c19d3 100644
--- a/server/.env.template
+++ b/server/.env.template
@@ -3,4 +3,7 @@ DB_USER=""
 DB_PASSWORD=""
 DB_HOST=""
 DB_DIALECT=""
-DB_PORT=""
\ No newline at end of file
+DB_PORT=""
+WIGLE_TOKEN=""
+WIGLE_BASE_URL="https://api.wigle.net"
+WIGLE_NETWORK_SEARCH="/api/v2/network/search"
\ No newline at end of file
diff --git a/server/src/proxy/wigle.ts b/server/src/proxy/wigle.ts
new file mode 100644
index 0000000..9270c67
--- /dev/null
+++ b/server/src/proxy/wigle.ts
@@ -0,0 +1,61 @@
+interface WifiLocationResponse {
+  success: boolean;
+  totalResults: number;
+  first: number;
+  last: number;
+  resultCount: number;
+  results: Result[];
+  searchAfter: string;
+  search_after: number;
+}
+
+interface Result {
+  trilat: number;
+  trilong: number;
+  ssid: string;
+  qos: number;
+  transid: string;
+  firsttime: string;
+  lasttime: string;
+  lastupdt: string;
+  netid: string;
+  name?: string;
+  type: string;
+  comment?: string;
+  wep: string;
+  bcninterval: number;
+  freenet: string;
+  dhcp: string;
+  paynet: string;
+  userfound: boolean;
+  channel: number;
+  rcois: string;
+  encryption: string;
+  country: string;
+  region: string;
+  road: string;
+  city?: string;
+  housenumber?: string;
+  postalcode: string;
+}
+
+export const getLocationForWifi = async (
+  mac: string
+): Promise<WifiLocationResponse | undefined> => {
+  try {
+    console.log(process.env.WIGLE_BASE_URL);
+    const url = `${process.env.WIGLE_BASE_URL!}${process.env
+      .WIGLE_NETWORK_SEARCH!}?netid=${encodeURIComponent(mac)}`;
+    const response = await fetch(url, {
+      method: "GET",
+      headers: {
+        "Content-Type": "application/json",
+        Cookie: `auth=${process.env.WIGLE_TOKEN}`,
+      },
+    });
+
+    return await response.json();
+  } catch (error) {
+    console.error("Fehler beim Aufruf des Services:", error);
+  }
+};

From d8ec609baf3129e9647da4ded5fc921830a569d7830f4f72b4942635c4f15ac5 Mon Sep 17 00:00:00 2001
From: Philipp Schweizer <Philipp.Schw@directbox.com>
Date: Wed, 1 Jan 2025 19:31:51 +0100
Subject: [PATCH 2/3] feat: added cache version for api call

---
 server/package-lock.json  | 167 ++++++++++++++++++++++++++++++++++++++
 server/package.json       |   4 +-
 server/src/proxy/wigle.ts |  10 ++-
 3 files changed, 178 insertions(+), 3 deletions(-)

diff --git a/server/package-lock.json b/server/package-lock.json
index c52f415..96f0aec 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -14,6 +14,7 @@
         "express": "^4.21.2",
         "http-status-codes": "^2.3.0",
         "mariadb": "^3.4.0",
+        "memoizee": "^0.4.17",
         "reflect-metadata": "^0.2.2",
         "sequelize": "^6.37.5",
         "swagger-jsdoc": "^6.2.8",
@@ -23,6 +24,7 @@
       },
       "devDependencies": {
         "@types/express": "^5.0.0",
+        "@types/memoizee": "^0.4.11",
         "@types/node": "^22.10.2",
         "nodemon": "^3.1.9",
         "ts-node": "^10.9.2",
@@ -230,6 +232,13 @@
       "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
       "license": "MIT"
     },
+    "node_modules/@types/memoizee": {
+      "version": "0.4.11",
+      "resolved": "https://registry.npmjs.org/@types/memoizee/-/memoizee-0.4.11.tgz",
+      "integrity": "sha512-2gyorIBZu8GoDr9pYjROkxWWcFtHCquF7TVbN2I+/OvgZhnIGQS0vX5KJz4lXNKb8XOSfxFOSG5OLru1ESqLUg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@types/mime": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@@ -573,6 +582,19 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/d": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
+      "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
+      "license": "ISC",
+      "dependencies": {
+        "es5-ext": "^0.10.64",
+        "type": "^2.7.2"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
     "node_modules/debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -709,12 +731,79 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/es5-ext": {
+      "version": "0.10.64",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
+      "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
+      "hasInstallScript": true,
+      "license": "ISC",
+      "dependencies": {
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.3",
+        "esniff": "^2.0.1",
+        "next-tick": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+      "license": "MIT",
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "node_modules/es6-symbol": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
+      "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
+      "license": "ISC",
+      "dependencies": {
+        "d": "^1.0.2",
+        "ext": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/es6-weak-map": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+      "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+      "license": "ISC",
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.46",
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.1"
+      }
+    },
     "node_modules/escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
       "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
       "license": "MIT"
     },
+    "node_modules/esniff": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
+      "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
+      "license": "ISC",
+      "dependencies": {
+        "d": "^1.0.1",
+        "es5-ext": "^0.10.62",
+        "event-emitter": "^0.3.5",
+        "type": "^2.7.2"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
     "node_modules/esutils": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -733,6 +822,16 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+      "license": "MIT",
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
     "node_modules/express": {
       "version": "4.21.2",
       "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
@@ -779,6 +878,15 @@
         "url": "https://opencollective.com/express"
       }
     },
+    "node_modules/ext": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+      "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+      "license": "ISC",
+      "dependencies": {
+        "type": "^2.7.2"
+      }
+    },
     "node_modules/fill-range": {
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -1084,6 +1192,12 @@
         "node": ">=0.12.0"
       }
     },
+    "node_modules/is-promise": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+      "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+      "license": "MIT"
+    },
     "node_modules/js-yaml": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -1126,6 +1240,15 @@
       "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
       "license": "ISC"
     },
+    "node_modules/lru-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+      "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
+      "license": "MIT",
+      "dependencies": {
+        "es5-ext": "~0.10.2"
+      }
+    },
     "node_modules/make-error": {
       "version": "1.3.6",
       "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
@@ -1179,6 +1302,25 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/memoizee": {
+      "version": "0.4.17",
+      "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz",
+      "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==",
+      "license": "ISC",
+      "dependencies": {
+        "d": "^1.0.2",
+        "es5-ext": "^0.10.64",
+        "es6-weak-map": "^2.0.3",
+        "event-emitter": "^0.3.5",
+        "is-promise": "^2.2.2",
+        "lru-queue": "^0.1.0",
+        "next-tick": "^1.1.0",
+        "timers-ext": "^0.1.7"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
     "node_modules/merge-descriptors": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -1278,6 +1420,12 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/next-tick": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+      "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
+      "license": "ISC"
+    },
     "node_modules/nodemon": {
       "version": "3.1.9",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
@@ -1873,6 +2021,19 @@
         "express": ">=4.0.0 || >=5.0.0-beta"
       }
     },
+    "node_modules/timers-ext": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz",
+      "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==",
+      "license": "ISC",
+      "dependencies": {
+        "es5-ext": "^0.10.64",
+        "next-tick": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
     "node_modules/to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -1973,6 +2134,12 @@
         "node": ">= 6.0.0"
       }
     },
+    "node_modules/type": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
+      "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==",
+      "license": "ISC"
+    },
     "node_modules/type-is": {
       "version": "1.6.18",
       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
diff --git a/server/package.json b/server/package.json
index 91701ba..a71e8c3 100644
--- a/server/package.json
+++ b/server/package.json
@@ -16,7 +16,8 @@
     "@types/node": "^22.10.2",
     "nodemon": "^3.1.9",
     "ts-node": "^10.9.2",
-    "typescript": "^5.7.2"
+    "typescript": "^5.7.2",
+    "@types/memoizee": "^0.4.11"
   },
   "dependencies": {
     "cors": "^2.8.5",
@@ -24,6 +25,7 @@
     "express": "^4.21.2",
     "http-status-codes": "^2.3.0",
     "mariadb": "^3.4.0",
+    "memoizee": "^0.4.17",
     "reflect-metadata": "^0.2.2",
     "sequelize": "^6.37.5",
     "swagger-jsdoc": "^6.2.8",
diff --git a/server/src/proxy/wigle.ts b/server/src/proxy/wigle.ts
index 9270c67..0b8d913 100644
--- a/server/src/proxy/wigle.ts
+++ b/server/src/proxy/wigle.ts
@@ -1,3 +1,5 @@
+import memoizee from "memoizee";
+
 interface WifiLocationResponse {
   success: boolean;
   totalResults: number;
@@ -43,7 +45,6 @@ export const getLocationForWifi = async (
   mac: string
 ): Promise<WifiLocationResponse | undefined> => {
   try {
-    console.log(process.env.WIGLE_BASE_URL);
     const url = `${process.env.WIGLE_BASE_URL!}${process.env
       .WIGLE_NETWORK_SEARCH!}?netid=${encodeURIComponent(mac)}`;
     const response = await fetch(url, {
@@ -53,9 +54,14 @@ export const getLocationForWifi = async (
         Cookie: `auth=${process.env.WIGLE_TOKEN}`,
       },
     });
-
     return await response.json();
   } catch (error) {
     console.error("Fehler beim Aufruf des Services:", error);
   }
 };
+
+export const getLocationForWifiMemoized = memoizee(getLocationForWifi, {
+  maxAge: Number(process.env.GET_LOCATION_WIFI_MAX_AGE),
+  max: Number(process.env.GET_LOCATION_WIFI_MAX),
+  primitive: process.env.GET_LOCATION_WIFI_PRIMITIVE === "true",
+});

From a10a8d9d6383b8ef2bac76966e5a8a9534ab2be7bb431d45c580208c4fa6fb08 Mon Sep 17 00:00:00 2001
From: Philipp Schweizer <Philipp.Schw@directbox.com>
Date: Wed, 1 Jan 2025 19:33:04 +0100
Subject: [PATCH 3/3] fix: added new env. varibales to template file

---
 server/.env.template | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/server/.env.template b/server/.env.template
index 16c19d3..d54c511 100644
--- a/server/.env.template
+++ b/server/.env.template
@@ -6,4 +6,7 @@ DB_DIALECT=""
 DB_PORT=""
 WIGLE_TOKEN=""
 WIGLE_BASE_URL="https://api.wigle.net"
-WIGLE_NETWORK_SEARCH="/api/v2/network/search"
\ No newline at end of file
+WIGLE_NETWORK_SEARCH="/api/v2/network/search"
+GET_LOCATION_WIFI_MAX_AGE=1209600000 # 14 Tage in Millisekunden (14 * 24 * 60 * 60 * 1000)
+GET_LOCATION_WIFI_MAX=10000          
+GET_LOCATION_WIFI_PRIMITIVE=true  
\ No newline at end of file