api.js 11 KB

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