diff --git a/backend/app.ts b/backend/app.ts index 6c8448e..8b31631 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -10,10 +10,10 @@ import { ServerConfiguration } from 'ass'; * Custom middleware to attach the ass object (and construct the `host` property) */ function assMetaMiddleware(port: number, proxied: boolean): RequestHandler { - return (req: Request, _res: Response, next: NextFunction) => { - req.ass = { host: `${req.protocol}://${req.hostname}${proxied ? '' : `:${port}`}` }; - next(); - } + return (req: Request, _res: Response, next: NextFunction) => { + req.ass = { host: `${req.protocol}://${req.hostname}${proxied ? '' : `:${port}`}` }; + next(); + } } /** @@ -22,77 +22,77 @@ function assMetaMiddleware(port: number, proxied: boolean): RequestHandler { */ async function main() { - // Set default server configuration - const serverConfig: ServerConfiguration = { - host: '0.0.0.0', - port: 40115, - proxied: isProd() - }; - - // Replace with user details, if necessary - try { - const exists = await fs.pathExists(path.join('server.json')); - if (exists) { - - // Read file - const { host, port, proxied } = await fs.readJson(path.join('server.json')) as { host?: string, port?: number, proxied?: boolean }; - - // Set details, if available - if (host) serverConfig.host = host; - if (port) serverConfig.port = port; - if (proxied != undefined) serverConfig.proxied = proxied; - - log.debug('server.json', `${host ? `host=${host},` : ''}${port ? `port=${port},` : ''}${proxied != undefined ? `proxied=${proxied},` : ''}`); - } - } catch (err) { - log.error('Failed to read server.json'); - console.error(err); - throw err; - } - - // Set up Express - const app = express(); - - app.enable('case sensitive routing'); - app.disable('x-powered-by'); - - app.set('trust proxy', serverConfig.proxied); - app.set('view engine', 'pug'); - app.set('views', 'views2/'); - - // Middleware - app.use(log.express()); - app.use(BodyParserJson()); - app.use(assMetaMiddleware(serverConfig.port, serverConfig.proxied)); - - // CSS - app.use('/.css', epcss({ - cssPath: path.join('tailwind2.css'), - plugins: [ - tailwindcss, - (await import('autoprefixer')).default(), - (await import('cssnano')).default(), - (await import('@tinycreek/postcss-font-magician')).default(), - ], - warn: (warning: Error) => log.warn('PostCSS', warning.toString()) - })); - - app.get('/.ass.host', (req, res) => res.send(req.ass.host)); - - // Routing - app.use('/setup', (await import('./routers/setup')).router); - app.use('/', (await import('./routers/index')).router); - - // Host app - const userConfigExists = await fs.pathExists(path.join('userconfig.json')); - app.listen(serverConfig.port, serverConfig.host, () => log[userConfigExists ? 'success' : 'warn']('Server listening', userConfigExists ? 'Ready for uploads' : 'Setup required', `click http://127.0.0.1:${serverConfig.port}`)); + // Set default server configuration + const serverConfig: ServerConfiguration = { + host: '0.0.0.0', + port: 40115, + proxied: isProd() + }; + + // Replace with user details, if necessary + try { + const exists = await fs.pathExists(path.join('server.json')); + if (exists) { + + // Read file + const { host, port, proxied } = await fs.readJson(path.join('server.json')) as { host?: string, port?: number, proxied?: boolean }; + + // Set details, if available + if (host) serverConfig.host = host; + if (port) serverConfig.port = port; + if (proxied != undefined) serverConfig.proxied = proxied; + + log.debug('server.json', `${host ? `host=${host},` : ''}${port ? `port=${port},` : ''}${proxied != undefined ? `proxied=${proxied},` : ''}`); + } + } catch (err) { + log.error('Failed to read server.json'); + console.error(err); + throw err; + } + + // Set up Express + const app = express(); + + app.enable('case sensitive routing'); + app.disable('x-powered-by'); + + app.set('trust proxy', serverConfig.proxied); + app.set('view engine', 'pug'); + app.set('views', 'views2/'); + + // Middleware + app.use(log.express()); + app.use(BodyParserJson()); + app.use(assMetaMiddleware(serverConfig.port, serverConfig.proxied)); + + // CSS + app.use('/.css', epcss({ + cssPath: path.join('tailwind2.css'), + plugins: [ + tailwindcss, + (await import('autoprefixer')).default(), + (await import('cssnano')).default(), + (await import('@tinycreek/postcss-font-magician')).default(), + ], + warn: (warning: Error) => log.warn('PostCSS', warning.toString()) + })); + + app.get('/.ass.host', (req, res) => res.send(req.ass.host)); + + // Routing + app.use('/setup', (await import('./routers/setup')).router); + app.use('/', (await import('./routers/index')).router); + + // Host app + const userConfigExists = await fs.pathExists(path.join('userconfig.json')); + app.listen(serverConfig.port, serverConfig.host, () => log[userConfigExists ? 'success' : 'warn']('Server listening', userConfigExists ? 'Ready for uploads' : 'Setup required', `click http://127.0.0.1:${serverConfig.port}`)); } // Launch log const pkg = fs.readJsonSync(path.join('package.json')) as { name: string, version: string }; log.blank() - .info(pkg.name, pkg.version) - .blank(); + .info(pkg.name, pkg.version) + .blank(); // Start program main().catch(() => process.exit(1)); @@ -100,10 +100,10 @@ main().catch(() => process.exit(1)); // Exit tasks ['SIGINT', 'SIGTERM'].forEach((signal) => process.addListener(signal as any, () => { - // Hide ^C in console output - process.stdout.write('\r'); + // Hide ^C in console output + process.stdout.write('\r'); - // Log then exit - log.info('Exiting', `received ${signal}`); - process.exit(); + // Log then exit + log.info('Exiting', `received ${signal}`); + process.exit(); })); diff --git a/backend/routers/setup.ts b/backend/routers/setup.ts index 0a352de..fb6834f 100644 --- a/backend/routers/setup.ts +++ b/backend/routers/setup.ts @@ -13,22 +13,22 @@ router.get('/ui.js', (req, res) => userConfigExists() ? res.send('') : res.type( // Setup route router.post('/', BodyParserJson(), (req, res) => { - if (userConfigExists()) - return res.status(409).json({ success: false, message: 'User config already exists' }); + if (userConfigExists()) + return res.status(409).json({ success: false, message: 'User config already exists' }); - log.debug('Running setup'); + log.debug('Running setup'); - // Parse body - const body = req.body as UserConfiguration; + // Parse body + const body = req.body as UserConfiguration; - // temp: print body for testing - log.debug('Uploads dir', body.uploadsDir); - log.debug('ID type', body.idType); - log.debug('ID size', body.idSize.toString()); - log.debug('Gfy size', body.gfySize.toString()); - log.debug('Max file size', body.maximumFileSize.toString()); + // temp: print body for testing + log.debug('Uploads dir', body.uploadsDir); + log.debug('ID type', body.idType); + log.debug('ID size', body.idSize.toString()); + log.debug('Gfy size', body.gfySize.toString()); + log.debug('Max file size', body.maximumFileSize.toString()); - return res.json({ success: true }); + return res.json({ success: true }); }); export { router }; diff --git a/common/global.d.ts b/common/global.d.ts index e1f0bdb..047b91f 100644 --- a/common/global.d.ts +++ b/common/global.d.ts @@ -1,19 +1,19 @@ import { Request, Response } from 'express'; declare global { - namespace Express { - interface Request { + namespace Express { + interface Request { - /** - * ass-specific request items - */ - ass: { + /** + * ass-specific request items + */ + ass: { - /** - * Combination of {protocol}://{hostname} - */ - host: string - } - } - } + /** + * Combination of {protocol}://{hostname} + */ + host: string + } + } + } } diff --git a/common/types.d.ts b/common/types.d.ts index 3569578..22a1147 100644 --- a/common/types.d.ts +++ b/common/types.d.ts @@ -1,24 +1,24 @@ declare module 'ass' { - type IdType = 'random' | 'original' | 'gfycat' | 'timestamp' | 'zws' + type IdType = 'random' | 'original' | 'gfycat' | 'timestamp' | 'zws' - /** - * Core Express server config. - * This is separate from the user configuration starting in 0.15.0 - */ - interface ServerConfiguration { - host: string, - port: number, - proxied: boolean - } + /** + * Core Express server config. + * This is separate from the user configuration starting in 0.15.0 + */ + interface ServerConfiguration { + host: string, + port: number, + proxied: boolean + } - interface UserConfiguration { - uploadsDir: string; - idType: IdType; - idSize: number; - gfySize: number; - maximumFileSize: number; - } + interface UserConfiguration { + uploadsDir: string; + idType: IdType; + idSize: number; + gfySize: number; + maximumFileSize: number; + } } //#region Dummy modules @@ -27,9 +27,9 @@ declare module '@tinycreek/postcss-font-magician'; // don't commit /* future UserConfig options: - mediaStrict: boolean; - viewDirect: boolean; - viewDirectDiscord: boolean; - adminWebhook: {} - s3: {} + mediaStrict: boolean; + viewDirect: boolean; + viewDirectDiscord: boolean; + adminWebhook: {} + s3: {} */ diff --git a/frontend/setup.mts b/frontend/setup.mts index bb59fd7..b4d1970 100644 --- a/frontend/setup.mts +++ b/frontend/setup.mts @@ -7,37 +7,37 @@ const errAlert = (logTitle: string, err: any, stream: 'error' | 'warn' = 'error' // * Wait for the document to be ready document.addEventListener('DOMContentLoaded', () => { - const dirInputElm = document.querySelector('#dir') as SlInput; - const idTypeInputElm = document.querySelector('#idtype') as SlInput; - const idSizeInputElm = document.querySelector('#idsize') as SlInput; - const gfySizeInputElm = document.querySelector('#gfysize') as SlInput; - const fileSizeInputElm = document.querySelector('#filesize') as SlInput; - const submitButtonElm = document.querySelector('#submit') as SlButton; + const dirInputElm = document.querySelector('#dir') as SlInput; + const idTypeInputElm = document.querySelector('#idtype') as SlInput; + const idSizeInputElm = document.querySelector('#idsize') as SlInput; + const gfySizeInputElm = document.querySelector('#gfysize') as SlInput; + const fileSizeInputElm = document.querySelector('#filesize') as SlInput; + const submitButtonElm = document.querySelector('#submit') as SlButton; - // * Setup button click handler - submitButtonElm.addEventListener('click', async () => { + // * Setup button click handler + submitButtonElm.addEventListener('click', async () => { - const config: UserConfiguration = { - uploadsDir: dirInputElm.value, - idType: idTypeInputElm.value as IdType, - idSize: parseInt(idSizeInputElm.value), - gfySize: parseInt(gfySizeInputElm.value), - maximumFileSize: parseInt(fileSizeInputElm.value), - }; + const config: UserConfiguration = { + uploadsDir: dirInputElm.value, + idType: idTypeInputElm.value as IdType, + idSize: parseInt(idSizeInputElm.value), + gfySize: parseInt(gfySizeInputElm.value), + maximumFileSize: parseInt(fileSizeInputElm.value), + }; - fetch('/setup', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(config) - }) - .then((res) => res.json()) - .then((data: { - success: boolean, - message: string - }) => { - if (!data.success) throw new Error(data.message); - else alert('good?'); - }) - .catch((err) => errAlert('POST to /setup failed!', err)); - }); + fetch('/setup', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(config) + }) + .then((res) => res.json()) + .then((data: { + success: boolean, + message: string + }) => { + if (!data.success) throw new Error(data.message); + else alert('good?'); + }) + .catch((err) => errAlert('POST to /setup failed!', err)); + }); });