diff --git a/dist/bundle.js b/dist/bundle.js index 929c7a2..587104b 100644 --- a/dist/bundle.js +++ b/dist/bundle.js @@ -128,7 +128,7 @@ eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * jQ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("// Imports\nvar ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = __webpack_require__(/*! ../../../node_modules/html-loader/dist/runtime/getUrl.js */ \"./node_modules/html-loader/dist/runtime/getUrl.js\");\nvar ___HTML_LOADER_IMPORT_0___ = __webpack_require__(/*! ../img/geschenke.jpg */ \"./src/client/img/geschenke.jpg\");\n// Module\nvar ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);\nvar code = \"
\\n
\\n

Geschenkeliste

\\n

\\n Ihr macht uns die größte Freude, wenn ihr mit uns feiert und den Tag verbringt. Wenn ihr uns gerne etwas\\n schenken möchtet, haben wir eine Liste zusammengestellt, worüber wir uns für den Start ins gemeinsame Leben\\n sehr freuen. Außerdem lieben wir es zu reisen und freuen uns immer über Geld für unsere Reisekasse. Falls\\n ihr euch unten in der Liste etwas ausgesucht habt, dann setzt dort gerne einen Haken. Wenn ihr auf ein Bild\\n klickt, öffnet sich direkt der passende Link dazu.\\n

\\n

\\n Diese Liste wird sich in den nächsten Wochen noch füllen. Schaut gerne noch mal vorbei!\\n

\\n \\n\\n
\\n
\\n \\n
\\n
\\n\";\n// Exports\nmodule.exports = code;\n\n//# sourceURL=webpack:///./src/client/html/geschenke.html?"); +eval("// Imports\nvar ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = __webpack_require__(/*! ../../../node_modules/html-loader/dist/runtime/getUrl.js */ \"./node_modules/html-loader/dist/runtime/getUrl.js\");\nvar ___HTML_LOADER_IMPORT_0___ = __webpack_require__(/*! ../img/geschenke.jpg */ \"./src/client/img/geschenke.jpg\");\n// Module\nvar ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);\nvar code = \"
\\n
\\n

Geschenkeliste

\\n

\\n Ihr macht uns die größte Freude, wenn ihr mit uns feiert und den Tag verbringt. Wenn ihr uns gerne etwas\\n schenken möchtet, haben wir eine Liste zusammengestellt, worüber wir uns für den Start ins gemeinsame Leben\\n sehr freuen. Außerdem lieben wir es zu reisen und freuen uns immer über Geld für unsere Reisekasse. Falls\\n ihr euch unten in der Liste etwas ausgesucht habt, dann setzt dort gerne einen Haken. Wenn ihr auf ein Bild\\n klickt, öffnet sich direkt der passende Link dazu.\\n

\\n\\n\\n\\n \\n\\n
\\n
\\n \\n
\\n
\\n\";\n// Exports\nmodule.exports = code;\n\n//# sourceURL=webpack:///./src/client/html/geschenke.html?"); /***/ }), @@ -139,7 +139,7 @@ eval("// Imports\nvar ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ = __webpack_requi /*! no static exports found */ /***/ (function(module, exports) { -eval("// Module\nvar code = \"
\\n

Herzlich Willkommen

\\n

Wir heiraten! Und das möchten wir mit euch gemeinsam am 8.Mai 2021 in Aachen feiern.\\n Bitte sagt uns doch bis zum 15.März, ob ihr dabei sein könnt! Schreibt uns dazu bitte eine Mail an hochzeit-js@gmx.net.

\\n\\n

Natürlich können wir unsere Einladung für nächstes Jahr nicht aussprechen, ohne ein paar Worte zu der aktuellen\\n Corona Pandemie zu verlieren. Wir hoffen sehr, dass sich die Lage bis Mai soweit beruhigt hat, dass wir unsere\\n Hochzeit mit euch allen feiern können. Leider ist das aber momentan sehr ungewiss. Soweit es geht, planen wir\\n damit, dass wir am 8. Mai gemeinsam feiern, falls sich daran etwas ändert, melden wir uns bei euch. Sagt uns\\n gerne trotzdem bis zum 15.März zu, damit wir besser planen können!

\\n
\";\n// Exports\nmodule.exports = code;\n\n//# sourceURL=webpack:///./src/client/html/home.html?"); +eval("// Module\nvar code = \"
\\n

Herzlich Willkommen

\\n

Wir heiraten! Und das möchten wir mit euch gemeinsam in Aachen feiern.\\n Leider müssen wir jedoch wegen der Corona Pandemie unsere kirchliche\\n Hochzeit um ein Jahr verschieben. Standesamtlich heiraten wir natürlich\\n trotzdem am 24.April in Betzdorf (Sieg) und sind glücklich darüber bald\\n gemeinsam in die Ehe zu starten. Wir freuen uns schon sehr darauf, nächstes Jahr\\n unseren Hochzeitsgottesdienst und eine große Party mit euch zu feiern\\n und melden uns, sobald der neue Hochzeitstermin feststeht.\\n

\\n\\n

Falls ihr Fragen habt, meldet euch gerne unter hochzeit-js@gmx.net

\\n
\\n\";\n// Exports\nmodule.exports = code;\n\n//# sourceURL=webpack:///./src/client/html/home.html?"); /***/ }), @@ -461,7 +461,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"PresentsHandler\", function() { return PresentsHandler; });\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nclass PresentsHandler {\n constructor() {\n this.presents = {};\n // @ts-ignore\n this.basePath = \".\";\n }\n loadPresents() {\n return __awaiter(this, void 0, void 0, function* () {\n const presents = __webpack_require__(/*! ./presents */ \"./src/client/js/presents.ts\").default;\n presents.forEach(p => this.presents[p.id] = p);\n yield this.updateStates();\n });\n }\n updateStates() {\n return __awaiter(this, void 0, void 0, function* () {\n const presentData = yield fetch(this.basePath + \"/presents\", {\n \"credentials\": \"same-origin\",\n \"method\": \"GET\",\n }).then(function (res) {\n return res.json();\n });\n presentData.forEach(data => {\n const present = this.presents[data.id];\n if (present) {\n present.isBought = data.isBought === 1;\n present.version = data.version;\n }\n });\n });\n }\n showPresents() {\n return __awaiter(this, void 0, void 0, function* () {\n const presentContainer = document.getElementById(\"present-container\");\n const presentTemplate = document.getElementById(\"present-template\");\n presentTemplate.remove();\n presentTemplate.removeAttribute(\"id\");\n yield this.loadPresents();\n presentContainer.innerText = \"\";\n Object.values(this.presents).forEach(present => {\n const element = presentTemplate.cloneNode(true);\n element.querySelector(\".present-image\").src = present.image;\n element.querySelector(\".present-name\").innerText = present.name;\n element.querySelector(\".present-description\").innerHTML = present.description;\n element.href = present.link;\n const checkboxElement = element.querySelector(\".present-checkbox\");\n if (present.isBought) {\n checkboxElement.classList.add(\"checked\");\n }\n checkboxElement.addEventListener(\"click\", (e) => __awaiter(this, void 0, void 0, function* () {\n e.preventDefault();\n yield this.setPresentIsBought(present, !present.isBought);\n if (present.isBought) {\n checkboxElement.classList.add(\"checked\");\n }\n else {\n checkboxElement.classList.remove(\"checked\");\n }\n }));\n presentContainer.appendChild(element);\n });\n });\n }\n setPresentIsBought(present, isBought) {\n return __awaiter(this, void 0, void 0, function* () {\n const url = this.basePath + \"/presents\";\n const params = {\n id: present.id,\n version: present.version,\n isBought: isBought\n };\n const res = yield this.send(url, params);\n console.log(\"result\", res);\n if (res.present && res.present.id === present.id) {\n present.version = res.present.version;\n present.isBought = res.present.isBought === 1;\n }\n if (res.success === false) {\n if (res.error === \"wrong-version\") {\n alert(\"Jemand hat schon vor dir das Geschenk bearbeitet. Bitte versuche es erneut.\");\n }\n }\n });\n }\n send(url, params) {\n return __awaiter(this, void 0, void 0, function* () {\n let headers = {};\n if (!(params instanceof FormData) && typeof params === \"object\") {\n params = JSON.stringify(params);\n headers = {\n \"Content-Type\": \"application/json\"\n };\n }\n return fetch(url, {\n \"credentials\": \"same-origin\",\n \"method\": \"POST\",\n \"headers\": headers,\n \"body\": params,\n }).then(function (res) {\n return res.json();\n }).catch(function (e) {\n debugger;\n console.error(\"error\", e);\n return {\n \"success\": false,\n \"errors\": [\n \"not-online\"\n ]\n };\n });\n });\n }\n}\n\n\n//# sourceURL=webpack:///./src/client/js/PresentsHandler.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"PresentsHandler\", function() { return PresentsHandler; });\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nclass PresentsHandler {\n constructor() {\n this.presents = {};\n // @ts-ignore\n this.basePath = \".\";\n }\n loadPresents() {\n return __awaiter(this, void 0, void 0, function* () {\n const presents = __webpack_require__(/*! ./presents */ \"./src/client/js/presents.ts\").default;\n presents.forEach(p => this.presents[p.id] = p);\n this.password = localStorage.getItem(\"pw\") || \"\";\n console.log(\"my pw:\", this.password);\n yield this.updateStates();\n });\n }\n updateStates() {\n return __awaiter(this, void 0, void 0, function* () {\n const presentData = yield this.send(this.basePath + \"/presents\", { password: this.password });\n presentData.forEach(data => {\n const present = this.presents[data.id];\n if (present) {\n present.isBought = data.isBought === 1;\n present.version = data.version;\n present.isMine = data.isMine === true;\n }\n });\n });\n }\n showPresents() {\n return __awaiter(this, void 0, void 0, function* () {\n const presentContainer = document.getElementById(\"present-container\");\n const presentTemplate = document.getElementById(\"present-template\");\n presentTemplate.remove();\n presentTemplate.removeAttribute(\"id\");\n yield this.loadPresents();\n presentContainer.innerText = \"\";\n Object.values(this.presents).forEach(present => {\n const element = presentTemplate.cloneNode(true);\n element.querySelector(\".present-image\").src = present.image;\n element.querySelector(\".present-name\").innerText = present.name;\n element.querySelector(\".present-description\").innerHTML = present.description;\n element.href = present.link;\n const checkboxElement = element.querySelector(\".present-checkbox\");\n if (present.isBought) {\n checkboxElement.classList.add(\"checked\");\n }\n checkboxElement.addEventListener(\"click\", (e) => __awaiter(this, void 0, void 0, function* () {\n e.preventDefault();\n if (!this.password || (present.isBought && !present.isMine)) {\n const pw = prompt(\"Bitte gib ein Passwort ein. Das brauchst du, wenn du das Geschenk wieder bearbeitest:\");\n if (pw) {\n this.password = pw;\n localStorage.setItem(\"pw\", pw);\n }\n else {\n alert(\"Du brauchst ein Passwort.\");\n return;\n }\n }\n yield this.setPresentIsBought(present, !present.isBought);\n if (present.isBought) {\n checkboxElement.classList.add(\"checked\");\n }\n else {\n checkboxElement.classList.remove(\"checked\");\n }\n }));\n presentContainer.appendChild(element);\n });\n });\n }\n setPresentIsBought(present, isBought) {\n return __awaiter(this, void 0, void 0, function* () {\n const url = this.basePath + \"/setPresent\";\n const params = {\n id: present.id,\n version: present.version,\n isBought: isBought,\n password: this.password\n };\n const res = yield this.send(url, params);\n if (res.present && res.present.id === present.id) {\n present.version = res.present.version;\n present.isBought = res.present.isBought === 1;\n if (present.isBought) {\n present.isMine = true;\n }\n }\n if (res.success === false) {\n if (res.error === \"wrong-version\") {\n alert(\"Jemand hat schon vor dir das Geschenk bearbeitet. Bitte versuche es erneut.\");\n }\n else if (res.error === \"wrong-password\") {\n alert(\"Das Passwort, was du angegeben hast, stimmt nicht.\");\n present.isMine = false;\n }\n else if (res.error === \"no-password\") {\n alert(\"Bitte gib ein Passwort an.\");\n }\n }\n });\n }\n send(url, params) {\n return __awaiter(this, void 0, void 0, function* () {\n let headers = {};\n if (!(params instanceof FormData) && typeof params === \"object\") {\n params = JSON.stringify(params);\n headers = {\n \"Content-Type\": \"application/json\"\n };\n }\n return fetch(url, {\n \"credentials\": \"same-origin\",\n \"method\": \"POST\",\n \"headers\": headers,\n \"body\": params,\n }).then(function (res) {\n return res.json();\n }).catch(function (e) {\n debugger;\n console.error(\"error\", e);\n return {\n \"success\": false,\n \"errors\": [\n \"not-online\"\n ]\n };\n });\n });\n }\n}\n\n\n//# sourceURL=webpack:///./src/client/js/PresentsHandler.ts?"); /***/ }), @@ -485,7 +485,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var jque /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ([{\n id: 1,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Quicheform.png */ \"./src/client/img/geschenke/Quicheform.png\").default,\n name: \"Quicheform\",\n description: \"Eine Keramik-Quicheform mit Haltegriffen, die spülmaschinengeeigent ist (wie im Link oder ähnlich)\",\n link: \"https://www.zwilling.com/de/zwilling-kuchenform-28-cm-keramik-40202-028-0/40202-028-0.html\",\n version: 0,\n }, {\n id: 2,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Sodastream.png */ \"./src/client/img/geschenke/Sodastream.png\").default,\n name: \"2 Sodastream Flaschen\",\n description: \"Zwei Glaskaraffen für den Sodastream Crystal\",\n link: \"https://sodastream.de/products/glaskaraffe-duo-pack-0-8l\",\n version: 0,\n }, {\n id: 3,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/GoPro.png */ \"./src/client/img/geschenke/GoPro.png\").default,\n name: \"Go Pro Hero 7 black\",\n description: \"Eine Go Pro Hero 7 Actioncam in schwarz\",\n link: \"https://gopro.com/de/de/shop/hero7-black/tech-specs?pid=CHDHX-701-master\",\n version: 0,\n }, {\n id: 4,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/AdventureKit_GoPro.png */ \"./src/client/img/geschenke/AdventureKit_GoPro.png\").default,\n name: \"Go Pro Zubehör\",\n description: \"Go Pro Abenteuer Kit mit schwimmendem Handgriff, Kopfgurt, QuickClip und Tasche\",\n link: \"https://gopro.com/de/de/shop/mounts-accessories/abenteuer-kit/AKTES-002.html\",\n version: 0,\n }, {\n id: 5,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Messerblock.png */ \"./src/client/img/geschenke/Messerblock.png\").default,\n name: \"Messerblock\",\n description: \"ZWILLING Messerblock, 8-tlg., Bambusblock, 6 Messer und eine Schere aus rostfreiem Spezialstahl\",\n link: \"https://www.amazon.de/Zwilling-32434-002-0-Bambus-Style-8-tlg/dp/B00AO2TRUI/\",\n version: 0,\n }, {\n id: 6,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Brettspiele.jpg */ \"./src/client/img/geschenke/Brettspiele.jpg\").default,\n name: \"Brettspiele\",\n // description: \"Wir freuen uns immer über ein neues, spannendes Brettspiel. Hier eine Liste von Spielen, die wir schon haben:\",\n description: \"Wir freuen uns immer über ein neues, spannendes Brettspiel. Falls ihr sichergehen wollt, welche Spiele wir schon haben, fragt doch unsere Trauzeugen Sinah oder Miriam.\",\n link: \"\",\n version: 0,\n },\n {\n id: 7,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Zahnbürste.png */ \"./src/client/img/geschenke/Zahnbürste.png\").default,\n name: \"Elektrische Pärchenzahn-bürste\",\n description: \"Nachhaltige elektrische Zahnbürste von happy brush, SCHALL VIBE 3 Partner Bundle\",\n link: \"https://www.happybrush.de/starterkit-vibe-3-schall-zahnbuerste-bundle-mix/\",\n version: 0,\n },\n {\n id: 8,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Kappsäge.png */ \"./src/client/img/geschenke/Kappsäge.png\").default,\n name: \"Kappsäge\",\n description: \"Einhell Kapp-/Gehrungssäge TC-MS 2112 (1600 W, Sägeblatt Ø 210 mm, Schnittbreite 120 mm, schwenkbarer Sägekopf)\",\n link: \"https://www.amazon.de/dp/B00DEXXFMK\",\n version: 0,\n },\n {\n id: 9,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Akkuschrauber.png */ \"./src/client/img/geschenke/Akkuschrauber.png\").default,\n name: \"Akku-schrauber\",\n description: \"LUX Akku-Bohrschrauber-Set inkl. Akku (wie im Link oder ähnlich)\",\n link: \"https://www.obi.de/akkuschrauber/lux-akku-bohrschrauber-set-1-powersystem-a-bs-20/p/9543208\",\n version: 0,\n },\n {\n id: 10,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/BodumBrotbox.jpg */ \"./src/client/img/geschenke/BodumBrotbox.jpg\").default,\n name: \"Bodum Brotbox\",\n description: \"Bodum bistroBrotkasten mit Bambus-Schneidebrett, 23.81 x 37.15 x 14.29 cm; 1.11 Kilogramm\",\n link: \"https://www.amazon.de/Bodum-bistroBrotkasten-Bambus-Schneidebrett-BPA-freier-Kunststoff/dp/B00MAPNVCW/\",\n version: 0,\n },\n {\n id: 11,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/großer_Topf.png */ \"./src/client/img/geschenke/großer_Topf.png\").default,\n name: \"Großer Kochtopf\",\n description: \"Tefal A70546 Duetto, ein großer Kochtopf, der circa 5l fasst (wie im Link oder ähnlich)\",\n link: \"https://www.amazon.de/dp/B00V6GF7UU/\",\n version: 0,\n },\n // {\n // id: 12,\n // isBought: false,\n // image: require(\"../img/geschenke/Ligretto.png\").default,\n // name: \"Ligretto in rot\",\n // description: \"Ligretto in rot, um mit acht Leuten spielen zu können\",\n // link: \"https://www.thalia.de/shop/home/artikeldetails/ID5130805.html\",\n // version: 0,\n // },\n {\n id: 13,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/studienbibel.png */ \"./src/client/img/geschenke/studienbibel.png\").default,\n name: \"Studienbibel\",\n description: \"MacArthur Studienbibel mit Schlachter 2000 Übersetzung\",\n link: \"https://www.scm-shop.de/macarthur-studienbibel-schlachter-2000-7485697.html\",\n version: 0,\n },\n {\n id: 14,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/nudelholz.png */ \"./src/client/img/geschenke/nudelholz.png\").default,\n name: \"Nudelholz\",\n description: \"Eine Teigrolle aus Holz (wie im Link oder ähnlich)\",\n link: \"https://shop.oetker.at/dr-oetker-teigroller-holz\",\n version: 0,\n },\n {\n id: 15,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/suppenkelle.png */ \"./src/client/img/geschenke/suppenkelle.png\").default,\n name: \"Suppenkelle mit Ausguss\",\n description: \"Eine Suppenkelle/ Schöpflöffel mit Ausguss\",\n link: \"https://www.fackelmann.de/fackelmann-ovalgriff-schoepfloeffel-29cm\",\n version: 0,\n },\n {\n id: 16,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/pizzaschneider.png */ \"./src/client/img/geschenke/pizzaschneider.png\").default,\n name: \"Pizzaschneider\",\n description: \"Ein Fahrrad Pizzaschneider\",\n link: \"https://www.amazon.de/s?k=Fahrrad+Pizzaschneider&i=kitchen&__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91\",\n version: 0,\n },\n {\n id: 17,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/teekasten.png */ \"./src/client/img/geschenke/teekasten.png\").default,\n name: \"Teebox\",\n description: \"Eine Teebox mit genügend Platz für viele Teebeutel (wie im Link oder ähnlich)\",\n link: \"https://www.amazon.de/dp/B002P9JK4Q?tag=teebox-best-21\",\n version: 0,\n },\n {\n id: 18,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/backblech.png */ \"./src/client/img/geschenke/backblech.png\").default,\n name: \"Backblech mit Kuchenhaube\",\n description: \"Ein Backblech mit passender Kuchenhaube (wie im Link oder ähnlich)\",\n link: \"https://www.real.de/product/309417147/\",\n version: 0,\n },\n {\n id: 19,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/zimmerpflanze.png */ \"./src/client/img/geschenke/zimmerpflanze.png\").default,\n name: \"Zimmerpflanze Strelitzia nicolai\",\n description: \"Strelitzie mit einer Höhe von 100 - 110 cm, Topf-Ø 24 cm, Paradiesvogelblume (wie im Link oder ähnlich)\",\n link: \"https://www.obi.de/weitere-gruenpflanzen/strelitzie-hoehe-100-110-cm-topf-24-cm-paradiesvogelblume-strelitzia-nicolai/p/9625096\",\n version: 0,\n },\n]);\n\n\n//# sourceURL=webpack:///./src/client/js/presents.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ([{\n id: 1,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Quicheform.png */ \"./src/client/img/geschenke/Quicheform.png\").default,\n name: \"Quicheform\",\n description: \"Eine Keramik-Quicheform mit Haltegriffen, die spülmaschinengeeigent ist (wie im Link oder ähnlich)\",\n link: \"https://www.zwilling.com/de/zwilling-kuchenform-28-cm-keramik-40202-028-0/40202-028-0.html\",\n version: 0,\n }, {\n id: 2,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Sodastream.png */ \"./src/client/img/geschenke/Sodastream.png\").default,\n name: \"2 Sodastream Flaschen\",\n description: \"Zwei Glaskaraffen für den Sodastream Crystal\",\n link: \"https://sodastream.de/products/glaskaraffe-duo-pack-0-8l\",\n version: 0,\n }, {\n id: 3,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/GoPro.png */ \"./src/client/img/geschenke/GoPro.png\").default,\n name: \"Go Pro Hero 7 black\",\n description: \"Eine Go Pro Hero 7 Actioncam in schwarz\",\n link: \"https://gopro.com/de/de/shop/hero7-black/tech-specs?pid=CHDHX-701-master\",\n version: 0,\n }, {\n id: 4,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/AdventureKit_GoPro.png */ \"./src/client/img/geschenke/AdventureKit_GoPro.png\").default,\n name: \"Go Pro Zubehör\",\n description: \"Go Pro Abenteuer Kit mit schwimmendem Handgriff, Kopfgurt, QuickClip und Tasche\",\n link: \"https://gopro.com/de/de/shop/mounts-accessories/abenteuer-kit/AKTES-002.html\",\n version: 0,\n }, {\n id: 5,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Messerblock.png */ \"./src/client/img/geschenke/Messerblock.png\").default,\n name: \"Messerblock\",\n description: \"ZWILLING Messerblock, 8-tlg., Bambusblock, 6 Messer und eine Schere aus rostfreiem Spezialstahl\",\n link: \"https://www.amazon.de/Zwilling-32434-002-0-Bambus-Style-8-tlg/dp/B00AO2TRUI/\",\n version: 0,\n }, {\n id: 6,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Brettspiele.jpg */ \"./src/client/img/geschenke/Brettspiele.jpg\").default,\n name: \"Brettspiele\",\n // description: \"Wir freuen uns immer über ein neues, spannendes Brettspiel. Hier eine Liste von Spielen, die wir schon haben:\",\n description: \"Wir freuen uns immer über ein neues, spannendes Brettspiel. Falls ihr sichergehen wollt, welche Spiele wir schon haben, fragt doch unsere Trauzeugen Sinah oder Miriam.\",\n link: \"\",\n version: 0,\n }, {\n id: 7,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Zahnbürste.png */ \"./src/client/img/geschenke/Zahnbürste.png\").default,\n name: \"Elektrische Pärchenzahn-bürste\",\n description: \"Nachhaltige elektrische Zahnbürste von happy brush, SCHALL VIBE 3 Partner Bundle\",\n link: \"https://www.happybrush.de/starterkit-vibe-3-schall-zahnbuerste-bundle-mix/\",\n version: 0,\n }, {\n id: 8,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Kappsäge.png */ \"./src/client/img/geschenke/Kappsäge.png\").default,\n name: \"Kappsäge\",\n description: \"Einhell Kapp-/Gehrungssäge TC-MS 2112 (1600 W, Sägeblatt Ø 210 mm, Schnittbreite 120 mm, schwenkbarer Sägekopf)\",\n link: \"https://www.amazon.de/dp/B00DEXXFMK\",\n version: 0,\n }, {\n id: 9,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/Akkuschrauber.png */ \"./src/client/img/geschenke/Akkuschrauber.png\").default,\n name: \"Akku-schrauber\",\n description: \"LUX Akku-Bohrschrauber-Set inkl. Akku (wie im Link oder ähnlich)\",\n link: \"https://www.obi.de/akkuschrauber/lux-akku-bohrschrauber-set-1-powersystem-a-bs-20/p/9543208\",\n version: 0,\n }, {\n id: 10,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/BodumBrotbox.jpg */ \"./src/client/img/geschenke/BodumBrotbox.jpg\").default,\n name: \"Bodum Brotbox\",\n description: \"Bodum bistroBrotkasten mit Bambus-Schneidebrett, 23.81 x 37.15 x 14.29 cm; 1.11 Kilogramm\",\n link: \"https://www.amazon.de/Bodum-bistroBrotkasten-Bambus-Schneidebrett-BPA-freier-Kunststoff/dp/B00MAPNVCW/\",\n version: 0,\n }, {\n id: 11,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/großer_Topf.png */ \"./src/client/img/geschenke/großer_Topf.png\").default,\n name: \"Großer Kochtopf\",\n description: \"Tefal A70546 Duetto, ein großer Kochtopf, der circa 5l fasst (wie im Link oder ähnlich)\",\n link: \"https://www.amazon.de/dp/B00V6GF7UU/\",\n version: 0,\n },\n // {\n // id: 12,\n // isBought: false,\n // image: require(\"../img/geschenke/Ligretto.png\").default,\n // name: \"Ligretto in rot\",\n // description: \"Ligretto in rot, um mit acht Leuten spielen zu können\",\n // link: \"https://www.thalia.de/shop/home/artikeldetails/ID5130805.html\",\n // version: 0,\n // },\n {\n id: 13,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/studienbibel.png */ \"./src/client/img/geschenke/studienbibel.png\").default,\n name: \"Studienbibel\",\n description: \"MacArthur Studienbibel mit Schlachter 2000 Übersetzung\",\n link: \"https://www.scm-shop.de/macarthur-studienbibel-schlachter-2000-7485697.html\",\n version: 0,\n }, {\n id: 14,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/nudelholz.png */ \"./src/client/img/geschenke/nudelholz.png\").default,\n name: \"Nudelholz\",\n description: \"Eine Teigrolle aus Holz (wie im Link oder ähnlich)\",\n link: \"https://shop.oetker.at/dr-oetker-teigroller-holz\",\n version: 0,\n }, {\n id: 15,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/suppenkelle.png */ \"./src/client/img/geschenke/suppenkelle.png\").default,\n name: \"Suppenkelle mit Ausguss\",\n description: \"Eine Suppenkelle/ Schöpflöffel mit Ausguss\",\n link: \"https://www.fackelmann.de/fackelmann-ovalgriff-schoepfloeffel-29cm\",\n version: 0,\n }, {\n id: 16,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/pizzaschneider.png */ \"./src/client/img/geschenke/pizzaschneider.png\").default,\n name: \"Pizzaschneider\",\n description: \"Ein Fahrrad Pizzaschneider\",\n link: \"https://www.amazon.de/s?k=Fahrrad+Pizzaschneider&i=kitchen&__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91\",\n version: 0,\n }, {\n id: 17,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/teekasten.png */ \"./src/client/img/geschenke/teekasten.png\").default,\n name: \"Teebox\",\n description: \"Eine Teebox mit genügend Platz für viele Teebeutel (wie im Link oder ähnlich)\",\n link: \"https://www.amazon.de/dp/B002P9JK4Q?tag=teebox-best-21\",\n version: 0,\n }, {\n id: 18,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/backblech.png */ \"./src/client/img/geschenke/backblech.png\").default,\n name: \"Backblech mit Kuchenhaube\",\n description: \"Ein Backblech mit passender Kuchenhaube (wie im Link oder ähnlich)\",\n link: \"https://www.real.de/product/309417147/\",\n version: 0,\n }, {\n id: 19,\n isBought: false,\n image: __webpack_require__(/*! ../img/geschenke/zimmerpflanze.png */ \"./src/client/img/geschenke/zimmerpflanze.png\").default,\n name: \"Zimmerpflanze Strelitzia nicolai\",\n description: \"Strelitzie mit einer Höhe von 100 - 110 cm, Topf-Ø 24 cm, Paradiesvogelblume (wie im Link oder ähnlich)\",\n link: \"https://www.obi.de/weitere-gruenpflanzen/strelitzie-hoehe-100-110-cm-topf-24-cm-paradiesvogelblume-strelitzia-nicolai/p/9625096\",\n version: 0,\n },\n]);\n\n\n//# sourceURL=webpack:///./src/client/js/presents.ts?"); /***/ }), diff --git a/setup.sql b/setup.sql index 97e1567..8311d2e 100644 --- a/setup.sql +++ b/setup.sql @@ -1 +1,4 @@ -CREATE TABLE presents (id int(11) NOT NULL PRIMARY KEY, version int(11) NOT NULL, isBought tinyint(1) NOT NULL) \ No newline at end of file +CREATE TABLE presents (id int(11) NOT NULL PRIMARY KEY, version int(11) NOT NULL, isBought tinyint(1) NOT NULL) + +--- +ALTER TABLE presents ADD COLUMN password varchar(127) NOT NULL DEFAULT ''; diff --git a/src/client/html/geschenke.html b/src/client/html/geschenke.html index 74e2683..99e2b96 100644 --- a/src/client/html/geschenke.html +++ b/src/client/html/geschenke.html @@ -8,9 +8,9 @@ ihr euch unten in der Liste etwas ausgesucht habt, dann setzt dort gerne einen Haken. Wenn ihr auf ein Bild klickt, öffnet sich direkt der passende Link dazu.

