@@ -8,9 +8,14 @@ import mongoose from 'mongoose'
88import nodemailer from 'nodemailer'
99import * as Sentry from '@sentry/node'
1010import * as Tracing from '@sentry/tracing'
11+ import config from '../../config'
12+ import validateConfig from './utils/validateConfig'
1113import handleAnnounce from './middleware/announce'
1214import auth from './middleware/auth'
13- import { userTrackerRoutes , otherTrackerRoutes } from './routes/tracker'
15+ import {
16+ createUserTrackerRoutes ,
17+ createOtherTrackerRoutes ,
18+ } from './routes/tracker'
1419import {
1520 register ,
1621 login ,
@@ -69,168 +74,173 @@ import {
6974 addCandidate ,
7075 acceptCandidate ,
7176} from './controllers/request'
72- import validateConfig from './utils/validateConfig'
7377import createAdminUser from './setup/createAdminUser'
7478
75- validateConfig ( )
76-
77- if ( process . env . SENTRY_DSN ) {
78- Sentry . init ( {
79- dsn : process . env . SENTRY_DSN ,
80- tracesSampleRate : 1.0 ,
81- environment :
82- process . env . NODE_ENV === 'production' ? 'production' : 'development' ,
83- } )
79+ let mail
8480
85- Sentry . setContext ( 'deployment' , {
86- name : process . env . SQ_SITE_NAME ,
87- url : process . env . SQ_BASE_URL ,
88- adminEmail : process . env . SQ_ADMIN_EMAIL ,
89- } )
90- }
91-
92- const connectToDb = ( ) => {
93- console . log ( '[sq] initiating db connection...' )
94- mongoose
95- . connect ( process . env . SQ_MONGO_URL , {
96- useNewUrlParser : true ,
97- useFindAndModify : false ,
98- useUnifiedTopology : true ,
81+ validateConfig ( config ) . then ( ( ) => {
82+ if ( process . env . SENTRY_DSN ) {
83+ Sentry . init ( {
84+ dsn : process . env . SENTRY_DSN ,
85+ tracesSampleRate : 1.0 ,
86+ environment :
87+ process . env . NODE_ENV === 'production' ? 'production' : 'development' ,
9988 } )
100- . catch ( ( e ) => {
101- console . error ( `[sq] error on initial db connection: ${ e . message } ` )
102- setTimeout ( connectToDb , 5000 )
89+
90+ Sentry . setContext ( 'deployment' , {
91+ name : process . env . SQ_SITE_NAME ,
92+ url : process . env . SQ_BASE_URL ,
93+ adminEmail : process . env . SQ_ADMIN_EMAIL ,
10394 } )
104- }
105- connectToDb ( )
95+ }
10696
107- mongoose . connection . once ( 'open' , ( ) => {
108- console . log ( '[sq] connected to mongodb successfully' )
109- createAdminUser ( )
110- } )
97+ const connectToDb = ( ) => {
98+ console . log ( '[sq] initiating db connection...' )
99+ mongoose
100+ . connect ( process . env . SQ_MONGO_URL , {
101+ useNewUrlParser : true ,
102+ useFindAndModify : false ,
103+ useUnifiedTopology : true ,
104+ } )
105+ . catch ( ( e ) => {
106+ console . error ( `[sq] error on initial db connection: ${ e . message } ` )
107+ setTimeout ( connectToDb , 5000 )
108+ } )
109+ }
110+ connectToDb ( )
111111
112- export const mail = nodemailer . createTransport ( {
113- host : process . env . SQ_SMTP_HOST ,
114- port : process . env . SQ_SMTP_PORT ,
115- secure : process . env . SQ_SMTP_SECURE ,
116- auth : {
117- user : process . env . SQ_SMTP_USER ,
118- pass : process . env . SQ_SMTP_PASS ,
119- } ,
120- } )
112+ mongoose . connection . once ( 'open' , async ( ) => {
113+ console . log ( '[sq] connected to mongodb successfully' )
114+ await createAdminUser ( )
115+ } )
116+
117+ mail = nodemailer . createTransport ( {
118+ host : process . env . SQ_SMTP_HOST ,
119+ port : process . env . SQ_SMTP_PORT ,
120+ secure : process . env . SQ_SMTP_SECURE ,
121+ auth : {
122+ user : process . env . SQ_SMTP_USER ,
123+ pass : process . env . SQ_SMTP_PASS ,
124+ } ,
125+ } )
121126
122- const app = express ( )
123- app . set ( 'trust proxy' , true )
124- app . disable ( 'x-powered-by' )
125-
126- const colorizeStatus = ( status ) => {
127- if ( ! status ) return '?'
128- if ( status . startsWith ( '2' ) ) {
129- return chalk . green ( status )
130- } else if ( status . startsWith ( '4' ) || status . startsWith ( '5' ) ) {
131- return chalk . red ( status )
132- } else {
133- return chalk . cyan ( status )
127+ const app = express ( )
128+ app . set ( 'trust proxy' , true )
129+ app . disable ( 'x-powered-by' )
130+
131+ const colorizeStatus = ( status ) => {
132+ if ( ! status ) return '?'
133+ if ( status . startsWith ( '2' ) ) {
134+ return chalk . green ( status )
135+ } else if ( status . startsWith ( '4' ) || status . startsWith ( '5' ) ) {
136+ return chalk . red ( status )
137+ } else {
138+ return chalk . cyan ( status )
139+ }
134140 }
135- }
136-
137- app . use (
138- morgan ( ( tokens , req , res ) => {
139- return [
140- chalk . grey ( new Date ( ) . toISOString ( ) ) ,
141- chalk . yellow ( tokens . method ( req , res ) ) ,
142- tokens . url ( req , res ) ,
143- colorizeStatus ( tokens . status ( req , res ) ) ,
144- `(${ tokens [ 'response-time' ] ( req , res ) } ms)` ,
145- ] . join ( ' ' )
141+
142+ app . use (
143+ morgan ( ( tokens , req , res ) => {
144+ return [
145+ chalk . grey ( new Date ( ) . toISOString ( ) ) ,
146+ chalk . yellow ( tokens . method ( req , res ) ) ,
147+ tokens . url ( req , res ) ,
148+ colorizeStatus ( tokens . status ( req , res ) ) ,
149+ `(${ tokens [ 'response-time' ] ( req , res ) } ms)` ,
150+ ] . join ( ' ' )
151+ } )
152+ )
153+
154+ // custom logic implementing user tracking, ratio control etc
155+ app . use ( '/sq/*/announce' , handleAnnounce )
156+
157+ // proxy and manipulate tracker routes
158+ const userTrackerRoutes = createUserTrackerRoutes ( )
159+ const otherTrackerRoutes = createOtherTrackerRoutes ( )
160+ app . use ( '/sq/*/announce' , userTrackerRoutes )
161+ app . use ( '/sq/*/scrape' , userTrackerRoutes )
162+ app . use ( '/stats' , otherTrackerRoutes )
163+
164+ app . use ( bodyParser . json ( ) )
165+ app . use ( cookieParser ( ) )
166+ app . use ( cors ( ) )
167+
168+ // root
169+ app . get ( '/' , ( req , res ) =>
170+ res . send ( `■ sqtracker running: ${ process . env . SQ_SITE_NAME } ` ) . status ( 200 )
171+ )
172+
173+ // auth routes
174+ app . post ( '/register' , register )
175+ app . post ( '/login' , login )
176+ app . post ( '/reset-password/initiate' , initiatePasswordReset )
177+ app . post ( '/reset-password/finalise' , finalisePasswordReset )
178+ app . post ( '/verify-email' , verifyUserEmail )
179+
180+ // rss feed (auth handled in cookies)
181+ app . get ( '/rss' , rssFeed )
182+
183+ // torrent file download (can download without auth, will not be able to announce)
184+ app . get ( '/torrent/download/:infoHash/:userId' , downloadTorrent )
185+
186+ // everything from here on requires user auth
187+ app . use ( auth )
188+
189+ // user/account routes
190+ app . get ( '/account/invites' , fetchInvites )
191+ app . post ( '/account/generate-invite' , generateInvite )
192+ app . post ( '/account/change-password' , changePassword )
193+ app . get ( '/account/get-role' , getUserRole )
194+ app . get ( '/account/get-verified' , getUserVerifiedEmailStatus )
195+ app . post ( '/account/buy' , buyItems )
196+ app . get ( '/user/:username' , fetchUser )
197+ app . post ( '/user/ban/:username' , banUser )
198+ app . post ( '/user/unban/:username' , unbanUser )
199+ app . get ( '/account/totp/generate' , generateTotpSecret )
200+ app . post ( '/account/totp/enable' , enableTotp )
201+ app . post ( '/account/totp/disable' , disableTotp )
202+
203+ // torrent routes
204+ app . post ( '/torrent/upload' , uploadTorrent )
205+ app . get ( '/torrent/info/:infoHash' , fetchTorrent )
206+ app . delete ( '/torrent/delete/:infoHash' , deleteTorrent )
207+ app . post ( '/torrent/comment/:infoHash' , addCommentTorrent )
208+ app . post ( '/torrent/vote/:infoHash/:vote' , addVote )
209+ app . post ( '/torrent/unvote/:infoHash/:vote' , removeVote )
210+ app . post ( '/torrent/report/:infoHash' , createReport )
211+ app . post ( '/torrent/toggle-freeleech/:infoHash' , toggleFreeleech )
212+ app . get ( '/torrents/latest' , listLatest )
213+ app . get ( '/torrents/search' , searchTorrents )
214+
215+ // announcement routes
216+ app . post ( '/announcements/new' , createAnnouncement )
217+ app . get ( '/announcements/pinned' , getPinnedAnnouncements )
218+ app . get ( '/announcements/:slug' , fetchAnnouncement )
219+ app . get ( '/announcements/page/:page' , getAnnouncements )
220+ app . delete ( '/announcements/:slug' , deleteAnnouncement )
221+ app . post ( '/announcements/pin/:announcementId/:action' , pinAnnouncement )
222+ app . post ( '/announcements/edit/:announcementId' , editAnnouncement )
223+ app . post ( '/announcements/comment/:announcementId' , addCommentAnnouncement )
224+
225+ // moderation routes
226+ app . get ( '/reports/page/:page' , getReports )
227+ app . post ( '/reports/resolve/:reportId' , setReportResolved )
228+ app . get ( '/reports/:reportId' , fetchReport )
229+ app . get ( '/admin/stats' , getStats )
230+
231+ // request routes
232+ app . post ( '/requests/new' , createRequest )
233+ app . get ( '/requests/page/:page' , getRequests )
234+ app . get ( '/requests/:index' , fetchRequest )
235+ app . delete ( '/requests/:index' , deleteRequest )
236+ app . post ( '/requests/comment/:requestId' , addCommentRequest )
237+ app . post ( '/requests/suggest/:requestId' , addCandidate )
238+ app . post ( '/requests/accept/:requestId' , acceptCandidate )
239+
240+ const port = process . env . SQ_PORT || 3001
241+ app . listen ( port , ( ) => {
242+ console . log ( `[sq] ■ sqtracker running http://localhost:${ port } ` )
146243 } )
147- )
148-
149- // custom logic implementing user tracking, ratio control etc
150- app . use ( '/sq/*/announce' , handleAnnounce )
151-
152- // proxy and manipulate tracker routes
153- app . use ( '/sq/*/announce' , userTrackerRoutes )
154- app . use ( '/sq/*/scrape' , userTrackerRoutes )
155- app . use ( '/stats' , otherTrackerRoutes )
156-
157- app . use ( bodyParser . json ( ) )
158- app . use ( cookieParser ( ) )
159- app . use ( cors ( ) )
160-
161- // root
162- app . get ( '/' , ( req , res ) =>
163- res . send ( `■ sqtracker running: ${ process . env . SQ_SITE_NAME } ` ) . status ( 200 )
164- )
165-
166- // auth routes
167- app . post ( '/register' , register )
168- app . post ( '/login' , login )
169- app . post ( '/reset-password/initiate' , initiatePasswordReset )
170- app . post ( '/reset-password/finalise' , finalisePasswordReset )
171- app . post ( '/verify-email' , verifyUserEmail )
172-
173- // rss feed (auth handled in cookies)
174- app . get ( '/rss' , rssFeed )
175-
176- // torrent file download (can download without auth, will not be able to announce)
177- app . get ( '/torrent/download/:infoHash/:userId' , downloadTorrent )
178-
179- // everything from here on requires user auth
180- app . use ( auth )
181-
182- // user/account routes
183- app . get ( '/account/invites' , fetchInvites )
184- app . post ( '/account/generate-invite' , generateInvite )
185- app . post ( '/account/change-password' , changePassword )
186- app . get ( '/account/get-role' , getUserRole )
187- app . get ( '/account/get-verified' , getUserVerifiedEmailStatus )
188- app . post ( '/account/buy' , buyItems )
189- app . get ( '/user/:username' , fetchUser )
190- app . post ( '/user/ban/:username' , banUser )
191- app . post ( '/user/unban/:username' , unbanUser )
192- app . get ( '/account/totp/generate' , generateTotpSecret )
193- app . post ( '/account/totp/enable' , enableTotp )
194- app . post ( '/account/totp/disable' , disableTotp )
195-
196- // torrent routes
197- app . post ( '/torrent/upload' , uploadTorrent )
198- app . get ( '/torrent/info/:infoHash' , fetchTorrent )
199- app . delete ( '/torrent/delete/:infoHash' , deleteTorrent )
200- app . post ( '/torrent/comment/:infoHash' , addCommentTorrent )
201- app . post ( '/torrent/vote/:infoHash/:vote' , addVote )
202- app . post ( '/torrent/unvote/:infoHash/:vote' , removeVote )
203- app . post ( '/torrent/report/:infoHash' , createReport )
204- app . post ( '/torrent/toggle-freeleech/:infoHash' , toggleFreeleech )
205- app . get ( '/torrents/latest' , listLatest )
206- app . get ( '/torrents/search' , searchTorrents )
207-
208- // announcement routes
209- app . post ( '/announcements/new' , createAnnouncement )
210- app . get ( '/announcements/pinned' , getPinnedAnnouncements )
211- app . get ( '/announcements/:slug' , fetchAnnouncement )
212- app . get ( '/announcements/page/:page' , getAnnouncements )
213- app . delete ( '/announcements/:slug' , deleteAnnouncement )
214- app . post ( '/announcements/pin/:announcementId/:action' , pinAnnouncement )
215- app . post ( '/announcements/edit/:announcementId' , editAnnouncement )
216- app . post ( '/announcements/comment/:announcementId' , addCommentAnnouncement )
217-
218- // moderation routes
219- app . get ( '/reports/page/:page' , getReports )
220- app . post ( '/reports/resolve/:reportId' , setReportResolved )
221- app . get ( '/reports/:reportId' , fetchReport )
222- app . get ( '/admin/stats' , getStats )
223-
224- // request routes
225- app . post ( '/requests/new' , createRequest )
226- app . get ( '/requests/page/:page' , getRequests )
227- app . get ( '/requests/:index' , fetchRequest )
228- app . delete ( '/requests/:index' , deleteRequest )
229- app . post ( '/requests/comment/:requestId' , addCommentRequest )
230- app . post ( '/requests/suggest/:requestId' , addCandidate )
231- app . post ( '/requests/accept/:requestId' , acceptCandidate )
232-
233- const port = process . env . SQ_PORT || 3001
234- app . listen ( port , ( ) => {
235- console . log ( `[sq] ■ sqtracker running http://localhost:${ port } ` )
236244} )
245+
246+ export { mail }
0 commit comments