Can I force a DB update to be synchronous?

So I have a situation in which I would like to update my DB just prior to a user attempting to log in. My code is as follows:

const dev_github  = Meteor.settings.private.OAuth.github.dev;
const prod_github = Meteor.settings.private.OAuth.github.prod;

configureDevOAuthFor10Seconds = () => {
  if (dev_github && prod_github) {
    // update the DB synchronously here so it has dev settings
    // for github oauth login
    ServiceConfiguration.configurations.upsert({ service: 'github' }, {
      $set: {
        clientId: dev_github.clientId,
        loginStyle: 'popup',
        requestOfflineToken: false,
        secret: dev_github.secret
      }
    });
    // asynchronously set it back 10 seconds later to prod_github
    // oauth for normal use
    Meteor.setTimeout(function() {
      ServiceConfiguration.configurations.upsert({ service: 'github' }, {
        $set: {
          clientId: prod_github.clientId,
          loginStyle: 'popup',
          requestOfflineToken: false,
          secret: prod_github.secret
        }
      });
    }, 10000);
  }  // end if dev_github && prod_github
};

// every time someone tries to login, first check to see if they are
// on a dev environment and update the service configuration to
// dev if they are - then set it back 10 secs later
Accounts.validateLoginAttempt(function({type, connection}) {
  if (type === 'github') {
    if (connection.httpHeaders.host == 'localhost:4000') {
      // I want this to run synchronously
      configureDevOAuthFor10Seconds();
      // return true only after DB is updated and we have 10 seconds to log in.
      return true;
    } else {
      // return true immediately for github login attempts
      // from non-localhost:4000
      return true;
  }
  // non-github login attempt is invalid.
  return false;
});

When I attempt to login with this code, the github oauth login attempt is failing because it is using prod credentials instead of dev credentials – I assume because the DB does not update synchronously.

How can I get this approach to work properly for me?

(The reason I am doing this is because I need to share the DB between my production and development environments, yet I need github oauth login to work for both of them.)

DB operations are synchronous by default on the server. Maybe sprinkle some console.log's in there to make sure they are definitely being run.

Hmm, ok - so apparently validateLoginAttempt() is called after the github login has already been attempted – is there any way I can hook into a login attempt before Meteor takes some steps into the process?

I don’t think that’s how it’s supposed to run but I guess you could call configureDevOAuthFor10Seconds from a method before login

Thanks, this is exactly the approach I have decided to take. I’ve added a button to the login page that only appears in dev mode. Upon pressing this button, the service configuration is switched to dev credentials for 10 seconds, then automatically switched back. The dev user is then presented with a 10 second countdown, during which time s/he must login.

It seems like I should just be able to hook into the button click event on the client, detect dev mode, and then call a Meteor method to update-dev-credentials automatically.

1 Like