-

- Diese Liste wird sich in den nächsten Wochen noch füllen. Schaut gerne noch mal vorbei! -

+ + +
diff --git a/src/client/html/home.html b/src/client/html/home.html index 567543b..b7be7a3 100644 --- a/src/client/html/home.html +++ b/src/client/html/home.html @@ -1,11 +1,13 @@

Herzlich Willkommen

-

Wir heiraten! Und das möchten wir mit euch gemeinsam am 8.Mai 2021 in Aachen feiern. - Bitte sagt uns doch bis zum 15.März, ob ihr dabei sein könnt! Schreibt uns dazu bitte eine Mail an hochzeit-js@gmx.net.

+

Wir heiraten! Und das möchten wir mit euch gemeinsam in Aachen feiern. + Leider müssen wir jedoch wegen der Corona Pandemie unsere kirchliche + Hochzeit um ein Jahr verschieben. Standesamtlich heiraten wir natürlich + trotzdem am 24.April in Betzdorf (Sieg) und sind glücklich darüber bald + gemeinsam in die Ehe zu starten. Wir freuen uns schon sehr darauf, nächstes Jahr + unseren Hochzeitsgottesdienst und eine große Party mit euch zu feiern + und melden uns, sobald der neue Hochzeitstermin feststeht. +

-

