1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-11-13 03:35:52 +01:00
verdaccio/lib/index-web.js
Waldemar Reusch ef360d6927 enable verdaccio behind a https nginx proxy (#222)
* enable verdaccio to run with http protcol behind a https reverse proxy

* add semicolon
2017-06-19 12:12:36 +08:00

169 lines
5.2 KiB
JavaScript

'use strict';
let async = require('async');
let bodyParser = require('body-parser');
let Cookies = require('cookies');
let express = require('express');
let fs = require('fs');
let Handlebars = require('handlebars');
let renderReadme = require('render-readme');
let Search = require('./search');
let Middleware = require('./middleware');
let Utils = require('./utils');
let match = Middleware.match;
let validate_name = Middleware.validate_name;
let validate_pkg = Middleware.validate_package;
module.exports = function(config, auth, storage) {
/* eslint new-cap:off */
let app = express.Router();
let can = Middleware.allow(auth);
// validate all of these params as a package name
// this might be too harsh, so ask if it causes trouble
app.param('package', validate_pkg);
app.param('filename', validate_name);
app.param('version', validate_name);
app.param('anything', match(/.*/));
app.use(Cookies.express());
app.use(bodyParser.urlencoded({extended: false}));
app.use(auth.cookie_middleware());
app.use(function(req, res, next) {
// disable loading in frames (clickjacking, etc.)
res.header('X-Frame-Options', 'deny');
next();
});
Search.configureStorage(storage);
Handlebars.registerPartial('entry', fs.readFileSync(require.resolve('./GUI/entry.hbs'), 'utf8'));
let template;
if (config.web && config.web.template) {
template = Handlebars.compile(fs.readFileSync(config.web.template, 'utf8'));
} else {
template = Handlebars.compile(fs.readFileSync(require.resolve('./GUI/index.hbs'), 'utf8'));
}
app.get('/', function(req, res, next) {
let proto = req.get('X-Forwarded-Proto') || req.protocol;
let base = Utils.combineBaseUrl(proto, req.get('host'), config.url_prefix);
res.setHeader('Content-Type', 'text/html');
storage.get_local(function(err, packages) {
if (err) throw err; // that function shouldn't produce any
async.filterSeries(packages, function(pkg, cb) {
auth.allow_access(pkg.name, req.remote_user, function(err, allowed) {
setImmediate(function() {
if (err) {
cb(null, false);
} else {
cb(err, allowed);
}
});
});
}, function(err, packages) {
if (err) throw err;
packages.sort(function(p1, p2) {
if (p1.name < p2.name) {
return -1;
} else {
return 1;
}
});
next(template({
name: config.web && config.web.title ? config.web.title : 'Verdaccio',
tagline: config.web && config.web.tagline ? config.web.tagline : '',
packages: packages,
baseUrl: base,
username: req.remote_user.name,
}));
});
});
});
// Static
app.get('/-/static/:filename', function(req, res, next) {
let file = __dirname + '/static/' + req.params.filename;
res.sendFile(file, function(err) {
if (!err) return;
if (err.status === 404) {
next();
} else {
next(err);
}
});
});
app.get('/-/logo', function(req, res, next) {
res.sendFile( config.web && config.web.logo
? config.web.logo
: __dirname + '/static/logo-sm.png' );
});
app.post('/-/login', function(req, res, next) {
auth.authenticate(req.body.user, req.body.pass, function(err, user) {
if (!err) {
req.remote_user = user;
// res.cookies.set('token', auth.issue_token(req.remote_user))
let str = req.body.user + ':' + req.body.pass;
res.cookies.set('token', auth.aes_encrypt(str).toString('base64'));
}
let base = config.url_prefix
? config.url_prefix.replace(/\/$/, '')
: req.protocol + '://' + req.get('host');
res.redirect(base);
});
});
app.post('/-/logout', function(req, res, next) {
let base = config.url_prefix
? config.url_prefix.replace(/\/$/, '')
: req.protocol + '://' + req.get('host');
res.cookies.set('token', '');
res.redirect(base);
});
// Search
app.get('/-/search/:anything', function(req, res, next) {
const results = Search.query(req.params.anything);
const packages = [];
const getData = function(i) {
storage.get_package(results[i].ref, function(err, entry) {
if (!err && entry) {
auth.allow_access(entry.name, req.remote_user, function(err, allowed) { // TODO: This may cause performance issue?
if (err || !allowed) return;
packages.push(entry.versions[entry['dist-tags'].latest]);
});
}
if (i >= results.length - 1) {
next(packages);
} else {
getData(i + 1);
}
});
};
if (results.length) {
getData(0);
} else {
next([]);
}
});
app.get('/-/readme(/@:scope?)?/:package/:version?', can('access'), function(req, res, next) {
let packageName = req.params.package;
if (req.params.scope) packageName = '@'+ req.params.scope + '/' + packageName;
storage.get_package(packageName, {req: req}, function(err, info) {
if (err) return next(err);
next( renderReadme(info.readme || 'ERROR: No README data found!') );
});
});
return app;
};