<pre>
fastify.post("/user", async (request, reply) => {
 validate(request.body, reply);

 const foundCodeworker = await findAlreadyRegistered(
   request.body.codeWorkerEmail,
   codeworkers
 );
 checkEmail(foundCodeworker, reply);

 const createdCodeWorker = await save(request.body, codeworkers);
 succeedOnCreation(createdCodeWorker, reply);
});
</pre>

<pre>
const { hash } = require("../../../infrastructure/webserver/utils/bcrypt");

module.exports = {
 findAlreadyRegistered: async (email, codeworkers) => {
   return await codeworkers.findOne({
     email,
   });
 },
 save: async (user, codeworkers) => {
   return await codeworkers.insertOne({
     email: user.codeWorkerEmail,
     password: await hash(user.codeWorkerPassword),
     authority: "user",
   });
 },
};
</pre>

<pre>
const { verify } = require("../../../infrastructure/webserver/utils/bcrypt");

module.exports = {
 find: async (email, codeworkers) => {
   return await codeworkers.findOne({
     email,
   });
 },
 checkPassword: async (userPassword, foundCodeworkerPassword) => {
   if (!foundCodeworkerPassword) return false;
   return await verify(userPassword, foundCodeworkerPassword);
 },
};
</pre>

<pre>
const bcrypt = require("bcrypt");

module.exports = {
 hash: (password) => {
   return new Promise(async (resolve, reject) => {
     await bcrypt.genSalt(10, async function (err, salt) {
       if (err) reject(err);
       await bcrypt.hash(password, salt, function (err, hash) {
         if (err) reject(err);
         resolve(hash);
       });
     });
   });
 },
 verify: (password, hash) => {
   return new Promise(async (resolve, reject) => {
     await bcrypt.compare(password, hash, function (err, result) {
       if (err) reject(err);
       resolve(result);
     });
   });
 },
};
</pre>

const Joi = require('joi');

const schema = Joi.object({
    username: Joi.string()
        .alphanum()
        .min(3)
        .max(30)
        .required(),

    password: Joi.string()
        .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),

    repeat_password: Joi.ref('password'),

    access_token: [
        Joi.string(),
        Joi.number()
    ],

    birth_year: Joi.number()
        .integer()
        .min(1900)
        .max(2013),

    email: Joi.string()
        .email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
})
    .with('username', 'birth_year')
    .xor('password', 'access_token')
    .with('password', 'repeat_password');

schema.validate({ username: 'abc', birth_year: 1994 });
// -> { value: { username: 'abc', birth_year: 1994 } }

schema.validate({});
// -> { value: {}, error: '"username" is required' }

// Also -

try {
    const value = await schema.validateAsync({ username: 'abc', birth_year: 1994 });
}
catch (err) { }

<pre>
const userName = location.hash.match(/userName=([^^&]*)/)[1]
// ...
div.innerHTML += `Welcome ${userName}">`
</pre>

<pre>
{
 "env": {
   "browser": true,
   "commonjs": true,
   "es2020": true
 },
 "parserOptions": {
   "ecmaVersion": 11
 },
 "extends": "eslint:recommended",
 "rules": {
   "no-eval": "error",
   "no-implied-eval": "error",
   "no-new-func": "error",
   "eqeqeq": ["error", "always"]
 }
}
</pre>