Natürlich können wir unsere Einladung für nächstes Jahr nicht aussprechen, ohne ein paar Worte zu der aktuellen - Corona Pandemie zu verlieren. Wir hoffen sehr, dass sich die Lage bis Mai soweit beruhigt hat, dass wir unsere - Hochzeit mit euch allen feiern können. Leider ist das aber momentan sehr ungewiss. Soweit es geht, planen wir - damit, dass wir am 8. Mai gemeinsam feiern, falls sich daran etwas ändert, melden wir uns bei euch. Sagt uns - gerne trotzdem bis zum 15.März zu, damit wir besser planen können!

-
\ No newline at end of file +

Falls ihr Fragen habt, meldet euch gerne unter hochzeit-js@gmx.net

+
diff --git a/src/client/js/PresentsHandler.ts b/src/client/js/PresentsHandler.ts index 14fcde3..8b3d8f1 100644 --- a/src/client/js/PresentsHandler.ts +++ b/src/client/js/PresentsHandler.ts @@ -7,32 +7,33 @@ export class PresentsHandler { image: string, name: string, description: string - link: string + link: string, + isMine?: boolean, } } = {}; + password: string; + // @ts-ignore private readonly basePath = __BASE_PATH__; async loadPresents() { const presents = require("./presents").default; presents.forEach(p => this.presents[p.id] = p); + this.password = localStorage.getItem("pw") || ""; + await this.updateStates(); } async updateStates() { - const presentData: any[] = await fetch(this.basePath + "/presents", { - "credentials": "same-origin", - "method": "GET", - }).then(function (res) { - return res.json(); - }); + const presentData: any[] = await this.send(this.basePath + "/presents", {password: this.password}); presentData.forEach(data => { const present = this.presents[data.id]; - if (present){ + if (present) { present.isBought = data.isBought === 1; present.version = data.version; + present.isMine = data.isMine === true } }) } @@ -60,6 +61,19 @@ export class PresentsHandler { checkboxElement.addEventListener("click", async e => { e.preventDefault(); + + if (!this.password || (present.isBought && !present.isMine)){ + const pw = prompt("Bitte gib ein Passwort ein. Das brauchst du, wenn du das Geschenk wieder bearbeitest:") + if (pw){ + this.password = pw; + localStorage.setItem("pw", pw); + } + else { + alert("Du brauchst ein Passwort."); + return; + } + } + await this.setPresentIsBought(present, !present.isBought); if (present.isBought) { checkboxElement.classList.add("checked"); @@ -72,28 +86,46 @@ export class PresentsHandler { }) } - private async setPresentIsBought(present: { id: number, isBought: boolean; version: number, image: string; name: string; description: string; link: string }, isBought: boolean) { - const url = this.basePath + "/presents" + private async setPresentIsBought(present: { + id: number, + isBought: boolean; + version: number, + image: string; + name: string; + description: string; + link: string, + isMine?: boolean + }, isBought: boolean) { + const url = this.basePath + "/setPresent" const params = { id: present.id, version: present.version, - isBought: isBought + isBought: isBought, + password: this.password } const res = await this.send(url, params); - console.log("result", res); - if (res.present && res.present.id === present.id) { present.version = res.present.version; present.isBought = res.present.isBought === 1 + if (present.isBought){ + present.isMine = true; + } } if (res.success === false) { if (res.error === "wrong-version") { alert("Jemand hat schon vor dir das Geschenk bearbeitet. Bitte versuche es erneut.") } + else if (res.error === "wrong-password"){ + alert("Das Passwort, was du angegeben hast, stimmt nicht.") + present.isMine = false; + } + else if (res.error === "no-password"){ + alert("Bitte gib ein Passwort an.") + } } } @@ -124,4 +156,4 @@ export class PresentsHandler { } }); } -} \ No newline at end of file +} diff --git a/src/client/js/presents.ts b/src/client/js/presents.ts index 7b019df..d905582 100644 --- a/src/client/js/presents.ts +++ b/src/client/js/presents.ts @@ -47,61 +47,56 @@ export default [{ description: "Wir freuen uns immer über ein neues, spannendes Brettspiel. Falls ihr sichergehen wollt, welche Spiele wir schon haben, fragt doch unsere Trauzeugen Sinah oder Miriam.", link: "", version: 0, +}, { + id: 7, + isBought: false, + image: require("../img/geschenke/Zahnbürste.png").default, + name: "Elektrische Pärchenzahn-bürste", + description: "Nachhaltige elektrische Zahnbürste von happy brush, SCHALL VIBE 3 Partner Bundle", + link: "https://www.happybrush.de/starterkit-vibe-3-schall-zahnbuerste-bundle-mix/", + version: 0, +}, { + id: 8, + isBought: false, + image: require("../img/geschenke/Kappsäge.png").default, + name: "Kappsäge", + description: "Einhell Kapp-/Gehrungssäge TC-MS 2112 (1600 W, Sägeblatt Ø 210 mm, Schnittbreite 120 mm, schwenkbarer Sägekopf)", + link: "https://www.amazon.de/dp/B00DEXXFMK", + version: 0, +}, { + id: 9, + isBought: false, + image: require("../img/geschenke/Akkuschrauber.png").default, + name: "Akku-schrauber", + description: "LUX Akku-Bohrschrauber-Set inkl. Akku (wie im Link oder ähnlich)", + link: "https://www.obi.de/akkuschrauber/lux-akku-bohrschrauber-set-1-powersystem-a-bs-20/p/9543208", + version: 0, +}, { + id: 10, + isBought: false, + image: require("../img/geschenke/BodumBrotbox.jpg").default, + name: "Bodum Brotbox", + description: "Bodum bistroBrotkasten mit Bambus-Schneidebrett, 23.81 x 37.15 x 14.29 cm; 1.11 Kilogramm", + link: "https://www.amazon.de/Bodum-bistroBrotkasten-Bambus-Schneidebrett-BPA-freier-Kunststoff/dp/B00MAPNVCW/", + version: 0, +}, { + id: 11, + isBought: false, + image: require("../img/geschenke/großer_Topf.png").default, + name: "Großer Kochtopf", + description: "Tefal A70546 Duetto, ein großer Kochtopf, der circa 5l fasst (wie im Link oder ähnlich)", + link: "https://www.amazon.de/dp/B00V6GF7UU/", + version: 0, }, - { - id: 7, - isBought: false, - image: require("../img/geschenke/Zahnbürste.png").default, - name: "Elektrische Pärchenzahn-bürste", - description: "Nachhaltige elektrische Zahnbürste von happy brush, SCHALL VIBE 3 Partner Bundle", - link: "https://www.happybrush.de/starterkit-vibe-3-schall-zahnbuerste-bundle-mix/", - version: 0, - }, - { - id: 8, - isBought: false, - image: require("../img/geschenke/Kappsäge.png").default, - name: "Kappsäge", - description: "Einhell Kapp-/Gehrungssäge TC-MS 2112 (1600 W, Sägeblatt Ø 210 mm, Schnittbreite 120 mm, schwenkbarer Sägekopf)", - link: "https://www.amazon.de/dp/B00DEXXFMK", - version: 0, - }, - { - id: 9, - isBought: false, - image: require("../img/geschenke/Akkuschrauber.png").default, - name: "Akku-schrauber", - description: "LUX Akku-Bohrschrauber-Set inkl. Akku (wie im Link oder ähnlich)", - link: "https://www.obi.de/akkuschrauber/lux-akku-bohrschrauber-set-1-powersystem-a-bs-20/p/9543208", - version: 0, - }, - { - id: 10, - isBought: false, - image: require("../img/geschenke/BodumBrotbox.jpg").default, - name: "Bodum Brotbox", - description: "Bodum bistroBrotkasten mit Bambus-Schneidebrett, 23.81 x 37.15 x 14.29 cm; 1.11 Kilogramm", - link: "https://www.amazon.de/Bodum-bistroBrotkasten-Bambus-Schneidebrett-BPA-freier-Kunststoff/dp/B00MAPNVCW/", - version: 0, - }, - { - id: 11, - isBought: false, - image: require("../img/geschenke/großer_Topf.png").default, - name: "Großer Kochtopf", - description: "Tefal A70546 Duetto, ein großer Kochtopf, der circa 5l fasst (wie im Link oder ähnlich)", - link: "https://www.amazon.de/dp/B00V6GF7UU/", - version: 0, - }, - // { - // id: 12, - // isBought: false, - // image: require("../img/geschenke/Ligretto.png").default, - // name: "Ligretto in rot", - // description: "Ligretto in rot, um mit acht Leuten spielen zu können", - // link: "https://www.thalia.de/shop/home/artikeldetails/ID5130805.html", - // version: 0, - // }, +// { +// id: 12, +// isBought: false, +// image: require("../img/geschenke/Ligretto.png").default, +// name: "Ligretto in rot", +// description: "Ligretto in rot, um mit acht Leuten spielen zu können", +// link: "https://www.thalia.de/shop/home/artikeldetails/ID5130805.html", +// version: 0, +// }, { id: 13, isBought: false, @@ -110,8 +105,7 @@ export default [{ description: "MacArthur Studienbibel mit Schlachter 2000 Übersetzung", link: "https://www.scm-shop.de/macarthur-studienbibel-schlachter-2000-7485697.html", version: 0, - }, - { + }, { id: 14, isBought: false, image: require("../img/geschenke/nudelholz.png").default, @@ -119,8 +113,7 @@ export default [{ description: "Eine Teigrolle aus Holz (wie im Link oder ähnlich)", link: "https://shop.oetker.at/dr-oetker-teigroller-holz", version: 0, - }, - { + }, { id: 15, isBought: false, image: require("../img/geschenke/suppenkelle.png").default, @@ -128,8 +121,7 @@ export default [{ description: "Eine Suppenkelle/ Schöpflöffel mit Ausguss", link: "https://www.fackelmann.de/fackelmann-ovalgriff-schoepfloeffel-29cm", version: 0, - }, - { + }, { id: 16, isBought: false, image: require("../img/geschenke/pizzaschneider.png").default, @@ -137,8 +129,7 @@ export default [{ description: "Ein Fahrrad Pizzaschneider", link: "https://www.amazon.de/s?k=Fahrrad+Pizzaschneider&i=kitchen&__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91", version: 0, - }, - { + }, { id: 17, isBought: false, image: require("../img/geschenke/teekasten.png").default, @@ -146,8 +137,7 @@ export default [{ description: "Eine Teebox mit genügend Platz für viele Teebeutel (wie im Link oder ähnlich)", link: "https://www.amazon.de/dp/B002P9JK4Q?tag=teebox-best-21", version: 0, - }, - { + }, { id: 18, isBought: false, image: require("../img/geschenke/backblech.png").default, @@ -155,8 +145,7 @@ export default [{ description: "Ein Backblech mit passender Kuchenhaube (wie im Link oder ähnlich)", link: "https://www.real.de/product/309417147/", version: 0, - }, - { + }, { id: 19, isBought: false, image: require("../img/geschenke/zimmerpflanze.png").default, diff --git a/src/server/Server.ts b/src/server/Server.ts index 710f23a..33e5693 100644 --- a/src/server/Server.ts +++ b/src/server/Server.ts @@ -34,31 +34,32 @@ export class Server { // this.handleSocketConnection(); } - private async query(sql): Promise { + private async query(sql, params?): Promise { return new Promise((resolve, reject) => { try { + params = params || []; + console.log("[LOG:DO_QUERY]", sql, params); + if (!this.mysqlConnection || (this.mysqlConnection.state !== "connected" && this.mysqlConnection.state !== "authenticated")) { + console.log("reopening connection..."); + this.mysqlConnection = mysql.createConnection({ + host: process.env.MYSQL_HOST || "localhost", + user: process.env.MYSQL_USER || "root", + password: process.env.MYSQL_PASSWORD || "", + database: process.env.MYSQL_DATABASE || "hochzeit" + }); - if (!this.mysqlConnection || this.mysqlConnection.state === "disconnected"){ - console.log("reopening connection..."); - this.mysqlConnection = mysql.createConnection({ - host: process.env.MYSQL_HOST || "localhost", - user: process.env.MYSQL_USER || "root", - password: process.env.MYSQL_PASSWORD || "", - database: process.env.MYSQL_DATABASE || "hochzeit" - }); - - // setTimeout(() => { - // this.mysqlConnection.destroy(); - // }, 5000); - } - }catch(e){ + // setTimeout(() => { + // this.mysqlConnection.destroy(); + // }, 5000); + } + } catch (e) { console.error(e); reject(e); } - this.mysqlConnection.query(sql, (error, results) => { + this.mysqlConnection.query(sql, params, (error, results) => { if (error) { - console.error(error); + console.error("Error for query", '"' + sql + '"\n', error); reject(error) } else { resolve(results); @@ -67,6 +68,16 @@ export class Server { }) } + private static preparePresent(present, password?) { + if (present.password) { + if (password && password === present.password) { + present.isMine = true; + } + delete present.password; + } + return present; + } + private configureApp(): void { this.app.use(express.json({limit: "1mb"})); this.app.use(express.static(path.join(__dirname, "../../dist"))); @@ -76,28 +87,56 @@ export class Server { this.app.get("/", (req, res) => { res.sendFile("index.html"); }); - this.app.get("/presents", async (req, res) => { - res.json(await this.query("SELECT * FROM presents")); - }) this.app.post("/presents", async (req, res) => { + res.json((await this.query("SELECT * FROM presents")).map(p => Server.preparePresent(p, req.body.password))); + }) + this.app.post("/setPresent", async (req, res) => { const id = parseInt(req.body.id); - const isBought = (req.body.isBought === true)?1:0; + const isBought = (req.body.isBought === true) ? 1 : 0; const version = parseInt(req.body.version) || 0; const newVersion = version + 1; + const password = req.body.password; - const presents = await this.query("SELECT * FROM presents WHERE id = '" + id + "'"); + const presents = await this.query("SELECT * FROM presents WHERE id = ?", [id]); if (presents.length === 0) { - await this.query("INSERT INTO presents (id, isBought, version) VALUES (" + id + ", " + isBought + ", " + newVersion + ");"); + if (password) { + await this.query("INSERT INTO presents (id, isBought, version, password) VALUES (?, ?, ?, ?);", [id, isBought, newVersion, password]); + } else { + return res.json({ + "success": false, + "error": "no-password", + }); + } } else { const present = presents[0]; if (present.version === version) { - await this.query("UPDATE presents SET version = " + newVersion + ", isBought = " + isBought + " WHERE ID = " + id); + if (present.isBought === 1) { + if (present.password !== "" && present.password !== password) { + return res.json({ + "success": false, + "error": "wrong-password", + present: Server.preparePresent(present, password) + }); + } + } + const newPassword = (isBought === 1 ? password : ""); + if (isBought && !password) { + return res.json({ + "success": false, + "error": "no-password", + }); + } + await this.query("UPDATE presents SET version = ?, isBought = ?, password = ? WHERE ID = ?", [newVersion, isBought, newPassword, id]); } else { - return res.json({"success": false, "error": "wrong-version", present: present}); + return res.json({ + "success": false, + "error": "wrong-version", + present: Server.preparePresent(present, password) + }); } } - return res.json({"success": true, present: {id: id, isBought: isBought, version: newVersion}}) - }) + return res.json({"success": true, present: {id: id, isBought: isBought, version: newVersion, isMine: true}}) + }); } public listen(callback: (port: number) => void): void {