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

Setting admins with couchConfig at database creation crashes #341

Closed
QuentinRoy opened this issue Aug 11, 2018 · 1 comment
Closed

Setting admins with couchConfig at database creation crashes #341

QuentinRoy opened this issue Aug 11, 2018 · 1 comment

Comments

@QuentinRoy
Copy link
Contributor

QuentinRoy commented Aug 11, 2018

It is often a good practice to always setup an admin of a database, i.e. at db creation, c.f. #239.
Unfortunately, the following crashes the first time the server is launches (even if one doesn't wait for the callback):

// Create the app.
const app = express();
const expressPouchDB = ExpressPouchDB(PouchDB);
// Set up the admin.
await new Promise((resolve, reject) => {
  expressPouchDB.couchConfig.set(
    'admins',
    config.adminName,
    config.adminPassword,
    err => {
      if (err) reject(err);
      else resolve()
    }
  )
});
// Go.
app.use(expressPouchDB);
app.listen(config.port);

with:

TypeError: refreshUsersDBImpl is not a function
    at CouchConfig.refreshUsersDB (/Users/qroy/Workspace/Code/project/node_modules/express-pouchdb/lib/routes/authentication.js:74:12)
    at CouchConfig.emit (events.js:182:13)
    at /Users/qroy/Workspace/Code/project/node_modules/express-pouchdb/lib/config-infrastructure.js:136:10
    at FSReqWrap.oncomplete (fs.js:145:20)

Subsequent launches would work however. It seems the issue is due to the _users database not being ready yet when the admin is set. Unfortunately, some process still try to update it without waiting.
A somewhat ridiculous workaround is to do this:

// Create the app.
const app = express();
const expressPouchDB = ExpressPouchDB(PouchDB);
// Wait for the _users database to be ready 😔
// (I've tried `await DB('_users').info()` instead without success).
await DB('_users')
  .get('whatever')
  .catch(() => {});
// Set up the admin.
await new Promise((resolve, reject) => {
  expressPouchDB.couchConfig.set(
    'admins',
    config.adminName,
    config.adminPassword,
    err => {
      if (err) reject(err);
      else resolve()
    }
  )
});
// Go.
app.use(expressPouchDB);
app.listen(config.port);
@marten-de-vries
Copy link
Member

Thanks for reporting. Sadly, I don't have time to fix this myself currently, but this is what's going on:

The problem is that refreshUsersDBImpl is only assigned after pouchdb-auth is set up: https://github.com/pouchdb/pouchdb-server/blob/master/packages/node_modules/express-pouchdb/lib/routes/authentication.js#L41

The easiest workaround would probably be to let https://github.com/pouchdb/pouchdb-server/blob/master/packages/node_modules/express-pouchdb/lib/routes/authentication.js#L74 retry calling refreshUsersDBImpl on the next tick if it currently fails. The hack of awaiting the _users db only works by coincidence, I think. What's important is that some time simply passes.

Calling on the next tick could be done using process.nextTick, or using promises.

PRs welcome!

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

2 participants