Initial commit for keyServer in Node.JS
commit
aa7019c1ac
@ -0,0 +1,165 @@
|
|||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/node,webstorm,visualstudiocode
|
||||||
|
|
||||||
|
### Node ###
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
### WebStorm ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
### WebStorm Patch ###
|
||||||
|
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||||
|
|
||||||
|
# *.iml
|
||||||
|
# modules.xml
|
||||||
|
# .idea/misc.xml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# Sonarlint plugin
|
||||||
|
.idea/sonarlint
|
||||||
|
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/node,webstorm,visualstudiocode
|
||||||
|
|
||||||
|
### Public Directory ###
|
||||||
|
/public/assets/stylesheets/*.css
|
||||||
|
/cache/
|
||||||
|
/logs/
|
@ -0,0 +1,28 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<DBN-PSQL>
|
||||||
|
<case-options enabled="false">
|
||||||
|
<option name="KEYWORD_CASE" value="lower" />
|
||||||
|
<option name="FUNCTION_CASE" value="lower" />
|
||||||
|
<option name="PARAMETER_CASE" value="lower" />
|
||||||
|
<option name="DATATYPE_CASE" value="lower" />
|
||||||
|
<option name="OBJECT_CASE" value="preserve" />
|
||||||
|
</case-options>
|
||||||
|
<formatting-settings enabled="false" />
|
||||||
|
</DBN-PSQL>
|
||||||
|
<DBN-SQL>
|
||||||
|
<case-options enabled="false">
|
||||||
|
<option name="KEYWORD_CASE" value="lower" />
|
||||||
|
<option name="FUNCTION_CASE" value="lower" />
|
||||||
|
<option name="PARAMETER_CASE" value="lower" />
|
||||||
|
<option name="DATATYPE_CASE" value="lower" />
|
||||||
|
<option name="OBJECT_CASE" value="preserve" />
|
||||||
|
</case-options>
|
||||||
|
<formatting-settings enabled="false">
|
||||||
|
<option name="STATEMENT_SPACING" value="one_line" />
|
||||||
|
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
||||||
|
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
||||||
|
</formatting-settings>
|
||||||
|
</DBN-SQL>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||||
|
</state>
|
||||||
|
</component>
|
@ -0,0 +1,32 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="CssUnknownProperty" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myCustomPropertiesEnabled" value="false" />
|
||||||
|
<option name="myIgnoreVendorSpecificProperties" value="true" />
|
||||||
|
<option name="myCustomPropertiesList">
|
||||||
|
<value>
|
||||||
|
<list size="0" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="8">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="nobr" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="noembed" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="comment" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="noscript" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="embed" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="script" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="marquee" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="blink" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HtmlUnknownTarget" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptLibraryMappings">
|
||||||
|
<includedPredefinedLibrary name="Node.js Core" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES6" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/keyServer.iml" filepath="$PROJECT_DIR$/.idea/keyServer.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectTasksOptions" suppressed-tasks="Less" />
|
||||||
|
</project>
|
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="WebResourcesPaths">
|
||||||
|
<contentEntries>
|
||||||
|
<entry url="file://$PROJECT_DIR$">
|
||||||
|
<entryData>
|
||||||
|
<resourceRoots>
|
||||||
|
<path value="file://$PROJECT_DIR$/public" />
|
||||||
|
</resourceRoots>
|
||||||
|
</entryData>
|
||||||
|
</entry>
|
||||||
|
</contentEntries>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
// Verwendet IntelliSense zum Ermitteln möglicher Attribute.
|
||||||
|
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
|
||||||
|
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Local",
|
||||||
|
"program": "${workspaceFolder}/bin/www"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
let config = require("./libs/configuration");
|
||||||
|
let express = require('express');
|
||||||
|
let createError = require("http-errors");
|
||||||
|
let path = require('path');
|
||||||
|
let cookieParser = require('cookie-parser');
|
||||||
|
//let lessMiddleware = require('less-middleware');
|
||||||
|
let logger = require('morgan');
|
||||||
|
let expressLayout = require('express-layout');
|
||||||
|
let hbs = require('hbs');
|
||||||
|
//let expressValidator = require('express-validator');
|
||||||
|
//let expressSession = require('express-session');
|
||||||
|
//let sessionMySQL = require("connect-mysql")(expressSession);
|
||||||
|
let compression = require("compression");
|
||||||
|
//let expressMinify = require('express-minify');
|
||||||
|
//let expressMinifyHtml = require('express-minify-html');
|
||||||
|
|
||||||
|
let app = express();
|
||||||
|
|
||||||
|
// Configure Views
|
||||||
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
|
app.engine('hbs', hbs.__express);
|
||||||
|
app.set('view engine', 'hbs');
|
||||||
|
app.set('layouts', './views');
|
||||||
|
app.set('layout', 'html');
|
||||||
|
app.set('trust proxy', 'loopback');
|
||||||
|
|
||||||
|
app.use(logger('dev'));
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(express.urlencoded({extended: false}));
|
||||||
|
app.use(expressLayout());
|
||||||
|
//app.use(expressValidator());
|
||||||
|
/*app.use(expressSession({
|
||||||
|
//store: require("./libs/SessionStorage"),
|
||||||
|
secret: config.session.secret,
|
||||||
|
saveUninitialized: false,
|
||||||
|
resave: true,
|
||||||
|
cookie: {
|
||||||
|
secure: false,
|
||||||
|
httpOnly: true,
|
||||||
|
maxAge: config.session.cookieMaxAge,
|
||||||
|
}
|
||||||
|
}));*/
|
||||||
|
app.use(cookieParser());
|
||||||
|
app.use(compression());
|
||||||
|
/*
|
||||||
|
app.use(expressMinify({
|
||||||
|
cache: __dirname + "/cache",
|
||||||
|
jsMatch: /javascript/,
|
||||||
|
cssMatch: /css/,
|
||||||
|
jsonMatch: /json/,
|
||||||
|
lessMatch: /less/,
|
||||||
|
}));
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
app.use(expressMinifyHtml({
|
||||||
|
override: true,
|
||||||
|
exception_url: false,
|
||||||
|
htmlMinifier: {
|
||||||
|
removeComments: true,
|
||||||
|
collapseWhitespace: true,
|
||||||
|
collapseBooleanAttributes: true,
|
||||||
|
removeAttributeQuotes: true,
|
||||||
|
removeEmptyAttributes: true,
|
||||||
|
minifyJS: true,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
*/
|
||||||
|
//app.use(lessMiddleware(path.join(__dirname, 'public')));
|
||||||
|
app.use(express.static(path.join(__dirname, 'static'), {
|
||||||
|
dotfiles: "ignore",
|
||||||
|
index: "index.htm",
|
||||||
|
redirect: false
|
||||||
|
}));
|
||||||
|
|
||||||
|
/* Routes */
|
||||||
|
|
||||||
|
function route(path, route) {
|
||||||
|
app.use(path, require('./routes/' + route));
|
||||||
|
}
|
||||||
|
|
||||||
|
route("/ssh", "ssh");
|
||||||
|
|
||||||
|
// catch 404 and forward to error handler
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
next(createError(404));
|
||||||
|
});
|
||||||
|
|
||||||
|
// error handler
|
||||||
|
app.use(function (err, req, res, next) {
|
||||||
|
// 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');
|
||||||
|
});
|
||||||
|
|
||||||
|
require("prepare")(app);
|
||||||
|
|
||||||
|
module.exports = app;
|
@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Helper
|
||||||
|
|
||||||
|
Date.createFromMysql = function (mysql_string) {
|
||||||
|
let t, result = null;
|
||||||
|
if (typeof mysql_string === 'string') {
|
||||||
|
t = mysql_string.split(/[- :]/);
|
||||||
|
//when t[3], t[4] and t[5] are missing they defaults to zero
|
||||||
|
result = new Date(t[0], t[1] - 1, t[2], t[3] || 0, t[4] || 0, t[5] || 0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var app = require('../app');
|
||||||
|
var debug = require('debug')('dsapage:server');
|
||||||
|
var http = require('http');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get port from environment and store in Express.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var port = normalizePort(process.env.PORT || '3000');
|
||||||
|
app.set('port', port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create HTTP server.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var server = http.createServer(app);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen on provided port, on all network interfaces.
|
||||||
|
*/
|
||||||
|
|
||||||
|
server.listen(port);
|
||||||
|
server.on('error', onError);
|
||||||
|
server.on('listening', onListening);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a port into a number, string, or false.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function normalizePort(val) {
|
||||||
|
var port = parseInt(val, 10);
|
||||||
|
|
||||||
|
if (isNaN(port)) {
|
||||||
|
// named pipe
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port >= 0) {
|
||||||
|
// port number
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener for HTTP server "error" event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onError(error) {
|
||||||
|
if (error.syscall !== 'listen') {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bind = typeof port === 'string'
|
||||||
|
? 'Pipe ' + port
|
||||||
|
: 'Port ' + port;
|
||||||
|
|
||||||
|
// handle specific listen errors with friendly messages
|
||||||
|
switch (error.code) {
|
||||||
|
case 'EACCES':
|
||||||
|
console.error(bind + ' requires elevated privileges');
|
||||||
|
process.exit(1);
|
||||||
|
break;
|
||||||
|
case 'EADDRINUSE':
|
||||||
|
console.error(bind + ' is already in use');
|
||||||
|
process.exit(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener for HTTP server "listening" event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onListening() {
|
||||||
|
var addr = server.address();
|
||||||
|
var bind = typeof addr === 'string'
|
||||||
|
? 'pipe ' + addr
|
||||||
|
: 'port ' + addr.port;
|
||||||
|
console.log("Listening on " + bind);
|
||||||
|
}
|
@ -0,0 +1,203 @@
|
|||||||
|
let mysql = require('mysql');
|
||||||
|
let config = require("./configuration");
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.pool = mysql.createPool({
|
||||||
|
connectionLimit: 50,
|
||||||
|
connectTimeout: 5000,
|
||||||
|
acquireTimeout: 5000,
|
||||||
|
host: config.sqlDatabase.host,
|
||||||
|
user: config.sqlDatabase.user,
|
||||||
|
password: config.sqlDatabase.password,
|
||||||
|
database: config.sqlDatabase.database,
|
||||||
|
multipleStatements: true,
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
this.pool.on('connection', function(connection) {
|
||||||
|
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
get q() {
|
||||||
|
return new SimpleQuery(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static instance() {
|
||||||
|
if (!Database.INSTANCE)
|
||||||
|
Database.INSTANCE = new Database();
|
||||||
|
return Database.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
con(cb) {
|
||||||
|
return this.pool.getConnection(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
query(sql, values, cb) {
|
||||||
|
this.pool.query(sql, values, (e, d) => cb(e, d));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class SelectElement {
|
||||||
|
|
||||||
|
constructor(row, asName) {
|
||||||
|
this.row = row;
|
||||||
|
this.asName = asName;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.asName || this.row;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleQuery {
|
||||||
|
|
||||||
|
constructor(db) {
|
||||||
|
this.db = db;
|
||||||
|
this.selects = [];
|
||||||
|
this.table = null;
|
||||||
|
this.filters = [];
|
||||||
|
this.orders = [];
|
||||||
|
this.limitVal = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static compileArray(arr, first, separator, comp) {
|
||||||
|
let res = "";
|
||||||
|
if (arr.length <= 0)
|
||||||
|
return res;
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (i < 1)
|
||||||
|
res += first;
|
||||||
|
else
|
||||||
|
res += separator;
|
||||||
|
res += comp(arr[i]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
select(row, asName) {
|
||||||
|
if (Array.isArray(row)) {
|
||||||
|
if (!Array.isArray(asName))
|
||||||
|
asName = [];
|
||||||
|
for (let i = 0; i < row.length; i++)
|
||||||
|
this.select(row[i], asName[i]);
|
||||||
|
} else {
|
||||||
|
this.selects.push(new SelectElement(row, asName));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
from(tab) {
|
||||||
|
this.table = tab;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter(row, val) {
|
||||||
|
this.filters.push({row: row, val: val});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
order(row, desc) {
|
||||||
|
this.orders.push({row: row, desc: !!desc});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
limit(limit) {
|
||||||
|
this.limitVal = limit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
reqSel(minVal) {
|
||||||
|
if (this.selects.length < minVal)
|
||||||
|
throw "Missing selectors";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
get(cb) {
|
||||||
|
let sel = this.selects[0].name;
|
||||||
|
this.first(function (e, d) {
|
||||||
|
if (d)
|
||||||
|
cb(e, d[sel]);
|
||||||
|
else
|
||||||
|
cb(e, d);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
first(cb) {
|
||||||
|
this.limit(1).all(function (e, d) {
|
||||||
|
if (d)
|
||||||
|
cb(e, d[0]);
|
||||||
|
else
|
||||||
|
cb(e, d);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
list(cb) {
|
||||||
|
let value = this.selects[0].name;
|
||||||
|
this.all(function (e, d) {
|
||||||
|
if (d)
|
||||||
|
cb(e, d.map(e => e[value]));
|
||||||
|
else
|
||||||
|
cb(e, d);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
array(cb) {
|
||||||
|
let index = this.selects[0].name;
|
||||||
|
let value = this.selects[1].name;
|
||||||
|
this.reqSel(2).all(function (e, d) {
|
||||||
|
if (d) {
|
||||||
|
let res = [];
|
||||||
|
d.forEach(e => res[e[index]] = e[value]);
|
||||||
|
cb(e, res);
|
||||||
|
} else {
|
||||||
|
cb(e, d);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
index(cb) {
|
||||||
|
let index = this.selects[0].name;
|
||||||
|
this.reqSel(1).all((e, d) => {
|
||||||
|
if (d) {
|
||||||
|
let res = [];
|
||||||
|
d.forEach(e => res[e[index]] = e);
|
||||||
|
cb(e, res);
|
||||||
|
} else {
|
||||||
|
cb(e, d);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
all(cb) {
|
||||||
|
if (this.selects.length < 1)
|
||||||
|
this.select("*");
|
||||||
|
if (!this.table)
|
||||||
|
throw "Missing Table Name";
|
||||||
|
let values = [];
|
||||||
|
let query = SimpleQuery.compileArray(this.selects, "SELECT ", ",", function (o) {
|
||||||
|
if (o.asName) {
|
||||||
|
return o.row + " AS " + o.asName;
|
||||||
|
}
|
||||||
|
return o.row;
|
||||||
|
}) + " FROM " + this.table + SimpleQuery.compileArray(this.filters, " WHERE", " AND", function (o) {
|
||||||
|
values.push(o.val);
|
||||||
|
return " " + o.row + " = ?";
|
||||||
|
}) + SimpleQuery.compileArray(this.orders, " ORDER BY ", ",", function (o) {
|
||||||
|
if (o.desc)
|
||||||
|
return o.row + " DESC";
|
||||||
|
else
|
||||||
|
return o.row + " ASC";
|
||||||
|
});
|
||||||
|
if (this.limitVal)
|
||||||
|
query += " LIMIT " + this.limitVal;
|
||||||
|
this.db.query(query, values, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Database;
|
@ -0,0 +1,9 @@
|
|||||||
|
module.exports = {
|
||||||
|
domain: "keys.banananet.work",
|
||||||
|
sqlDatabase: {
|
||||||
|
host: "localhost",
|
||||||
|
user: 'publicKeys',
|
||||||
|
password: 'cxekSE7Kgp4PhjoYrjhEP5DuSoKpKGfNhEbm77DZSdxrHXuFU5x9aBfQiHEVcJRyyM5Qd2pdsWp4ZxRgYxZHfCmJrrLpmcGJX5J5yVbL5CcMVSuVe5pGUWmR3638cPXyeKd5g2xzurJThEJUbYKvv7dWFHgZj3dD4qL5KUTDdiRfHiLZ9DDU3nEZhQdc6rnipdrJCT5RdzHhzFjFTqCZwbqucyycAHjUzhVotGctFP6mS6an3hQSnN3HbLCne54y',
|
||||||
|
database: 'publicKeys',
|
||||||
|
},
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "keyserver",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"start": "node ./bin/www"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"async": "^2.6.1",
|
||||||
|
"bcrypt": "^3.0.0",
|
||||||
|
"compression": "^1.7.3",
|
||||||
|
"connect-mysql": "^2.1.7",
|
||||||
|
"cookie-parser": "~1.4.3",
|
||||||
|
"debug": "~2.6.9",
|
||||||
|
"express": "~4.16.0",
|
||||||
|
"express-layout": "^0.1.0",
|
||||||
|
"express-minify": "^1.0.0",
|
||||||
|
"express-minify-html": "^0.12.0",
|
||||||
|
"express-session": "^1.15.6",
|
||||||
|
"express-validator": "^5.3.0",
|
||||||
|
"handlebars": "^4.0.12",
|
||||||
|
"hbs": "~4.0.1",
|
||||||
|
"http-errors": "~1.6.2",
|
||||||
|
"ical-generator": "^1.0.4",
|
||||||
|
"less-middleware": "~3.0.1",
|
||||||
|
"markdown-it": "^8.4.2",
|
||||||
|
"moment": "^2.22.2",
|
||||||
|
"morgan": "~1.9.0",
|
||||||
|
"mysql": "^2.16.0",
|
||||||
|
"npm": "^6.4.1",
|
||||||
|
"utils-merge": "~1.0.1"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
let fs = require("fs");
|
||||||
|
let path = require("path");
|
||||||
|
|
||||||
|
const staticDir = path.join(__dirname, "static");
|
||||||
|
|
||||||
|
module.exports = (app) => {
|
||||||
|
function renderAndSave(file, template, options) {
|
||||||
|
file = path.join(staticDir, file);
|
||||||
|
app.render(template, options, (e, r) => {
|
||||||
|
if (e) return fs.writeFile(file, "<!DOCTYPE html><html><head><title>Something went wrong!</title></head><body><h1>Something went wrong!</h1><p>Could not render this page! Please contact the administrator!</p></body></html>");
|
||||||
|
return fs.writeFile(file, r);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir);
|
||||||
|
|
||||||
|
[
|
||||||
|
["index.htm", "linkList", {
|
||||||
|
links: [
|
||||||
|
{href: "/ssh", name: "All SSH Keys"},
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
].forEach(e => renderAndSave(e[0], e[1], e[2]));
|
||||||
|
};
|
@ -0,0 +1,40 @@
|
|||||||
|
const user = ":user([^@]+)";
|
||||||
|
const host = ":host([^@]+)";
|
||||||
|
const type = ":type((dsa|rsa|ecdsa|ed25519))";
|
||||||
|
|
||||||
|
let express = require("express");
|
||||||
|
let db = require("../libs/Database").instance();
|
||||||
|
let router = express.Router();
|
||||||
|
let userRouter = express.Router();
|
||||||
|
|
||||||
|
function toList(a, b) {
|
||||||
|
return a + "\n" + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
router.use(["/user", "/users", "/userKeys"], userRouter);
|
||||||
|
|
||||||
|
function userReq(req, res) {
|
||||||
|
let p = req.params;
|
||||||
|
let q = db.q.select("publicKeyComment");
|
||||||
|
if (p.user) q.filter("user", p.user);
|
||||||
|
if (p.host) q.filter("host", p.host);
|
||||||
|
if (p.type) q.filter("type", p.type);
|
||||||
|
q.list((e, d) => {
|
||||||
|
if (e) return res.status(500).send("ERROR");
|
||||||
|
res.type("text/plain");
|
||||||
|
res.send(d.reduce(toList));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
[
|
||||||
|
"/",
|
||||||
|
"/" + type,
|
||||||
|
"/@" + host,
|
||||||
|
"/" + user,
|
||||||
|
"/" + user + "@" + host,
|
||||||
|
"/@" + host + "/" + type,
|
||||||
|
"/" + user + "/" + type,
|
||||||
|
"/" + user + "@" + host + "/" + type,
|
||||||
|
].forEach(e => userRouter.get(e, userReq));
|
||||||
|
|
||||||
|
module.exports = router;
|
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{title}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
{{{body}}}
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<address>Key Server of <a href="https://banananet.work/">banananet.work</a></address>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,5 @@
|
|||||||
|
<ul>
|
||||||
|
{{#each links as |link|}}
|
||||||
|
<li><a href="{{link.href}}">{{#if link.name}}{{link.name}}{{else}}{{link.href}}{{/if}}</a></li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
@ -0,0 +1 @@
|
|||||||
|
{{{ body }}}
|
Loading…
Reference in New Issue