started working on moving to typescript [WIP]

- slightly changed concept of routers, graphql, sockets to make things easier to implement
- WARNING! this is experimental and might not work right now
typescript
Trivernis 5 years ago
parent b9d65d6a84
commit aff0579a45

1
.gitignore vendored

@ -6,3 +6,4 @@ tmp
config.yaml
sessions
sessions-journal
dist

116
app.js

@ -1,116 +0,0 @@
const createError = require('http-errors'),
path = require('path'),
express = require('express'),
cookieParser = require('cookie-parser'),
logger = require('morgan'),
compileSass = require('express-compile-sass'),
minify = require('express-minify'),
compression = require('compression'),
uglifyEs = require('uglify-es'),
session = require('express-session'),
pgSession = require('connect-pg-simple')(session),
fsx = require('fs-extra'),
graphqlHTTP = require('express-graphql'),
{buildSchema} = require('graphql'),
{importSchema} = require('graphql-import'),
globals = require('./lib/globals'),
settings = globals.settings,
indexRouter = require('./routes/index'),
//usersRouter = require('./routes/users'),
//riddleRouter = require('./routes/riddle'),
changelogRouter = require('./routes/changelog'),
bingoRouter = require('./routes/bingo');
let app = require('express')(),
server = require('http').Server(app),
io = require('socket.io')(server);
async function init() {
// grapql default resolver
let graphqlResolver = async (request, response) => {
return {
time: Date.now(),
bingo: await bingoRouter.graphqlResolver(request, response),
acceptCookies: () => {
request.session.acceptedCookies = true;
return true;
}
};
};
// database setup
let pgPool = globals.pgPool;
await pgPool.query(fsx.readFileSync('./sql/init.sql', 'utf-8'));
let bingoIo = io.of('/bingo');
await bingoRouter.init(bingoIo, io);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.set('trust proxy', 1);
app.use(compression());
app.use(minify({
uglifyJsModule: uglifyEs
}));
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(session({
store: new pgSession({
pool: pgPool,
tableName: 'user_sessions'
}),
secret: settings.sessions.secret,
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000 // maxAge 7 days
}
}));
app.use('/sass', compileSass({
root: './public/stylesheets/sass',
sourceMap: true,
watchFiles: (process.env.NODE_ENV !== 'development'),
logToConsole: true
}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
//app.use('/users', usersRouter);
//app.use(/\/riddle(\/.*)?/, riddleRouter);
app.use('/bingo', bingoRouter);
app.use('/changelog', changelogRouter);
app.use('/graphql', graphqlHTTP(async (request, response) => {
return await {
schema: buildSchema(importSchema('./graphql/schema.graphql')),
rootValue: await graphqlResolver(request, response),
context: {session: request.session},
graphiql: true
};
}));
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
return [app, server];
}
module.exports = init;
//app.listen(settings.port);

@ -1,17 +0,0 @@
Sharkinator
Dry River
Cool Dude
Noobmaster69
TheLegend27
BeastMaster64
BitMaster
Angry Koala
Dragonslayer
Goblin Slayer
useless Aqua
theP0wner79
Pr0wn
Cool User 68
My name Jeff
Bingo Bingo Duolingo
Max Mustermann

572
package-lock.json generated

@ -37,6 +37,242 @@
"@types/babel-types": "*"
}
},
"@types/body-parser": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz",
"integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==",
"requires": {
"@types/connect": "*",
"@types/node": "*"
}
},
"@types/compression": {
"version": "0.0.36",
"resolved": "https://registry.npmjs.org/@types/compression/-/compression-0.0.36.tgz",
"integrity": "sha512-B66iZCIcD2eB2F8e8YDIVtCUKgfiseOR5YOIbmMN2tM57Wu55j1xSdxdSw78aVzsPmbZ6G+hINc+1xe1tt4NBg==",
"dev": true,
"requires": {
"@types/express": "*"
}
},
"@types/connect": {
"version": "3.4.32",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
"integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
"requires": {
"@types/node": "*"
}
},
"@types/connect-pg-simple": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@types/connect-pg-simple/-/connect-pg-simple-4.2.0.tgz",
"integrity": "sha512-Y+ptWW6q6Ll92Y0Zbqb+YiPIUd5ldNsovZJ22Oy5wc4tyl0QVqXPx+ksYCrMgUINXeBDQxJi7HcZ5iATZ62x8A==",
"dev": true,
"requires": {
"@types/express": "*",
"@types/express-session": "*",
"@types/pg": "*"
}
},
"@types/cookie-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.1.tgz",
"integrity": "sha512-iJY6B3ZGufLiDf2OCAgiAAQuj1sMKC/wz/7XCEjZ+/MDuultfFJuSwrBKcLSmJ5iYApLzCCYBYJZs0Ws8GPmwA==",
"dev": true,
"requires": {
"@types/express": "*"
}
},
"@types/express": {
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.0.tgz",
"integrity": "sha512-CjaMu57cjgjuZbh9DpkloeGxV45CnMGlVd+XpG7Gm9QgVrd7KFq+X4HY0vM+2v0bczS48Wg7bvnMY5TN+Xmcfw==",
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "*",
"@types/serve-static": "*"
}
},
"@types/express-graphql": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@types/express-graphql/-/express-graphql-0.8.0.tgz",
"integrity": "sha512-Gzhx6v15CRLnWbD7C9nmQTPd+QXRuJhOovQVyQjw15e2LjmVYI06BhUdAlGtf7sg/BMIeVW6M8RtNww+8HowuA==",
"dev": true,
"requires": {
"@types/express": "*",
"@types/graphql": "*"
}
},
"@types/express-minify": {
"version": "0.1.34",
"resolved": "https://registry.npmjs.org/@types/express-minify/-/express-minify-0.1.34.tgz",
"integrity": "sha512-8HUb0vICbT+Amj2vD2uJbsH2WBMViCwxD6e2c5ajreseO1F8LrqNXgslWMcK7LIB6whG9y/veH+hrIlrFnScGg==",
"dev": true,
"requires": {
"@types/express": "*",
"@types/node": "*"
}
},
"@types/express-serve-static-core": {
"version": "4.16.7",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.7.tgz",
"integrity": "sha512-847KvL8Q1y3TtFLRTXcVakErLJQgdpFSaq+k043xefz9raEf0C7HalpSY7OW5PyjCnY8P7bPW5t/Co9qqp+USg==",
"requires": {
"@types/node": "*",
"@types/range-parser": "*"
}
},
"@types/express-session": {
"version": "1.15.13",
"resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.15.13.tgz",
"integrity": "sha512-BLRzO/ZfjTTLSRakUJxB0p5I5NmBHuyHkXDyh8sezdCMYxpqXrvMljKwle81I9AeCAzdq6nfz6qafmYLQ/rU9A==",
"dev": true,
"requires": {
"@types/express": "*",
"@types/node": "*"
}
},
"@types/express-socket.io-session": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@types/express-socket.io-session/-/express-socket.io-session-1.3.1.tgz",
"integrity": "sha512-QgL8bssVAQhvn6CKUz7AX17inBNDSTsZtS8/rPnu5C5A7CVt9UTIEkRcqO4T1W9bM+jWuskCkLiIykO6onhFRg==",
"requires": {
"@types/express": "*",
"@types/socket.io": "*"
}
},
"@types/fs-extra": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.0.0.tgz",
"integrity": "sha512-bCtL5v9zdbQW86yexOlXWTEGvLNqWxMFyi7gQA7Gcthbezr2cPSOb8SkESVKA937QD5cIwOFLDFt0MQoXOEr9Q==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/graphql": {
"version": "14.2.2",
"resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-14.2.2.tgz",
"integrity": "sha512-okXbUmdZFMO3AYBEJCcpJFPFDkKmIiZZBqWD5TmPtAv+GHfjD2qLZEI0PvZ8IWMU4ozoK2HV2lDxWjw4LbVlnw==",
"dev": true
},
"@types/http-errors": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.6.1.tgz",
"integrity": "sha512-s+RHKSGc3r0m3YEE2UXomJYrpQaY9cDmNDLU2XvG1/LAZsQ7y8emYkTLfcw/ByDtcsTyRQKwr76Bj4PkN2hfWg==",
"dev": true
},
"@types/js-yaml": {
"version": "3.12.1",
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz",
"integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==",
"dev": true
},
"@types/linkify-it": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-2.1.0.tgz",
"integrity": "sha512-Q7DYAOi9O/+cLLhdaSvKdaumWyHbm7HAk/bFwwyTuU0arR5yyCeW5GOoqt4tJTpDRxhpx9Q8kQL6vMpuw9hDSw=="
},
"@types/markdown-it": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-0.0.8.tgz",
"integrity": "sha512-ouaTOi5kAdkTPl97u6uDkth9od4pQffPF9STcjYVZKFrEwLYf15s7Z772WxWE3IOcYBJglaT0XqdyNEiEfGgYg==",
"requires": {
"@types/linkify-it": "*"
}
},
"@types/mime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
"integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw=="
},
"@types/morgan": {
"version": "1.7.36",
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.7.36.tgz",
"integrity": "sha512-Hc2UfTpnqS3gfGZFPk6aaQf/nwxFHboC/o1O25W29UsENPLv8qd/GJUBqzrBuczgaIS3/vZxZRHTfFF28uFNeQ==",
"dev": true,
"requires": {
"@types/express": "*"
}
},
"@types/node": {
"version": "12.6.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz",
"integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg=="
},
"@types/pg": {
"version": "7.4.14",
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-7.4.14.tgz",
"integrity": "sha512-2e4XapP9V/X42IGByC5IHzCzHqLLCNJid8iZBbkk6lkaDMvli8Rk62YE9wjGcLD5Qr5Zaw1ShkQyXy91PI8C0Q==",
"requires": {
"@types/node": "*",
"@types/pg-types": "*"
}
},
"@types/pg-types": {
"version": "1.11.4",
"resolved": "https://registry.npmjs.org/@types/pg-types/-/pg-types-1.11.4.tgz",
"integrity": "sha512-WdIiQmE347LGc1Vq3Ki8sk3iyCuLgnccqVzgxek6gEHp2H0p3MQ3jniIHt+bRODXKju4kNQ+mp53lmP5+/9moQ==",
"requires": {
"moment": ">=2.14.0"
}
},
"@types/range-parser": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
},
"@types/serve-static": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==",
"requires": {
"@types/express-serve-static-core": "*",
"@types/mime": "*"
}
},
"@types/socket.io": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.2.tgz",
"integrity": "sha512-Ind+4qMNfQ62llyB4IMs1D8znMEBsMKohZBPqfBUIXqLQ9bdtWIbNTBWwtdcBWJKnokMZGcmWOOKslatni5vtA==",
"requires": {
"@types/node": "*"
}
},
"@types/uglify-es": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/uglify-es/-/uglify-es-3.0.0.tgz",
"integrity": "sha512-Oc/c7pGIQL0MVhC6g+VftWiDQethKsT4c3fQKYm6nOprkvkx9s1MLrnJprDTKlZL3ZJulMpCF9Qn7s6u3uCNxQ==",
"dev": true,
"requires": {
"@types/uglify-js": "*"
}
},
"@types/uglify-js": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz",
"integrity": "sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ==",
"dev": true,
"requires": {
"source-map": "^0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"@types/winston": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/@types/winston/-/winston-2.4.4.tgz",
"integrity": "sha512-BVGCztsypW8EYwJ+Hq+QNYiT/MUyCif0ouBH+flrY66O5W+KIXAMML6E/0fJpm7VjIzgangahl5S03bJJQGrZw==",
"requires": {
"winston": "*"
}
},
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@ -252,6 +488,14 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true
},
"async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"requires": {
"lodash": "^4.17.14"
}
},
"async-each": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
@ -377,6 +621,11 @@
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
"integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
},
"base64-js": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
},
"base64id": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
@ -538,6 +787,15 @@
}
}
},
"buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
"integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
},
"buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
@ -728,6 +986,15 @@
"object-visit": "^1.0.0"
}
},
"color": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
"integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==",
"requires": {
"color-convert": "^1.9.1",
"color-string": "^1.5.2"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -741,6 +1008,34 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
"requires": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"colornames": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
"integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y="
},
"colors": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg=="
},
"colorspace": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz",
"integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==",
"requires": {
"color": "3.0.x",
"text-hex": "1.0.x"
}
},
"combined-stream": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
@ -883,6 +1178,14 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"crc": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
"integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
"requires": {
"buffer": "^5.1.0"
}
},
"cross-fetch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz",
@ -1048,6 +1351,16 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"diagnostics": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
"integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
"requires": {
"colorspace": "1.1.x",
"enabled": "1.0.x",
"kuler": "1.0.x"
}
},
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@ -1082,6 +1395,14 @@
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"enabled": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
"integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
"requires": {
"env-variable": "0.0.x"
}
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -1160,6 +1481,11 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
},
"env-variable": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz",
"integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA=="
},
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@ -1571,16 +1897,6 @@
"integrity": "sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA==",
"dev": true
},
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"eslint-utils": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
@ -1836,6 +2152,40 @@
}
}
},
"express-socket.io-session": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/express-socket.io-session/-/express-socket.io-session-1.3.5.tgz",
"integrity": "sha512-ila9jN7Pu9OuNIDzkuW+ZChR2Y0TzyyFITT7xiOWCjuGCDUWioD382zqxI7HOaa8kIhfs3wTLOZMU9h6buuOFw==",
"requires": {
"cookie-parser": "~1.3.3",
"crc": "^3.3.0",
"debug": "~2.6.0"
},
"dependencies": {
"cookie": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz",
"integrity": "sha1-5zSlwUF/zkctWu+Cw4HKu2TRpDU="
},
"cookie-parser": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz",
"integrity": "sha1-nXVVcPtdF4kHcSJ6AjFNm+fPg1Y=",
"requires": {
"cookie": "0.1.3",
"cookie-signature": "1.0.6"
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
}
}
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@ -1962,6 +2312,16 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"fast-safe-stringify": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
"integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg=="
},
"fecha": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
},
"figures": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
@ -2139,8 +2499,7 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"optional": true
"bundled": true
},
"aproba": {
"version": "1.2.0",
@ -2158,13 +2517,11 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"optional": true
"bundled": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -2177,18 +2534,15 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"core-util-is": {
"version": "1.0.2",
@ -2291,8 +2645,7 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true,
"optional": true
"bundled": true
},
"ini": {
"version": "1.3.5",
@ -2302,7 +2655,6 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -2315,20 +2667,17 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true,
"optional": true
"bundled": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -2345,7 +2694,6 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -2418,8 +2766,7 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"object-assign": {
"version": "4.1.1",
@ -2429,7 +2776,6 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -2505,8 +2851,7 @@
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"optional": true
"bundled": true
},
"safer-buffer": {
"version": "2.1.2",
@ -2536,7 +2881,6 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -2554,7 +2898,6 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -2593,20 +2936,18 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true,
"optional": true
"bundled": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"optional": true
"bundled": true
}
}
},
"fstream": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
@ -2902,14 +3243,10 @@
"sshpk": "^1.7.0"
}
},
"iconv-lite": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
"dev": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
"ieee754": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
},
"ignore": {
"version": "4.0.6",
@ -3262,6 +3599,11 @@
"has": "^1.0.1"
}
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
@ -3411,6 +3753,14 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
},
"kuler": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz",
"integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==",
"requires": {
"colornames": "^1.1.1"
}
},
"lazy-cache": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
@ -3473,9 +3823,28 @@
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"logform": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz",
"integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==",
"requires": {
"colors": "^1.2.1",
"fast-safe-stringify": "^2.0.4",
"fecha": "^2.3.3",
"ms": "^2.1.1",
"triple-beam": "^1.3.0"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"longest": {
"version": "1.0.1",
@ -3682,6 +4051,11 @@
}
}
},
"moment": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"morgan": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
@ -4009,6 +4383,11 @@
"wrappy": "1"
}
},
"one-time": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
"integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4="
},
"onetime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
@ -5027,6 +5406,21 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
},
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
"requires": {
"is-arrayish": "^0.3.1"
},
"dependencies": {
"is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
}
}
},
"slice-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
@ -5330,6 +5724,11 @@
"tweetnacl": "~0.14.0"
}
},
"stack-trace": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
},
"standard": {
"version": "13.1.0",
"resolved": "https://registry.npmjs.org/standard/-/standard-13.1.0.tgz",
@ -5556,12 +5955,6 @@
"get-stdin": "^4.0.1"
}
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
},
"sum-up": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz",
@ -5689,6 +6082,11 @@
}
}
},
"text-hex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@ -5788,6 +6186,11 @@
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
"integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
},
"triple-beam": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
},
"true-case-path": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
@ -5796,6 +6199,12 @@
"glob": "^7.1.2"
}
},
"tsc": {
"version": "1.20150623.0",
"resolved": "https://registry.npmjs.org/tsc/-/tsc-1.20150623.0.tgz",
"integrity": "sha1-Trw8d04WkUjLx2inNCUz8ILHpuU=",
"dev": true
},
"tslib": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
@ -5839,6 +6248,12 @@
"mime-types": "~2.1.24"
}
},
"typescript": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
"integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
"dev": true
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
@ -6064,6 +6479,43 @@
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
},
"winston": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz",
"integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==",
"requires": {
"async": "^2.6.1",
"diagnostics": "^1.1.1",
"is-stream": "^1.1.0",
"logform": "^2.1.1",
"one-time": "0.0.4",
"readable-stream": "^3.1.1",
"stack-trace": "0.0.x",
"triple-beam": "^1.3.0",
"winston-transport": "^4.3.0"
},
"dependencies": {
"readable-stream": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"winston-transport": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz",
"integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==",
"requires": {
"readable-stream": "^2.3.6",
"triple-beam": "^1.2.0"
}
},
"with": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",

