diff --git a/client.mjs b/client.mjs index a05a777..901fc98 100644 --- a/client.mjs +++ b/client.mjs @@ -6,7 +6,7 @@ export class Client { * @return {Promise} username * */ async getUser() { - throw new Error("Not implemented"); + return await fetch('/api/username').then(async res => await res.text()); } /** @@ -17,7 +17,8 @@ export class Client { * @return {Promise} username * */ async loginUser(username) { - throw new Error("Not implemented"); + await fetch(`/api/login?username=${username}`).then(async res => await res.text()); + return username || null } /** @@ -26,7 +27,7 @@ export class Client { * @return {void} * */ async logoutUser() { - throw new Error("Not implemented"); + await fetch('/api/logout'); } /** @@ -50,7 +51,7 @@ export class Client { * @return {Promise} * */ async getInfo() { - throw new Error("Not implemented"); + return (await fetch("https://api.spacexdata.com/v3/info")).json(); } /** @@ -63,7 +64,7 @@ export class Client { * @return {Promise} * */ async getHistory() { - throw new Error("Not implemented"); + return (await fetch('https://api.spacexdata.com/v3/history')).json(); } /** @@ -80,7 +81,7 @@ export class Client { * @return {Promise} * */ async getHistoryEvent(id) { - throw new Error("Not implemented"); + return (await fetch(`https://api.spacexdata.com/v3/history/${id}`)).json(); } /** @@ -93,7 +94,7 @@ export class Client { * @return {Promise} * */ async getRockets() { - throw new Error("Not implemented"); + return (await fetch('https://api.spacexdata.com/v3/rockets')).json(); } /** @@ -118,7 +119,7 @@ export class Client { * @return {Promise} * */ async getRocket(id) { - throw new Error("Not implemented"); + return (await fetch(`https://api.spacexdata.com/v3/rockets/${id}`)).json(); } /** @@ -135,7 +136,7 @@ export class Client { * @return {Promise} * */ async getRoadster() { - throw new Error("Not implemented"); + return (await fetch('https://api.spacexdata.com/v3/roadster')).json(); } /** @@ -152,7 +153,8 @@ export class Client { * @return {Promise} * */ async getSentToMars() { - throw new Error("Not implemented"); + let response = await fetch('api/user/sendToMars/get'); + return (await response.json()); } /** @@ -170,7 +172,15 @@ export class Client { * @return {Promise} * */ async sendToMars(item) { - throw new Error("Not implemented"); + let response = await fetch('api/user/sendToMars/send', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({'item': item}) + }); + + return (await response.json()); } /** @@ -181,6 +191,14 @@ export class Client { * @return {Promise} * */ async cancelSendingToMars(item) { - throw new Error("Not implemented"); + let response = await fetch('api/user/sendToMars/cancel', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({'item': item}) + }); + + return (await response.json()); } } diff --git a/package-lock.json b/package-lock.json index 87f8931..4ae7fc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,52 +31,17 @@ } }, "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "requires": { - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } + "string-width": "^4.1.0" } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", @@ -517,9 +482,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } @@ -611,9 +576,9 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "ipaddr.js": { "version": "1.9.1", @@ -846,9 +811,9 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" }, "object-assign": { "version": "4.1.1", diff --git a/server.mjs b/server.mjs index 75d9cbe..1332bdb 100644 --- a/server.mjs +++ b/server.mjs @@ -2,26 +2,96 @@ import * as path from "path"; import fs from "fs"; import express from "express"; import https from "https"; -import cookieParser from "cookie-parser"; import bodyParser from "body-parser"; -import fetch from "node-fetch"; +import cookieParser from "cookie-parser"; const rootDir = process.cwd(); const port = 3000; const app = express(); +const notRedirectingUrls = ['login', 'api', 'static']; + +app.use(express.static("spa/build")); +app.use(cookieParser()); +app.use(bodyParser.json()); + +app.use(function (req, res, next) { + const root = req.url.split('/')[1]; + const shouldBeSkipped = notRedirectingUrls.includes(root); + const isFile = root.split('.').length > 1; + const haveCookie = req.cookies.username !== undefined; + if (shouldBeSkipped || isFile || haveCookie) { + next() + } else + res.redirect('/login'); +}) app.get("/client.mjs", (_, res) => { - res.header("Cache-Control", "private, no-cache, no-store, must-revalidate"); - res.sendFile(path.join(rootDir, "client.mjs"), { - maxAge: -1, - cacheControl: false, - }); + res.header("Cache-Control", "private, no-cache, no-store, must-revalidate"); + res.sendFile(path.join(rootDir, "client.mjs"), { + maxAge: -1, + cacheControl: false, + }); }); app.get("/", (_, res) => { - res.send(":)"); + res.send(":)"); +}); + +app.get("/api/username", (req, res) => { + res.send(req.cookies.username || null); }); -app.listen(port, () => { - console.log(`App listening on port ${port}`); +app.get("/api/login", (req, res) => { + const username = req.query.username; + res.cookie("username", username); + res.send(username); }); + +app.get("/api/logout", (req, res) => { + res.clearCookie('username'); + res.status(201).end(); +}); + +const mars = {} + +app.post("/api/user/sendToMars/send", (req, res) => { + const name = req.cookies.username; + + const item = req.body['item']; + + if (name in mars) { + mars[name].push(item) + } else { + mars[name] = [item]; + } + + res.json(mars[name]); +}); +app.post("/api/user/sendToMars/cancel", (req, res) => { + const name = req.cookies.username; + + const item = req.body['item']; + + if (name in mars) { + const index = mars[name].indexOf(item); + mars[name].splice(index, 1); + } + + res.json(mars[name]); +}); +app.get("/api/user/sendToMars/get", (req, res) => { + const name = req.cookies.username; + + res.json(mars[name] || []); +}); + +app.get("/*", (req, res) => { + res.sendFile(path.join(rootDir, "spa/build/index.html")); +}); + +https.createServer({ + key: fs.readFileSync("certs/server.key"), + cert: fs.readFileSync("certs/server.cert"), +}, app).listen(port, function () { + console.log(`app on https://localhost:3000/`); +}); \ No newline at end of file