diff --git a/controllers/playlists.js b/controllers/playlists.js
new file mode 100644
index 0000000..83b0148
--- /dev/null
+++ b/controllers/playlists.js
@@ -0,0 +1,84 @@
+require('dotenv').config();
+const logger = require("../utils/logger")(module);
+
+const typedefs = require("../typedefs");
+const { axiosInstance } = require('../axios');
+
+/**
+ * Retrieve list of all of user's playlists
+ * @param {typedefs.Req} req
+ * @param {typedefs.Res} res
+ */
+const getUserPlaylists = async (req, res) => {
+ try {
+ // get first 50
+ const response = await axiosInstance.get(
+ "/me/playlists",
+ {
+ params: {
+ offset: 0,
+ limit: 50,
+ },
+ headers: {
+ ...req.authHeader
+ }
+ }
+ );
+
+ let playlists = {};
+
+ playlists.items = response.data.items.map((playlist) => {
+ return {
+ name: playlist.name,
+ description: playlist.description,
+ owner: playlist.owner.display_name,
+ images: playlist.images.map((image) => image.url),
+ link: playlist.external_urls.spotify,
+ collaborative: playlist.collaborative,
+ public: playlist.public,
+ id: playlist.id,
+ }
+ });
+
+ playlists.total = response.data.total;
+ playlists.next = response.data.next;
+
+ // keep getting batches of 50 more till exhausted
+ while (playlists.next) {
+ const nextResponse = await axiosInstance.get(
+ playlists.next, // absolute URL which has params
+ {
+ headers: {
+ ...req.authHeader
+ }
+ }
+ );
+
+ playlists.items.push(
+ ...nextResponse.data.items.map((playlist) => {
+ return {
+ name: playlist.name,
+ description: playlist.description,
+ owner: playlist.owner.display_name,
+ images: playlist.images.map((image) => image.url),
+ link: playlist.external_urls.spotify,
+ collaborative: playlist.collaborative,
+ public: playlist.public,
+ id: playlist.id,
+ }
+ })
+ );
+
+ playlists.next = nextResponse.data.next;
+ }
+
+ return res.status(200).send(playlists);
+ } catch (error) {
+ logger.error('Error', { error });
+ return res.status(500).send({ message: "Server Error. Try again." });
+ }
+}
+
+module.exports = {
+ getUserPlaylists
+};
\ No newline at end of file
diff --git a/index.js b/index.js
index 00d9721..22160e9 100644
--- a/index.js
+++ b/index.js
@@ -4,37 +4,71 @@ const session = require("express-session");
const cors = require('cors');
const cookieParser = require('cookie-parser');
const helmet = require("helmet");
+const redis = require('redis');
+const connectRedis = require('connect-redis');
+const logger = require("./utils/logger")(module);
const app = express();
-app.use(
- session({
- secret: process.env.SESSION_SECRET,
- resave: true,
- saveUninitialized: true
- })
-);
+// Enable this if you run behind a proxy (e.g. nginx)
+app.set('trust proxy', 1);
+const RedisStore = connectRedis(session);
+
+// Configure Redis client
+const redisClient = redis.createClient({
+ // host: process.env.NODE_ENV === 'development'? 'localhost' : process.env.LIVE_URL,
+ host: 'localhost',
+ port: 6379,
+ legacyMode: true,
+});
+
+redisClient.connect()
+ .then(() => {
+ logger.info("Connected to Redis store");
+ })
+ .catch((error) => {
+ logger.error("Redis connection error", { error });
+ });
+
+// Configure session middleware
+app.use(session({
+ store: new RedisStore({ client: redisClient }),
+ secret: process.env.SESSION_SECRET,
+ resave: false,
+ saveUninitialized: false,
+ cookie: {
+ secure: 'auto', // if true only transmit cookie over https
+ httpOnly: true, // if true prevent client side JS from reading the cookie
+ }
+}));
+
+// Configure CORS options
const corsOptions = {
- origin: process.env.NODE_ENV === 'development' ? 'localhost:' + process.env.PORT : process.env.LIVE_URL,
+ origin: process.env.NODE_ENV === 'development' ? 'localhost:' + (process.env.PORT || 3000) : process.env.LIVE_URL,
}
app.use(cors(corsOptions));
app.use(cookieParser());
+// Configure helmet
app.use(helmet());
app.disable('x-powered-by')
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
+// Static
app.use(express.static(__dirname + '/public'));
+// Routes
app.use("/api/auth/", require("./routes/auth"));
+app.use("/api/playlists", require("./routes/playlists"));
+// Fallbacks
app.use((_req, res) => {
return res.status(404).send(
- "Oops! You're not supposed to know about this..."
+ "Guess the cat's out of the bag!"
);
});
diff --git a/package-lock.json b/package-lock.json
index f47a797..c6aa663 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"license": "MIT",
"dependencies": {
"axios": "^0.27.2",
+ "connect-redis": "^6.1.3",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
@@ -18,6 +19,7 @@
"express-validator": "^6.14.2",
"got": "^12.1.0",
"helmet": "^5.1.0",
+ "redis": "^4.2.0",
"winston": "^3.8.1"
},
"devDependencies": {
@@ -43,12 +45,65 @@
"kuler": "^2.0.0"
}
},
- "node_modules/@sindresorhus/is": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
- "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+ "node_modules/@redis/bloom": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.0.2.tgz",
+ "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/client": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.2.0.tgz",
+ "integrity": "sha512-a8Nlw5fv2EIAFJxTDSSDVUT7yfBGpZO96ybZXzQpgkyLg/dxtQ1uiwTc0EGfzg1mrPjZokeBSEGTbGXekqTNOg==",
+ "dependencies": {
+ "cluster-key-slot": "1.1.0",
+ "generic-pool": "3.8.2",
+ "yallist": "4.0.0"
+ },
"engines": {
- "node": ">=10"
+ "node": ">=14"
+ }
+ },
+ "node_modules/@redis/graph": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.0.1.tgz",
+ "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/json": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.3.tgz",
+ "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/search": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.0.6.tgz",
+ "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/time-series": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz",
+ "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz",
+ "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==",
+ "engines": {
+ "node": ">=14.16"
},
"funding": {
"url": "https://github.com/sindresorhus/is?sponsor=1"
@@ -143,9 +198,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "18.0.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz",
- "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ=="
+ "version": "18.0.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz",
+ "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw=="
},
"node_modules/@types/qs": {
"version": "6.9.7",
@@ -387,11 +442,22 @@
}
},
"node_modules/clone-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
- "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
+ "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"dependencies": {
"mimic-response": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
+ "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==",
+ "engines": {
+ "node": ">=0.10.0"
}
},
"node_modules/color": {
@@ -463,6 +529,14 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
+ "node_modules/connect-redis": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-6.1.3.tgz",
+ "integrity": "sha512-aaNluLlAn/3JPxRwdzw7lhvEoU6Enb+d83xnokUNhC9dktqBoawKWL+WuxinxvBLTz6q9vReTnUDnUslaz74aw==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -483,9 +557,9 @@
}
},
"node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
"engines": {
"node": ">= 0.6"
}
@@ -502,14 +576,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/cookie-parser/node_modules/cookie": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
- "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
@@ -719,6 +785,14 @@
"node": ">= 8.0.0"
}
},
+ "node_modules/express/node_modules/cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/fecha": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
@@ -791,9 +865,12 @@
}
},
"node_modules/form-data-encoder": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz",
- "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg=="
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.0.1.tgz",
+ "integrity": "sha512-Oy+P9w5mnO4TWXVgUiQvggNKPI9/ummcSt5usuIV6HkaLKigwzPpoenhEqmGmx3zHqm6ZLJ+CR/99N8JLinaEw==",
+ "engines": {
+ "node": ">= 14.17"
+ }
},
"node_modules/forwarded": {
"version": "0.2.0",
@@ -830,6 +907,14 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
+ "node_modules/generic-pool": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.8.2.tgz",
+ "integrity": "sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/get-intrinsic": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
@@ -867,18 +952,18 @@
}
},
"node_modules/got": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz",
- "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==",
+ "version": "12.2.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-12.2.0.tgz",
+ "integrity": "sha512-A81ll5Z8wzeCmSdIlWVMDWFKDo82v2nmOaMZDQNHKGInNqDBcle+CSb6BBiZcn/Aiefz/kSpo520WBKi9QAO/A==",
"dependencies": {
- "@sindresorhus/is": "^4.6.0",
+ "@sindresorhus/is": "^5.2.0",
"@szmarczak/http-timer": "^5.0.1",
"@types/cacheable-request": "^6.0.2",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^6.0.4",
"cacheable-request": "^7.0.2",
"decompress-response": "^6.0.0",
- "form-data-encoder": "1.7.1",
+ "form-data-encoder": "^2.0.1",
"get-stream": "^6.0.1",
"http2-wrapper": "^2.1.10",
"lowercase-keys": "^3.0.0",
@@ -924,9 +1009,9 @@
}
},
"node_modules/helmet": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.1.0.tgz",
- "integrity": "sha512-klsunXs8rgNSZoaUrNeuCiWUxyc+wzucnEnFejUg3/A+CaF589k9qepLZZ1Jehnzig7YbD4hEuscGXuBY3fq+g==",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.1.1.tgz",
+ "integrity": "sha512-/yX0oVZBggA9cLJh8aw3PPCfedBnbd7J2aowjzsaWwZh7/UFY0nccn/aHAggIgWUFfnykX8GKd3a1pSbrmlcVQ==",
"engines": {
"node": ">=12.0.0"
}
@@ -1057,9 +1142,9 @@
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
},
"node_modules/keyv": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.2.tgz",
- "integrity": "sha512-kn8WmodVBe12lmHpA6W8OY7SNh6wVR+Z+wZESF4iF5FCazaVXGWOtnbnvX0tMQ1bO+/TmOD9LziuYMvrIIs0xw==",
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz",
+ "integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==",
"dependencies": {
"compress-brotli": "^1.3.8",
"json-buffer": "3.0.1"
@@ -1457,17 +1542,33 @@
"node": ">=8.10.0"
}
},
+ "node_modules/redis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-4.2.0.tgz",
+ "integrity": "sha512-bCR0gKVhIXFg8zCQjXEANzgI01DDixtPZgIUZHBCmwqixnu+MK3Tb2yqGjh+HCLASQVVgApiwhNkv+FoedZOGQ==",
+ "dependencies": {
+ "@redis/bloom": "1.0.2",
+ "@redis/client": "1.2.0",
+ "@redis/graph": "1.0.1",
+ "@redis/json": "1.0.3",
+ "@redis/search": "1.0.6",
+ "@redis/time-series": "1.0.3"
+ }
+ },
"node_modules/resolve-alpn": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
},
"node_modules/responselike": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
- "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
+ "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"dependencies": {
"lowercase-keys": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/responselike/node_modules/lowercase-keys": {
@@ -1789,6 +1890,11 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
},
"dependencies": {
@@ -1807,10 +1913,50 @@
"kuler": "^2.0.0"
}
},
+ "@redis/bloom": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.0.2.tgz",
+ "integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==",
+ "requires": {}
+ },
+ "@redis/client": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.2.0.tgz",
+ "integrity": "sha512-a8Nlw5fv2EIAFJxTDSSDVUT7yfBGpZO96ybZXzQpgkyLg/dxtQ1uiwTc0EGfzg1mrPjZokeBSEGTbGXekqTNOg==",
+ "requires": {
+ "cluster-key-slot": "1.1.0",
+ "generic-pool": "3.8.2",
+ "yallist": "4.0.0"
+ }
+ },
+ "@redis/graph": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.0.1.tgz",
+ "integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==",
+ "requires": {}
+ },
+ "@redis/json": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.3.tgz",
+ "integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==",
+ "requires": {}
+ },
+ "@redis/search": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.0.6.tgz",
+ "integrity": "sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==",
+ "requires": {}
+ },
+ "@redis/time-series": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz",
+ "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==",
+ "requires": {}
+ },
"@sindresorhus/is": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
- "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz",
+ "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw=="
},
"@szmarczak/http-timer": {
"version": "5.0.1",
@@ -1898,9 +2044,9 @@
"dev": true
},
"@types/node": {
- "version": "18.0.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz",
- "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ=="
+ "version": "18.0.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz",
+ "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw=="
},
"@types/qs": {
"version": "6.9.7",
@@ -2096,13 +2242,18 @@
}
},
"clone-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
- "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
+ "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"requires": {
"mimic-response": "^1.0.0"
}
},
+ "cluster-key-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
+ "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw=="
+ },
"color": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
@@ -2166,6 +2317,11 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
+ "connect-redis": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-6.1.3.tgz",
+ "integrity": "sha512-aaNluLlAn/3JPxRwdzw7lhvEoU6Enb+d83xnokUNhC9dktqBoawKWL+WuxinxvBLTz6q9vReTnUDnUslaz74aw=="
+ },
"content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -2180,9 +2336,9 @@
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
},
"cookie-parser": {
"version": "1.4.6",
@@ -2191,13 +2347,6 @@
"requires": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
- },
- "dependencies": {
- "cookie": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
- "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
- }
}
},
"cookie-signature": {
@@ -2331,6 +2480,13 @@
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
+ },
+ "dependencies": {
+ "cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
+ }
}
},
"express-session": {
@@ -2413,9 +2569,9 @@
}
},
"form-data-encoder": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz",
- "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg=="
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.0.1.tgz",
+ "integrity": "sha512-Oy+P9w5mnO4TWXVgUiQvggNKPI9/ummcSt5usuIV6HkaLKigwzPpoenhEqmGmx3zHqm6ZLJ+CR/99N8JLinaEw=="
},
"forwarded": {
"version": "0.2.0",
@@ -2439,6 +2595,11 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
+ "generic-pool": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.8.2.tgz",
+ "integrity": "sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg=="
+ },
"get-intrinsic": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
@@ -2464,18 +2625,18 @@
}
},
"got": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz",
- "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==",
+ "version": "12.2.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-12.2.0.tgz",
+ "integrity": "sha512-A81ll5Z8wzeCmSdIlWVMDWFKDo82v2nmOaMZDQNHKGInNqDBcle+CSb6BBiZcn/Aiefz/kSpo520WBKi9QAO/A==",
"requires": {
- "@sindresorhus/is": "^4.6.0",
+ "@sindresorhus/is": "^5.2.0",
"@szmarczak/http-timer": "^5.0.1",
"@types/cacheable-request": "^6.0.2",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^6.0.4",
"cacheable-request": "^7.0.2",
"decompress-response": "^6.0.0",
- "form-data-encoder": "1.7.1",
+ "form-data-encoder": "^2.0.1",
"get-stream": "^6.0.1",
"http2-wrapper": "^2.1.10",
"lowercase-keys": "^3.0.0",
@@ -2503,9 +2664,9 @@
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"helmet": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.1.0.tgz",
- "integrity": "sha512-klsunXs8rgNSZoaUrNeuCiWUxyc+wzucnEnFejUg3/A+CaF589k9qepLZZ1Jehnzig7YbD4hEuscGXuBY3fq+g=="
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.1.1.tgz",
+ "integrity": "sha512-/yX0oVZBggA9cLJh8aw3PPCfedBnbd7J2aowjzsaWwZh7/UFY0nccn/aHAggIgWUFfnykX8GKd3a1pSbrmlcVQ=="
},
"http-cache-semantics": {
"version": "4.1.0",
@@ -2603,9 +2764,9 @@
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
},
"keyv": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.2.tgz",
- "integrity": "sha512-kn8WmodVBe12lmHpA6W8OY7SNh6wVR+Z+wZESF4iF5FCazaVXGWOtnbnvX0tMQ1bO+/TmOD9LziuYMvrIIs0xw==",
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz",
+ "integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==",
"requires": {
"compress-brotli": "^1.3.8",
"json-buffer": "3.0.1"
@@ -2894,15 +3055,28 @@
"picomatch": "^2.2.1"
}
},
+ "redis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-4.2.0.tgz",
+ "integrity": "sha512-bCR0gKVhIXFg8zCQjXEANzgI01DDixtPZgIUZHBCmwqixnu+MK3Tb2yqGjh+HCLASQVVgApiwhNkv+FoedZOGQ==",
+ "requires": {
+ "@redis/bloom": "1.0.2",
+ "@redis/client": "1.2.0",
+ "@redis/graph": "1.0.1",
+ "@redis/json": "1.0.3",
+ "@redis/search": "1.0.6",
+ "@redis/time-series": "1.0.3"
+ }
+ },
"resolve-alpn": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
},
"responselike": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
- "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
+ "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"requires": {
"lowercase-keys": "^2.0.0"
},
@@ -3152,6 +3326,11 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
}
diff --git a/package.json b/package.json
index 6716b79..1b7a624 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"homepage": "https://github.com/20kaushik02/spotify-manager#readme",
"dependencies": {
"axios": "^0.27.2",
+ "connect-redis": "^6.1.3",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
@@ -27,6 +28,7 @@
"express-validator": "^6.14.2",
"got": "^12.1.0",
"helmet": "^5.1.0",
+ "redis": "^4.2.0",
"winston": "^3.8.1"
},
"devDependencies": {
diff --git a/routes/playlists.js b/routes/playlists.js
new file mode 100644
index 0000000..5ee784b
--- /dev/null
+++ b/routes/playlists.js
@@ -0,0 +1,14 @@
+const router = require('express').Router();
+
+const { getUserPlaylists } = require('../controllers/playlists');
+const { isAuthenticated } = require('../middleware/authCheck');
+const validator = require("../validators");
+
+router.get(
+ "/user",
+ isAuthenticated,
+ validator.validate,
+ getUserPlaylists
+);
+
+module.exports = router;