VulcanJS / vulcan-meteor-next-transition

A starter using Vulcan Next as the frontend and Vulcan Meteor as the backend (for transition purpose)
2 stars 1 forks source link

From Meteor to Next

This repository demoes using a Vulcan Next frontend with a legacy Vulcan Meteor backend. This is targeted at existing Vulcan application that needs a progressive migration.

/!\ Please use Vulcan Next directly if you are not an experimented user of Vulcan Meteor

Install

git clone https://github.com/VulcanJS/vulcan-meteor-next-transition
cd ./vulcan-next-transition
git submodule update --init --recursive

Start the Meteor server

cd ./meteor-backend
# For contributions, go to the right branch (submodules only gets you to a commit)
# git checkout demo/with-next-frontend
# Install if not yet done: 
meteor npm install
cp ./sample_settings.json ./settings.json
meteor npm run start -- --port=3001
# Remember to also read ./meteor-backend/README.md to continue the setup

Start the Next frontend

cd ./next-frontend
# For contributions, go to the right branch (submodules only gets you to a commit)
# git checkout demo/with-meteor-backend
# Install if not yet done: 
yarn install
yarn run dev
# Remember to also read ./next-frontend/README.md to continue the setup

Use the app

The Next frontend will run on http://localhost:3000 ; the Meteor backend will run on http://localhost:3001. Note: you can still access the frontend part of your Meteor app as well! This is great if you want to keep the admin area in Meteor for instance, but move some pages to Next progressively.

You can authenticate in the Vulcan Next app as usual, using the same credentials you would use in Meteor.

Access the http://localhost:3000/meteor-demo to see the connection in action.

How it works

Frontend

Top priority of this demo is to connect a Vulcan Next frontend to an existing Meteor backend.

Full-stack = progressively use Next as your backend

In the long run, the goal is to transition the Meteor backend to Next as well, using Next API routes.

Reuse the meteor database

See this script: https://github.com/GraemeFulton/vulcan-next-meteor-mongo-migrate

See https://github.com/VulcanJS/vulcan-npm/issues/63. Meteor uses string _id as a default, while Mongo uses ObjectId type, so you need to do ObjectId.str to get the actual id or use a method like isEqual from lodash. This means that objects created using Next backend might create bugs in the Meteor backend. You need to avoid that, by doing creation operations only in Meteor, or to clearly separate things you manage in Next and things you manage in Meteor until you have fully transitionned.

Reuse existing user

Check the existing password

Simply alter Vulcan Next password check method so it fall back to services.password.bcrypt to find the hashed password, see https://willvincent.com/2018/08/09/replicating-meteors-password-hashing-implementation/

This is already done in Vulcan Next latest version.

Example structure of a user:

 {
 "_id":"RXSk3HJemC6haii64",
 "username":"administrator",
 "email":"admin@vulcanjs.org",
 "isDummy":false,
 "groups":["admins"],
 "isAdmin":true,
"emails":[{"address":"admin@vulcanjs.org"}],
"createdAt":{"$date":"2021-12-29T11:43:29.772Z"},
"displayName":"administrator",
"slug":"administrator",
// admin123
 "services": {
        "password": {
            "bcrypt": "$2b$10$vxNlPs/AJdIYlypKCp7RVOiFNcc0I8ay6xj0TTXnA94rh5SSn.I8W"
        }
"status":{"online":false}}

Example code:

 export const checkPasswordForUser = (
  user: Pick<UserTypeServer, "hash" | "salt">,
  passwordToTest: string
): boolean => {

  //legacy meteor start
  const userInput = crypto
  .Hash('sha256')
  .update(passwordToTest)
  .digest('hex')

  if(bcrypt.compareSync(userInput, `$2b$10$${user.salt}${user.hash}`)){
    console.log('match')
    const passwordsMatch = user.hash;
    return passwordsMatch;
  }//legacy meteor end

  const hash = (crypto as any)
    .pbkdf2Sync(userInput, user.salt, 1000, 64, "sha512")
    .toString("hex");

  const passwordsMatch = user.hash === hash;
  return passwordsMatch;
};

Attempt to update password

/!\ This doesn't work as expected, probably because Meteor is using SHA256 and Vulcan Next SHA512. Instead, update the password field only when the user change their password.

To update password:

Caveats