api.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import config from "config";
  2. import async from "async";
  3. import CoreClass from "../core";
  4. class APIModule extends CoreClass {
  5. // eslint-disable-next-line require-jsdoc
  6. constructor() {
  7. super("api");
  8. }
  9. /**
  10. * Initialises the api module
  11. *
  12. * @returns {Promise} - returns promise (reject, resolve)
  13. */
  14. initialize() {
  15. return new Promise((resolve, reject) => {
  16. this.app = this.moduleManager.modules.app;
  17. this.stations = this.moduleManager.modules.stations;
  18. this.db = this.moduleManager.modules.db;
  19. this.playlists = this.moduleManager.modules.playlists;
  20. this.utils = this.moduleManager.modules.utils;
  21. this.punishments = this.moduleManager.modules.punishments;
  22. this.cache = this.moduleManager.modules.cache;
  23. this.notifications = this.moduleManager.modules.notifications;
  24. const SIDname = config.get("cookie.SIDname");
  25. const isLoggedIn = (req, res, next) => {
  26. let SID;
  27. async.waterfall(
  28. [
  29. next => {
  30. this.utils
  31. .runJob("PARSE_COOKIES", {
  32. cookieString: req.headers.cookie
  33. })
  34. .then(res => {
  35. SID = res[SIDname];
  36. next(null);
  37. })
  38. .catch(next);
  39. },
  40. next => {
  41. if (!SID) return next("No SID.");
  42. return next();
  43. },
  44. next => {
  45. this.cache
  46. .runJob("HGET", { table: "sessions", key: SID })
  47. .then(session => next(null, session));
  48. },
  49. (session, next) => {
  50. if (!session) return next("No session found.");
  51. session.refreshDate = Date.now();
  52. req.session = session;
  53. return this.cache
  54. .runJob("HSET", {
  55. table: "sessions",
  56. key: SID,
  57. value: session
  58. })
  59. .then(session => {
  60. next(null, session);
  61. });
  62. },
  63. (res, next) => {
  64. // check if a session's user / IP is banned
  65. this.punishments
  66. .runJob("GET_PUNISHMENTS", {})
  67. .then(punishments => {
  68. const isLoggedIn = !!(req.session && req.session.refreshDate);
  69. const userId = isLoggedIn ? req.session.userId : null;
  70. const banishment = { banned: false, ban: 0 };
  71. punishments.forEach(punishment => {
  72. if (punishment.expiresAt > banishment.ban) banishment.ban = punishment;
  73. if (
  74. punishment.type === "banUserId" &&
  75. isLoggedIn &&
  76. punishment.value === userId
  77. )
  78. banishment.banned = true;
  79. if (punishment.type === "banUserIp" && punishment.value === req.ip)
  80. banishment.banned = true;
  81. });
  82. req.banishment = banishment;
  83. next();
  84. })
  85. .catch(() => {
  86. next();
  87. });
  88. }
  89. ],
  90. err => {
  91. if (err) return res.json({ status: "error", message: "You are not logged in" });
  92. return next();
  93. }
  94. );
  95. };
  96. this.app
  97. .runJob("GET_APP", {})
  98. .then(response => {
  99. response.app.get("/", (req, res) => {
  100. res.json({
  101. status: "success",
  102. message: "Coming Soon"
  103. });
  104. });
  105. response.app.get("/export/privatePlaylist/:playlistId", isLoggedIn, (req, res) => {
  106. const { playlistId } = req.params;
  107. this.playlists
  108. .runJob("GET_PLAYLIST", { playlistId })
  109. .then(playlist => {
  110. if (playlist.createdBy === req.session.userId)
  111. res.json({ status: "success", playlist });
  112. else res.json({ status: "error", message: "You're not the owner." });
  113. })
  114. .catch(err => {
  115. res.json({ status: "error", message: err.message });
  116. });
  117. });
  118. // response.app.get("/debug_station", async (req, res) => {
  119. // const responseObject = {};
  120. // const stationModel = await this.db.runJob(
  121. // "GET_MODEL",
  122. // {
  123. // modelName: "station",
  124. // }
  125. // );
  126. // async.waterfall([
  127. // next => {
  128. // stationModel.find({}, next);
  129. // },
  130. // (stations, next) => {
  131. // responseObject.mongo = {
  132. // stations
  133. // };
  134. // next();
  135. // },
  136. // next => {
  137. // this.cache
  138. // .runJob("HGETALL", { table: "stations" })
  139. // .then(stations => {
  140. // next(null, stations);
  141. // })
  142. // .catch(next);
  143. // },
  144. // (stations, next) => {
  145. // responseObject.redis = {
  146. // stations
  147. // };
  148. // next();
  149. // },
  150. // next => {
  151. // responseObject.cryptoExamples = {};
  152. // responseObject.mongo.stations.forEach(station => {
  153. // const payloadName = `stations.nextSong?id=${station._id}`;
  154. // responseObject.cryptoExamples[station._id] = crypto
  155. // .createHash("md5")
  156. // .update(`_notification:${payloadName}_`)
  157. // .digest("hex")
  158. // });
  159. // next();
  160. // },
  161. // next => {
  162. // this.notifications.pub.keys("*", next);
  163. // },
  164. // (redisKeys, next) => {
  165. // responseObject.redis = {
  166. // ...redisKeys,
  167. // ttl: {}
  168. // };
  169. // async.eachLimit(redisKeys, 1, (redisKey, next) => {
  170. // this.notifications.pub.ttl(redisKey, (err, ttl) => {
  171. // responseObject.redis.ttl[redisKey] = ttl;
  172. // next(err);
  173. // })
  174. // }, next);
  175. // },
  176. // next => {
  177. // responseObject.debugLogs = this.moduleManager.debugLogs.stationIssue;
  178. // next();
  179. // },
  180. // next => {
  181. // responseObject.debugJobs = this.moduleManager.debugJobs;
  182. // next();
  183. // }
  184. // ], (err, response) => {
  185. // if (err) {
  186. // console.log(err);
  187. // return res.json({
  188. // error: err,
  189. // objectSoFar: responseObject
  190. // });
  191. // }
  192. // res.json(responseObject);
  193. // });
  194. // });
  195. // Object.keys(actions).forEach(namespace => {
  196. // Object.keys(actions[namespace]).forEach(action => {
  197. // let name = `/${namespace}/${action}`;
  198. // response.app.get(name, (req, res) => {
  199. // actions[namespace][action](null, result => {
  200. // if (typeof cb === "function")
  201. // return res.json(result);
  202. // });
  203. // });
  204. // });
  205. // });
  206. resolve();
  207. })
  208. .catch(err => {
  209. reject(err);
  210. });
  211. });
  212. }
  213. }
  214. export default new APIModule();