pull/243/head
Josh Moore 11 months ago
parent 83c89a9e25
commit 352cb2b636

@ -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();
}));

@ -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 };

26
common/global.d.ts vendored

@ -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
}
}
}
}

44
common/types.d.ts vendored

@ -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: {}
*/

@ -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));
});
});

Loading…
Cancel
Save