@ -3,9 +3,13 @@
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
"start": "node src/www"
},
"dependencies": {
"@types/express-socket.io-session": "^1.3.1",
"@types/markdown-it": "0.0.8",
"@types/pg": "^7.4.14",
"@types/winston": "^2.4.4",
"compression": "1.7.4",
"connect-pg-simple": "5.0.0",
"cookie-parser": "1.4.4",
@ -15,6 +19,7 @@
"express-graphql": "0.9.0",
"express-minify": "1.0.0",
"express-session": "latest",
"express-socket.io-session": "^1.3.5",
"fs-extra": "8.1.0",
"graphql": "14.4.2",
"graphql-import": "0.7.1",
@ -29,13 +34,31 @@
"pg": "7.11.0",
"pug": "2.0.4",
"socket.io": "2.2.0",
"uglify-es": "3.3.9"
"uglify-es": "3.3.9",
"winston": "^3.2.1"
},
"devDependencies": {
"@types/js-yaml": "^3.12.1",
"@types/socket.io": "^2.1.2",
"@types/compression": "0.0.36",
"@types/connect-pg-simple": "^4.2.0",
"@types/cookie-parser": "^1.4.1",
"@types/express": "^4.17.0",
"@types/express-graphql": "^0.8.0",
"@types/express-minify": "^0.1.34",
"@types/express-session": "^1.15.13",
"@types/fs-extra": "^8.0.0",
"@types/graphql": "^14.2.2",
"@types/http-errors": "^1.6.1",
"@types/morgan": "^1.7.36",
"@types/node": "^12.6.8",
"@types/uglify-es": "^3.0.0",
"eslint": "6.1.0",
"eslint-plugin-graphql": "3.0.3",
"eslint-plugin-promise": "4.2.1",
"standard": "13.1.0"
"standard": "13.1.0",
"tsc": "^1.20150623.0",
"typescript": "^3.5.3"
},
"eslintConfig": {
"parserOptions": {

@ -1,14 +0,0 @@
const express = require('express'),
router = express.Router(),
globals = require('../lib/globals'),
mdEmoji = require('markdown-it-emoji'),
md = require('markdown-it')()
.use(mdEmoji);
/* GET home page. */
router.get('/', (req, res) => {
let info = req.session.acceptedCookies? null: globals.cookieInfo;
res.render('changelog/changes', { changelog: md.render(globals.changelog), info: info});
});
module.exports = router;

@ -1,92 +0,0 @@
const express = require('express'),
router = express.Router(),
cproc = require('child_process'),
fsx = require('fs-extra');
const rWordOnly = /^\w+$/;
let downloads = {};
class RedditDownload {
constructor(file) {
this.file = file;
this.status = 'pending';
this.progress = 'N/A';
this.process = null;
}
}
/**
* Generates an id for a subreddit download.
* @returns {string}
*/
function generateDownloadId() {
return Date.now().toString(16);
}
/**
* Starts the subreddit download by executing the riddle python file.
* @param subreddit {String}
* @returns {string}
*/
function startDownload(subreddit) {
if (rWordOnly.test(subreddit)) {
let downloadId = generateDownloadId();
let dlFilePath = `./public/static/${downloadId}.zip`;
let dlWebPath = `/static/${downloadId}.zip`;
let dl = new RedditDownload(dlWebPath);
dl.process = cproc.exec(`python3 -u riddle.py -o ../../public/static/${downloadId} -z --lzma ${subreddit}`,
{cwd: './scripts/reddit-riddle', env: {PYTHONIOENCODING: 'utf-8', PYTHONUNBUFFERED: true}},
(err, stdout) => {
if (err)
console.error(err);
else
console.log(`riddle.py: ${stdout}`);
});
dl.process.on('exit', (code) => {
if (code === 0)
dl.status = 'finished';
else
dl.status = 'failed';
setTimeout(async () => {
await fsx.remove(dlFilePath);
delete downloads[downloadId];
}, 300000); // delete the file after 5 minutes
});
dl.process.on('message', (msg) => {
console.log(msg);
});
downloads[downloadId] = dl;
return downloadId;
}
}
router.use('/files', express.static('./tmp'));
router.get('/', (req, res) => {
res.render('riddle');
});
router.post('/', (req, res) => {
if (req.body.subreddit) {
let id = startDownload(req.body.subreddit);
let download = downloads[id];
res.send({id: id, status: download.status, file: download.file});
} else if (req.body.id) {
let id = req.body.id;
let download = downloads[id];
if (download)
res.send({
id: id,
status: download.status,
file: download.file
});
else
res.send({error: 'Unknown download ID', id: id});
}
});
module.exports = router;

@ -1,9 +0,0 @@
const express = require('express');
const router = express.Router();
/* GET users listing. */
router.get('/', function(req, res) {
res.send('There are no users :(');
});
module.exports = router;

@ -0,0 +1,177 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var createError = require("http-errors");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
var compileSass = require("express-compile-sass");
var minify = require("express-minify");
var compression = require("compression");
var uglifyEs = require("uglify-es");
var session = require("express-session");
var ConnectPostgres = require("connect-pg-simple");
var fsx = require("fs-extra");
var graphqlHTTP = require("express-graphql");
var graphql_1 = require("graphql");
var graphql_import_1 = require("graphql-import");
var globals = require("./lib/globals");
var routes_1 = require("./routes");
var express = require("express");
var http = require("http");
var App = /** @class */ (function () {
function App() {
this.app = express();
this.server = new http.Server(this.app);
}
App.prototype.init = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/];
});
});
};
App.prototype.configure = function () {
var _this = this;
this.app.set('views', path.join(__dirname, 'views'));
this.app.set('view engine', 'pug');
this.app.set('trust proxy', 1);
this.app.use(compression());
this.app.use(minify({
uglifyJsModule: uglifyEs
}));
this.app.use(logger('dev'));
this.app.use(express.json());
this.app.use(express.urlencoded({ extended: false }));
this.app.use('/sass', compileSass({
root: './public/stylesheets/sass',
sourceMap: true,
watchFiles: (process.env.NODE_ENV !== 'development'),
logToConsole: true
}));
this.app.use(express.static(path.join(__dirname, 'public')));
this.app.use(routes_1.default);
this.app.use(cookieParser());
this.app.use(session({
store: new ConnectPostgres(session)({
pool: pgPool,
tableName: 'user_sessions'
}),
secret: settings.sessions.secret,
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000 // maxAge 7 days
}
}));
this.app.use('/graphql', graphqlHTTP(function (request, response) { return __awaiter(_this, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = {
schema: graphql_1.buildSchema(graphql_import_1.importSchema('./graphql/schema.graphql'))
};
return [4 /*yield*/, graphqlResolver(request, response)];
case 1: return [4 /*yield*/, (_a.rootValue = _b.sent(),
_a.context = { session: request.session },
_a.graphiql = true,
_a)];
case 2: return [2 /*return*/, _b.sent()];
}
});
}); }));
// catch 404 and forward to error handler
this.app.use(function (req, res, next) {
next(createError(404));
});
// error handler
this.app.use(function (err, req, res) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
};
return App;
}());
function init() {
return __awaiter(this, void 0, void 0, function () {
var server, io, settings, graphqlResolver, pgPool, bingoIo;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
server = require('http').Server(app);
io = require('socket.io')(server);
settings = globals.settings;
graphqlResolver = function (request, response) { return __awaiter(_this, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = {
time: Date.now()
};
return [4 /*yield*/, bingoRouter.graphqlResolver(request, response)];
case 1: return [2 /*return*/, (_a.bingo = _b.sent(),
_a.acceptCookies = function () {
request.session.acceptedCookies = true;
return true;
},
_a)];
}
});
}); };
pgPool = globals.pgPool;
return [4 /*yield*/, pgPool.query(fsx.readFileSync('./sql/init.sql', 'utf-8'))];
case 1:
_a.sent();
bingoIo = io.of('/bingo');
return [4 /*yield*/, bingoRouter.init(bingoIo, io)];
case 2:
_a.sent();
// view engine setup
return [2 /*return*/, [app, server]];
}
});
});
}
module.exports = init;
//app.listen(settings.port);

