Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: db.info is not a function #374

Open
PenguinSnail opened this issue Feb 11, 2019 · 4 comments
Open

TypeError: db.info is not a function #374

PenguinSnail opened this issue Feb 11, 2019 · 4 comments

Comments

@PenguinSnail
Copy link

Whenever I try creating a database or performing actions that require authentication that I don't have, instead of the server returning an unauthorized message, it never responds and I get this error:

(node:4599) UnhandledPromiseRejectionWarning: TypeError: db.info is not a function
    at /home/penguinsnail/Documents/FRC/StrangeScout/server/node_modules/express-pouchdb/lib/routes/db.js:31:10
    at /home/penguinsnail/Documents/FRC/StrangeScout/server/node_modules/promise-nodify/index.js:22:7
    at processTicksAndRejections (internal/process/next_tick.js:81:5)
(node:4599) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:4599) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:4599) UnhandledPromiseRejectionWarning: [object Object]
(node:4599) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

However, with proper authorization no error occurs and the request completes and responds successfully.

My code is here:

const express = require('express');
const PouchDB = require('pouchdb');
const path = require('path');

// winston for logging
const winston = require('winston');
const expressWinston = require('express-winston');

// define database prefix
const db = PouchDB.defaults({prefix: path.join(__dirname, 'dbs/')})

const app = express();
const port = 80;

// listener
app.listen(port, () => console.log(`listening on port ${port}`));

// logging (https://github.com/bithavoc/express-winston#request-logging)
app.use(expressWinston.logger({
	transports: [
		new winston.transports.Console()
	],
	format: winston.format.combine(
		winston.format.json()
	),
	meta: false,
	msg: "HTTP {{req.method}} {{req.url}} {{req.method}} {{res.responseTime}}ms",
	expressFormat: false
}));

// static files at root
app.use('/', express.static(path.join(__dirname, 'static')));
// pouchdb-server
app.use('/db', require('express-pouchdb')(db));
@benbenbenbenbenben
Copy link

Looks like line 30 of express-pouchdb/lib/routes/db.js anticipates a synchronous function call for req.PouchDB.new. In reality this is a promise...

var db = req.PouchDB.new(name, utils.makeOpts(req));

I've create a pull request that I believe fixes it. #433

@HiveTechDev
Copy link

HiveTechDev commented Nov 24, 2021

so, I looked @benbenbenbenbenben's implementation, and he's right. One catch, it's not ALWAYS a promise.

Using pouchdb-authentication with express-pouchdb you have a couple scenarios of users:

  1. User asking for/creating a DB without proper authorization.
  1. User is asking for db with proper authorization
  • DB is a promise
  1. User is an ADMIN, creating a db with proper authorization. This should be successful, but if you use the above code, it doesn't work. Because the db returned is a db object, not a promise.

So, i let it resolve if it is a promise, and if its not, resolve will pass the db through anyway. My solution is as follows:

  1. Replace app.put('/:db ... with

`
app.put('/:db', utils.jsonParser, function (req, res) {
var name = cleanFilename(req.params.db);

	req.PouchDB.allDbs(function (err, dbs) {
		if (err) {
			return utils.sendError(res, err);
		}

		if (dbs.indexOf(name) !== -1) {
			return utils.sendJSON(res, 412, {
				'error': 'file_exists',
				'reason': 'The database could not be created.'
			});
		}

		// PouchDB.new() instead of new PouchDB() because that adds
		// authorisation logic
		var check_resolve = req.PouchDB.new(name, utils.makeOpts(req));
		Promise.resolve(check_resolve).then(function(db) {
			db.info(function (err) {
				if (err) {
					// temoperary workaround for leveldb adapter, see
					// https://github.com/pouchdb/pouchdb/issues/5668
					// when removing this code, also remove mkdir
					// from dependencies in package.json
					if (err.name === 'OpenError') {
						var path = db.__opts.prefix ? db.__opts.prefix + name : name;

						mkdirp(pathResolve(path), function (err) {
							if (err) {
								return utils.sendError(res, err, 412);
							}

							db = req.PouchDB.new(name, utils.makeOpts(req));
							db.info(function (err) {

								if (err) {
									return utils.sendError(res, err, 412);
								}
								utils.setLocation(res, name);
								utils.sendJSON(res, 201, {ok: true});
							});
						});
						return;
					}

					return utils.sendError(res, err, 412);
				}
				utils.setLocation(res, name);
				utils.sendJSON(res, 201, {ok: true});
			});
		})
		.catch((err) =>  {
			console.error("err: ", err);
			return utils.sendError(res, err, 412);
		})
	});
});

`

I then used patch-package to save these changes to my project express-pouchdb. It was the easiest since this is a monorepo and hard to install via git in npm if i forked pouch-db server.

I might make a pull request but. From the looks of it, it will sit stale.

@HiveTechDev
Copy link

I'm also going to note, this error, should have been properly wrapped anyway. right now it will fail and the WHOLE express app will stop functioning. So, kind of problematic. i don't know why this hasn't come up or people are just not using pouchdb-authentication at all

@ghost
Copy link

ghost commented Jan 9, 2022

This bug was reported Feb 2019, it's now nearly 3 years later.

I did this with CURL
C:\Users\fluff>curl -X PUT localhost:26501/somedatabase
curl: (56) Recv failure: Connection was reset

Server Did This
C:\Users\fluff\AppData\Roaming\npm\node_modules\pouchdb-server\node_modules\express-pouchdb\lib\routes\db.js:31
db.info(function (err) {
^

TypeError: db.info is not a function

Conclusion
This is all it takes to crash the server due to this bug, it's not a bug it's a VOLNURABILITY!
Literally, if the database does not exist and someone tries to call it even without a username and password, boom server dies!

This software is ABANDON WEAR and should not be used because no one fixes security issues such as these in anywhere near a timely fashion!

I just wated 7 hours come find out I need to delete this and find a windows based CouchDB alternative..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants