api.js 6.8 KB

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