@ -0,0 +1,139 @@
import * as path from 'path';
import * as createError from 'http-errors';
import * as cookieParser from 'cookie-parser';
import * as logger from 'morgan';
import * as compression from 'compression';
import * as uglifyEs from 'uglify-es';
import * as session from 'express-session';
import * as sharedsession from 'express-socket.io-session';
import * as connectPgSimple from 'connect-pg-simple';
import * as fsx from 'fs-extra';
import * as graphqlHTTP from 'express-graphql';
import {buildSchema} from 'graphql';
import {importSchema} from 'graphql-import';
import * as express from 'express';
import * as http from 'http';
import * as socketIo from 'socket.io';
import globals from './lib/globals';
import pgPool from './lib/db';
import routes from './routes';
let minify: any = require('express-minify');
let compileSass: any = require('express-compile-sass');
class App {
public app: express.Application;
public server: http.Server;
public io: socketIo.Server;
/**
* Creates a new app and http server aswell as a socket.io instance.
*/
constructor() {
this.app = express();
this.server = new http.Server(this.app);
this.io = socketIo(this.server);
}
/**
* Public access to the configure function
* @async
* @return Promise
*/
public async init() {
return await this.configure();
}
/**
* Ansynchronously initializes the app.
* @async
* @return Promise
*/
private async configure() {
let settings = globals.settings;
await pgPool.query(fsx.readFileSync('./sql/init.sql', 'utf-8'));
let appSession = session({
// @ts-ignore
store: new connectPgSimple(session)({
pool: pgPool,
tableName: 'user_sessions'
}),
secret: settings.sessions.secret,
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000 // maxAge 7 days
}
});
this.io.use(sharedsession(appSession, {autoSave: true}));
routes.ioListeners(this.io);
let graphqlResolver = async (request: express.Request, response: express.Response) => {
return {
...routes.resolvers(request, response),
time: Date.now(),
acceptCookies: () => {
request.session.acceptedCookies = true;
return true;
}
};
};
this.app.set('views', path.join(__dirname, 'views'));
this.app.set('view engine', 'pug');
this.app.set('trust proxy', 1);
this.app.use(compression());
this.app.use(minify({
// @ts-ignore
uglifyJsModule: uglifyEs
}));
this.app.use(logger('dev'));
this.app.use(express.json());
this.app.use(express.urlencoded({extended: false}));
this.app.use('/sass', compileSass({
root: './public/stylesheets/sass',
sourceMap: true,
watchFiles: (process.env.NODE_ENV !== 'development'),
logToConsole: true
}));
this.app.use(express.static(path.join(__dirname, 'public')));
this.app.use(routes.router);
this.app.use(cookieParser());
this.app.use(appSession);
this.app.use('/graphql', graphqlHTTP(async (request: any, response: any) => {
return await {
schema: buildSchema(importSchema('./graphql/schema.graphql')),
rootValue: await graphqlResolver(request, response),
context: {session: request.session},
graphiql: true
};
}));
// catch 404 and forward to error handler
this.app.use((req, res, next) => {
next(createError(404));
});
// error handler
this.app.use((err: createError.HttpError, req: any, res: any) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
return;
}
}
export default App;

