handlers.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. const requestlib = require ( 'request' );
  2. const formidable = require ( 'formidable' );
  3. const util = require ( 'util' );
  4. const Config = require ( './config.json' );
  5. const WebServer = require ( './index.js' );
  6. const fileutil = require ( './fileutil.js' );
  7. const logger = require ( './logger.js' );
  8. function verifyUserCredentials ( access_token, token_type, success, failure )
  9. {
  10. requestlib.get ( {
  11. url: 'https://discordapp.com/api/users/@me',
  12. headers: { authorization: token_type + ' ' + access_token }
  13. }, function ( error, res, body )
  14. {
  15. if ( !error )
  16. {
  17. success ( JSON.parse ( body ) );
  18. }
  19. else failure ( error );
  20. } );
  21. }
  22. function displayApiError ( request, response, code, message )
  23. {
  24. response.writeHead ( code, { 'Content-Type': 'application/json' } );
  25. response.write ( JSON.stringify ( { success: false, message: message } ) );
  26. response.end ( );
  27. }
  28. WebServer.registerRequestHandler ( '/process', function ( request, response, requestData, cookies, session )
  29. {
  30. if ( request.method.toLowerCase ( ) == 'post' )
  31. {
  32. if ( !session.variables.discordAuth && Config.auth_required )
  33. {
  34. displayApiError ( request, response, 403, 'authentication required' );
  35. return;
  36. }
  37. let form = new formidable.IncomingForm ( );
  38. form.uploadDir = './uploads';
  39. form.maxFileSize = 10 * 1024 * 1024;
  40. form.parse ( request, function ( error, fields, files )
  41. {
  42. if ( error ) return displayApiError ( request, response, 400, 'invalid request' );
  43. if ( !files.song )
  44. {
  45. response.writeHead ( 400, { 'Content-Type': 'application/json' } );
  46. response.write ( JSON.stringify ( { success: false, message: 'no files uploaded' } ) );
  47. response.end ( );
  48. return;
  49. }
  50. let path = files.song.path;
  51. fileutil.handleUploadedFile ( path, function ( )
  52. {
  53. // success
  54. response.writeHead ( 200, { 'Content-Type': 'application/json' } );
  55. response.write ( JSON.stringify ( { success: true, message: 'upload complete' } ) );
  56. response.end ( );
  57. }, function ( )
  58. {
  59. return displayApiError ( request, response, 400, 'invalid file format' );
  60. } );
  61. } );
  62. }
  63. else displayApiError ( request, response, 405, 'method not allowed' );
  64. } );
  65. WebServer.registerRequestHandler ( '/upload', function ( request, response, requestData, cookies, session )
  66. {
  67. if ( session.variables.discordAuth )
  68. {
  69. response.writeHead ( 200, { 'Content-Type': 'text/html' } );
  70. let userdata = session.variables.discordAuth.userdata;
  71. WebServer.renderTemplate ( 'uploadform', request, response,
  72. {
  73. username: userdata.username,
  74. useravatar: 'https://cdn.discordapp.com/avatars/' + userdata.id + '/' + userdata.avatar + '.png',
  75. discriminator: userdata.discriminator
  76. } );
  77. response.end ( );
  78. }
  79. else
  80. {
  81. return WebServer.redirect ( request, response, '/' );
  82. }
  83. } );
  84. WebServer.registerRequestHandler ( '/auth', function ( request, response, requestData, cookies, session )
  85. {
  86. if ( session.variables.discordAuth ) return WebServer.redirect ( request, response, '/upload' );
  87. if ( requestData.query && requestData.query.code && !session.variables.discordAuth )
  88. {
  89. let code = requestData.query.code;
  90. requestlib.post ( {
  91. url: 'https://discordapp.com/api/oauth2/token',
  92. form:
  93. {
  94. client_id: Config.client_id,
  95. client_secret: Config.client_secret,
  96. grant_type: 'authorization_code',
  97. code: code,
  98. redirect_uri: Config.discord_auth.redirect_uri,
  99. scope: 'identify'
  100. }
  101. }, function ( error, res, body )
  102. {
  103. if ( !error )
  104. {
  105. let json = JSON.parse ( body );
  106. if ( json.access_token )
  107. {
  108. // return WebServer.redirect ( request, response, 'https://localhost:3000/upload' );
  109. verifyUserCredentials ( json.access_token, json.token_type, function ( userdata )
  110. {
  111. logger.log ( '[Info/WebServer] Authenticated discord user ' + userdata.id );
  112. session.variables.discordAuth = { };
  113. session.variables.discordAuth.data = json;
  114. session.variables.discordAuth.userdata = userdata;
  115. return WebServer.redirect ( request, response, 'upload' );
  116. }, function ( )
  117. {
  118. response.writeHead ( 200, { 'Content-Type': 'text/html' } );
  119. response.write ( '<h1>Auth Failed</h1>' );
  120. response.end ( );
  121. } );
  122. }
  123. else return WebServer.redirect ( request, response, '/' );
  124. }
  125. else throw new Error ( error );
  126. } );
  127. }
  128. else
  129. {
  130. logger.log ( '[Info/WebServer] Invalid Auth, no code provided. Redirecting...' );
  131. return WebServer.redirect ( request, response, Config.discord_auth.redirect );
  132. }
  133. } );
  134. WebServer.registerRequestHandler ( '/template_test', function ( request, response, requestData, cookies, session )
  135. {
  136. response.writeHead ( 200, { 'Content-Type': 'text/html' } );
  137. WebServer.renderTemplate ( 'uploadform', request, response,
  138. {
  139. username: 'huj',
  140. useravatar: 'https://cdn.discordapp.com/avatars/276791868141076480/4a3736a3aa445bec61dde599040d0ec7.png',
  141. discriminator: '6969'
  142. } );
  143. response.end ( );
  144. } );
  145. WebServer.registerRequestHandler ( '/session_test', function ( request, response, requestData, cookies, session )
  146. {
  147. if ( !session.variables.testRandomNumber ) session.variables.testRandomNumber = Math.floor ( Math.random ( ) * 2000 );
  148. response.writeHead ( 200, { 'Content-Type': 'text/html' } );
  149. response.write ( '<h1>Session Data</h1>' );
  150. response.write ( '<p>Session ID: ' + session.id + '</p>' );
  151. response.write ( '<p>Session Started: ' + session.started + '</p>' );
  152. response.write ( '<p>Session Expires: ' + session.expires + '</p>' );
  153. response.write ( '<p>Lifetime Remaining: ' + ( session.expires - Date.now ( ) ) + '</p>' );
  154. response.write ( '<p>Secret Number: ' + session.variables.testRandomNumber + '</p>' );
  155. response.write ( '<p>Variables: ' + JSON.stringify ( session.variables ) + '</p>' )
  156. response.end ( );
  157. } );