@ -1,21 +1,24 @@
#!/usr/bin/env node
import {Server} from 'http';
import * as yaml from 'js-yaml';
import * as fsx from 'fs-extra';
import App from './app';
/**
* Module dependencies.
*/
const appInit = require('../app');
const debug = require('debug')('whooshy:server');
const yaml = require('js-yaml');
const fsx = require('fs-extra');
let settings = {};
let settings: any = {};
try {
settings = yaml.safeLoad(fsx.readFileSync('default-config.yaml'));
settings = yaml.safeLoad(fsx.readFileSync('default-config.yaml', 'utf-8'));
if (fsx.existsSync('config.yaml'))
Object.assign(settings, yaml.safeLoad(fsx.readFileSync('config.yaml')));
Object.assign(settings, yaml.safeLoad(fsx.readFileSync('config.yaml', 'utf-8')));
} catch (err) {
console.error(err);
}
@ -25,8 +28,11 @@ try {
*/
let port = normalizePort(process.env.PORT || settings.port || '3000');
let webApp = new App();
appInit().then(([app, server]) => {
webApp.init().then(() => {
let app = webApp.app;
let server = webApp.server;
app.set('port', port);
/**
@ -45,7 +51,7 @@ appInit().then(([app, server]) => {
console.error(err.stack);
});
function normalizePort(val) {
function normalizePort(val: string) {
let port = parseInt(val, 10);
if (isNaN(port))
@ -63,7 +69,7 @@ function normalizePort(val) {
* Event listener for HTTP server "error" event.
*/
function onError(error) {
function onError(error: any) {
if (error.syscall !== 'listen')
throw error;
@ -90,7 +96,7 @@ function onError(error) {
* Event listener for HTTP server "listening" event.
*/
function onListening(server) {
function onListening(server: Server) {
let addr = server.address();
let bind = typeof addr === 'string'
? 'pipe ' + addr

@ -0,0 +1,99 @@
import globals from './globals';
import {Pool, PoolClient, QueryConfig, QueryResult} from "pg";
const logger = globals.logger;
class SqlTransaction {
constructor(private client: PoolClient) {
}
/**
* Begins the transaction.
*/
async begin() {
return await this.client.query('BEGIN');
}
/**
* Commits the transaction
*/
async commit() {
return await this.client.query('COMMIT');
}
/**
* Rolls back the transaction
*/
async rollback() {
return await this.client.query('ROLLBACK');
}
/**
* Executes a query inside the transaction.
* @param query
*/
async query(query: QueryConfig) {
return await this.client.query(query);
}
/**
* Releases the client back to the pool.
*/
async release() {
this.client.release();
}
}
class QueryHelper {
private pool: Pool;
constructor(pgPool: Pool) {
this.pool = pgPool;
}
/**
* Queries the database with error handling.
* @param query - the sql and values to execute
*/
private async query(query: QueryConfig): Promise<QueryResult|{rows: any}> {
try {
return await this.pool.query(query);
} catch (err) {
logger.debug(`Error on query "${query}".`);
logger.error(`Sql query failed: ${err}`);
logger.verbose(err.stack);
return {
rows: null
};
}
}
/**
* executes the sql query with values and returns all results.
* @param query
*/
public async all(query: QueryConfig): Promise<any[]> {
let result = await this.query(query);
return result.rows;
}
/**
* executes the sql query with values and returns the first result.
* @param query
*/
public async first(query: QueryConfig): Promise<any> {
let result = await this.query(query);
if (result.rows && result.rows.length > 0)
return result.rows[0];
}
/**
* Creates a new Transaction to be uses with error handling.
*/
public async createTransaction() {
let client: PoolClient = await this.pool.connect();
return new SqlTransaction(client);
}
}
export default QueryHelper

@ -0,0 +1,19 @@
import {Router} from 'express';
import {Server} from 'socket.io';
/**
* Abstract Route class to be implemented by each route.
* This class contains the socket-io Server, router and resolver
* for each route.
*/
abstract class Route {
private io?: Server;
public router?: Router;
public resolver?: object;
abstract async init(...params: any): Promise<any>;
abstract async destroy(...params: any): Promise<any>;
}
export default Route;

@ -0,0 +1,4 @@
class BingoSql {
constructor() {
}
}

@ -1,6 +1,7 @@
const yaml = require('js-yaml'),
fsx = require('fs-extra');
import * as yaml from 'js-yaml';
import * as fsx from 'fs-extra';
// @ts-ignore
String.prototype.replaceAll = function(search, replacement) {
let target = this;
return target.replace(new RegExp(search, 'g'), replacement);
@ -15,8 +16,8 @@ String.prototype.replaceAll = function(search, replacement) {
* sql: {String} pure sql if it is not stored in a file. Will be replaced by file contents if a file was given.
* @param path {String} - the path where the queries.yaml file is stored
*/
function parseSqlYaml(path) {
let queries = yaml.safeLoad(fsx.readFileSync(`${path}/queries.yaml`));
export function parseSqlYaml(path: string) {
let queries = yaml.safeLoad(fsx.readFileSync(`${path}/queries.yaml`, 'utf-8'));
for (let query of queries.exports)
if (queries[query].file)
@ -29,11 +30,11 @@ function parseSqlYaml(path) {
* Reads the default-config.yaml and config.yaml in the path directory.
* @param path {String} - the directory of the settings files.
*/
function readSettings(path) {
let settings = yaml.safeLoad(fsx.readFileSync(`${path}/default-config.yaml`));
export function readSettings(path: string) {
let settings = yaml.safeLoad(fsx.readFileSync(`${path}/default-config.yaml`, 'utf-8'));
if (fsx.existsSync('config.yaml'))
Object.assign(settings, yaml.safeLoad(fsx.readFileSync(`${path}/config.yaml`)));
Object.assign(settings, yaml.safeLoad(fsx.readFileSync(`${path}/config.yaml`, 'utf-8')));
return settings;
}
@ -42,12 +43,7 @@ function readSettings(path) {
* @param fname {String} - the name of the file
* @returns {string[]}
*/
function getFileLines(fname) {
export function getFileLines(fname: string) {
// @ts-ignore
return fsx.readFileSync(fname).toString().replaceAll('\r\n', '\n').split('\n');
}
Object.assign(exports, {
parseSqlYaml: parseSqlYaml,
readSettings: readSettings,
getFileLines: getFileLines
});

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

@ -0,0 +1,52 @@
import {Router} from 'express';
import {GraphQLError} from "graphql";
import * as markdownIt from 'markdown-it';
import * as utils from '../lib/utils';
import globals from '../lib/globals';
import Route from '../lib/Route';
import * as wrappers from '../lib/bingo-wrappers';
let mdEmoji = require('markdown-it-emoji');
let mdMark = require('markdown-it-mark');
let mdSmartarrows = require('markdown-it-smartarrows');
const pgPool = globals.pgPool;
class BingoRoute extends Route {
constructor() {
super();
this.router = Router();
this.resolver = this.getResolver();
}
/**
* Inits the Route
*/
public async init() {
}
/**
* Destroys the Route
*/
public async destroy() {
this.router = null;
this.resolver = null;
}
private getResolver(): object {
return async (req: any, res: any) => {
let playerId = req.session.bingoPlayerId;
return {
player: () => {
return playerId;
}
};
};
}
}
export default BingoRoute;

@ -0,0 +1,17 @@
import {Router} from 'express';
import * as markdownIt from 'markdown-it';
// @ts-ignore
import * as mdEmoji from 'markdown-it-emoji';
import globals from '../lib/globals';
const router = Router();
const md = markdownIt(mdEmoji);
/* GET home page. */
router.get('/', (req, res) => {
let info = req.session.acceptedCookies? null: globals.cookieInfo;
res.render('changelog/changes', { changelog: md.render(globals.changelog), info: info});
});
export default router;

@ -6,7 +6,7 @@ const globals = require('../lib/globals');
/* GET home page. */
router.get('/', function(req, res) {
let info = req.session.acceptedCookies? null: globals.cookieInfo;
res.render('index', { title: 'Trivernis.net', info: info, contact: 'mailto:trivernis@gmail.com'});
res.render('home.js', { title: 'Trivernis.net', info: info, contact: 'mailto:trivernis@gmail.com'});
});
module.exports = router;

@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var express_1 = require("express");
var bingoRouter = require("./bingo");
var router = express_1.Router();
router.use('/bingo', bingoRouter);
exports.default = router;

@ -0,0 +1,24 @@
import {Router} from 'express';
import {Server} from 'socket.io';
import * as homeRouter from './home';
import * as bingoRouter from './bingo';
import changelogRouter from './changelog';
namespace routes {
export const router = Router();
router.use('/', homeRouter);
router.use('/bingo', bingoRouter);
router.use('/changelog', changelogRouter);
export const resolvers = (request: any, response: any):object => {
};
export const ioListeners = (io: Server) => {
};
}
export default routes;

@ -1,7 +1,7 @@
html
head
title= title
include includes/head.pug
include includes/head
script(type='text/javascript', src='/javascripts/riddle-web.js')
link(rel='stylesheet', href='/sass/riddle/style.sass')
body

@ -0,0 +1,20 @@
{
"compileOnSave": true,
"compilerOptions": {
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outDir": "./dist",
"sourceMap": true,
"target": "es2018",
"allowJs": true,
"moduleResolution": "node"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
Loading…
Cancel
Save