<file_sep>const EntitySchema = require("typeorm").EntitySchema; // import {EntitySchema} from "typeorm";
const counterModel = require("../model/counter");

module.exports = new EntitySchema({

    name :"counter",
    target:counterModel,
    columns:{
        _id:{
            primary :true,
            type:"varchar",
            objectId:true
        },
        sequence_val:{
           type:"int"
       }
    }
})<file_sep>const EntitySchema = require("typeorm").EntitySchema; // import {EntitySchema} from "typeorm";
const AuthProviderModel = require("../model/AuthProviders");
//const { O } = require("typeorm");

module.exports = new EntitySchema({

    name: "AuthProvider",
    target: AuthProviderModel,
    columns: {
        providerId:
        {
            primary: true,
            type: "int",
            objectId:true
        },
        providerName
            : {
            type: "varchar",
            
        },
        createdDate: {
            type: "datetime"
        }

    }
})<file_sep>const EntitySchema = require("typeorm").EntitySchema; // import {EntitySchema} from "typeorm";
const AuthProviderDetailsModel = require("../model/AuthProviderDetails");
const UserDetailsModel = require("../model/UserDetailsModel");
const AuthProviderModel = require("../model/AuthProviders");



module.exports = new EntitySchema({

    name: "AuthProviderDetails",
    target: AuthProviderDetailsModel,
    columns: {
        
        name
            : {
            type: "varchar"
        },
        email: {
            type: "varchar"
        },
        createdDate:{
            type:"datetime"
        },
        relations:{
            authProviderUserId:
            {
                target: UserDetailsModel,
                type: "one-to-one",
                joinTable: true,
                cascade: true 
            },
            providerId:
            {
                target: AuthProviderModel,
                type: "one-to-one",
                joinTable: true,
                cascade: true 
            },

        }

    }
})<file_sep>const registerUser = require("../database").registerUser;

module.exports = async (req, res) => {
    try{
        const user = await registerUser.findUser(req.params.authId);
        
        let response = {};
    
        if(user.length === 0){
            response.status = true;
            response.data = "User ";    
        }    
        else{
            response.status = true;
            response.data = user[0];
        }

        res.json(response);
    }    
    catch(ex){
        console.log(ex);
        res.json({
            status: false,
            message: "Internal Server Error"
        });
    }
};
<file_sep>const express = require("express");
const app = express();
const env = require("./config/env_variables").getEnv();
const registerUser = require("./database");
const controllers = require("./controllers");
const amqpStacker = require("./utils/RabbitMQ");
const DBConnection = require("./utils/DBConnection");

app.set('trust proxy')

require("./express-middlewares")(app);

app.post("/user/v1/register", controllers.register.v1);
app.post("/user/v1/login", controllers.login.v1);
app.get("/user/v1/profile", controllers.profile.v1);

process.on('uncaughtException', function (err) {    
    console.log(err.message);
    console.log(err.stack);
});

app.use((req, res, next) => {
    res.json({
        data: `${req.originalUrl} not found`
    });    
});

(async () => {
    try {
       // await registerUser.connect(env.mongodb.url, env.mongodb.dbName);
      //console.log(DBConnection);
        await amqpStacker.config(env.rabbitmq.server);
        
        app.listen(env.port, () => console.log("Registration Services started at port %s", env.port));
    }
    catch (ex) {
        console.log(`\nError starting the service\n`);
        console.log(ex);
        process.exit(0);
    }
})()
<file_sep>const EntitySchema = require("typeorm").EntitySchema; // import {EntitySchema} from "typeorm";
const UserDetailsModel = require("../model/UserDetailsModel");
const AccountTypeModel = require("../model/AccountType");


module.exports = new EntitySchema({
    name: UserDetailsModel,
    target: UserDetailsModel,
    columns: {
        authProviderUserId: {
            primary: true,
            generated: true,
            type: "int"
        },
        attributeName: {
            type: "varchar"
        },
        acccountStatus: {
            type: "varchar"
        },
        privacy: { type: "varchar" },
        termsCondition: { type: "varchar" },
        createdDate: { type: "varchar" },
        updateDate: { type: "varchar" }
    },
    relations: {
        accountTypeId: {
            target: AccountTypeModel,
            type: "many-to-one",
            joinTable: true,
            cascade: true
        },
    }
})<file_sep>const dbConnection = require("../utils/DBConnection");
const UserDetailsModel = require("../model/UserDetailsModel");
const AuthProviderModel = require("../model/AuthProviders");
const AuthProviderDetailsModel = require("../model/AuthProviderDetails");
const AccountTypeModel = require("../model/AccountType");
const counterModel = require("../model/counter");
const AuthProviderEntity = require("../entity/AuthProviders");
const { getMongoManager, getManager, getMongoRepository, getConnection } = require("typeorm");

class USerDetailRepo {
    // manager = getManager();
    //This function is used to insert a record of different auth provider like fb,google,linkedin
    async createAuthProvider(authProviderName) {
        try {
            //console.log(dbConnection);
            let authProviderSeqVal = this.getNextSequenceValue("authProviderSeq");
            console.log("seq val ", authProviderSeqVal);
            let authProviderObj = new AuthProviderModel();
            authProviderObj.providerId = authProviderSeqVal;
            authProviderObj.providerName = authProviderName;
            authProviderObj.createdDate = new Date();
            const manager = getManager();
            await manager.save(authProviderObj);
        } catch (ex) {
            console.log(ex)
        }

    }

    async findAuthProvider(name) {
        try {
            console.log("findAuthProvider");
            const manager = getManager();
            const authProvider = await manager.find(AuthProviderModel, { providerName: name });
            //console.log(authProvider);
            return authProvider;
        } catch (ex) {
            console.log(ex);
        }
    }

    async findAccountType(accountName) {
        try {
            console.log("findAuthProvider");
            const manager = getManager();
            const accountType = await manager.find(AccountTypeModel, { accountTypeName: accountName });
            //console.log(authProvider);
            return accountType;
        } catch (ex) {
            console.log(ex);
        }
    }

    async saveUserAuthProviderDetails(userAuthProvidserData, authProviderId) {
        try {
            const userAuthProviderDetails = new AuthProviderDetailsModel();
            userAuthProviderDetails.authProviderId = authProviderId;
            userAuthProviderDetails.authProviderUserId = userAuthProvidserData.authProviderUserId;
            userAuthProviderDetails.name = userAuthProvidserData.name;
            userAuthProviderDetails.email = userAuthProvidserData.email;
            userAuthProviderDetails.createdDate = new Date();
            const manager = getManager();
            await manager.save(userAuthProviderDetails);
        } catch (ex) {
            console.log(ex);
        }

    }


    async saveUserDetails() {
        try {
            const userDetails = new UserDetailsModel(userDetailsData);

            userDetails.authProviderUserId = parseInt(authProviderUserId),
                userDetails.accountTypeId = userDetailsData.accountTypeId,
                userDetails.attributeName = userDetailsData.attributeName,
                userDetails.acccountStatus = userDetailsData.acccountStatus,
                userDetails.privacy = userDetailsData.privacy,
                userDetails.termsCondition = userDetailsData.termsCondition,
                userDetails.createdDate = userDetailsData.createdDate,
                userDetails.updateDate = userDetailsData.updateDate
            const manager = getManager();
            await manager.save(userDetails);
        } catch (ex) {
            console.log(ex);
        }
    }

    async getNextSequenceValue(sequenceName) {
        const manager = getMongoManager();
        console.log("seqname ", sequenceName);
        var seqdocument = await manager.find(counterModel, { _id: sequenceName });
        console.log(seqdocument[0]);
        var seqVal = seqdocument[0];
        // console.log(seqVal);
        console.log(seqVal.sequence_val);
        var oldSeq = seqVal.sequence_val;
        var incSeq = oldSeq + 1;
        //let counterObj = new counterModel();
        //counterObj._id = sequenceName;
        //counterObj.sequence_val = incSeq;
        console.log("new seq", incSeq);        
        var updateSeq = await manager.updateOne(counterModel,{_id:sequenceName}, { '$set':  {sequence_val : incSeq }});
        var updatedSeqVal = updateSeq[0];
        console.log(updatedSeqVal);
        return updateSeq[0].sequence_value;
    }
}
module.exports = new USerDetailRepo();


<file_sep>class AuthProviders {
    constructor(providerId, name,createdDate) {

        this.providerId = providerId,
        this.providerName = name,
        this.createdDate = createdDate
    }
}
module.exports = AuthProviders;<file_sep>const registerUser = require("../../database");
const amqp = require("./amqp");
const logger = require("../../config/logger");
const uuidv4 = require('uuid/v4');
const env = require("../../config/env_variables").getEnv();

module.exports = async (req, res) => {
    const requestId = uuidv4();

    try {
        logger.info(`/login ${req.method} requestId: ${requestId}`);
        const { accessToken, signedRequest, authProvider } = req.body;
        const correlationId = uuidv4();
        let userAuthData = null;

        if (authProvider === "facebook") {
            logger.info(`${requestId}: Request FBServices_Authentication`);
            userAuthData = await amqp.FBServices_Authentication({ accessToken, signedRequest }, correlationId, requestId);
            logger.info(`${requestId}: User ${userAuthData.id} authenticated by facebook services`);
        }

        if (userAuthData === null) {
            res.json({
                data: "No scheme exists to authenticate validate user"
            });
            return void (0);
        }
        else {
            logger.info(`${requestId}__${userAuthData.id} Request StellarServices_CreateAccount`);
            await registerUser.findUser(userAuthData.id);

            logger.info(`${requestId}__${userAuthData.id} Sending response to client`);
            res.json({
                data: "User logged in stacker"
            });
        }
    }
    catch (ex) {
        console.log(ex);
        let error = "";
        if (ex.type && ex.type === "Facebook") {
            const msg = typeof ex.message === "object" ? JSON.stringify(ex.message) : ex.message;
            logger.info(`${requestId}: Facebook Services error, ${msg}`);
            error = msg;
        }
        res.json({
            messgae: error
        });
    }
};
<file_sep>const typeorm = require("typeorm"); // import * as typeorm from "typeorm";
const env = require("../config/env_variables").getEnv();

module.exports = typeorm.createConnection({
    type: "mongodb",
    host: "localhost",
    port: 27017,
    //username: "test",
   // password: "<PASSWORD>",
    database: "StackerUsers",
    //synchronize: true,
   // logging: false,
    entities: [
        require("../entity/AuthProviders"),
        require("../entity/AccountType"),
        require("../entity/counter")
       // require("../entity/AuthProviderDetails"),
       // require("../entity/UserDetails")       
            ], 
    useNewUrlParser: true 

}).then(function (connection) {
    console.log(" DB Connected !!!! ");
    return connection
}).catch(function (error) {
    console.log("Error: ", error);
});<file_sep>class counter {
    constructor(_id, sequence_val) {
        this._id = _id,
            this.sequence_val = sequence_val

    }
}
module.exports = counter;<file_sep>### User Registration Process

The user registration process can be summarised as follows:

<file_sep>class AuthProviderDetails {
    constructor(authProviderUserid, name, email, authproviderIdcreatedDate) {
        this.authProviderUserId = authProviderUserid,
            this.providerId = id,
            this.providerName = name,
            this.email = email,
            this.createdDate = authproviderIdcreatedDate
    }
}
module.exports = AuthProviderDetails;<file_sep>exports.register = require("./register");
exports.login = require("./login");
exports.profile = require("./profile");<file_sep>exports.MongoError = (userId, operation, message) => {
    throw {
        user: userId,
        timestamp: Date.now(),
        operation: operation,
        error_code: message.code,                
        error_message: message.errmsg
    }
};<file_sep>module.exports = (app) => (...middlewares) => ({
    get: (routePath, controller) => {
        app.get(
            routePath, 
            (req, res, next) => {
                middlewares.forEach(mw => mw(req, res, next))
            },
            controller
        )
    },
    post: (routePath, controller) => {
        app.post(
            routePath, 
            (req, res, next) => {
                middlewares.forEach(mw => mw(req, res, next))
            },
            controller
        )
    }
});<file_sep>const registerUser = require("../../database");
const logger = require("../../config/logger");
const amqp = require("./amqp");
const uuidv4 = require('uuid/v4');

module.exports = async (req, res) => {

    const requestId = uuidv4();
    logger.info(`/profile ${req.method} requestId: ${requestId}`);
    
    try{
        const { userId } = req.query;
        const correlationId = uuidv4();

        logger.info(`${requestId}__${userId}: Find user in stacker database`);
        const user = await registerUser.findUser(userId);

        logger.info(`${requestId}: Request StellarServices_Balance`);
        const balance = await amqp.StellarServices_Balance({ account: user.account }, correlationId, requestId);
        console.log(balance);
        logger.info(`${requestId}__${userId} Sending response to client`);
        res.json({
            name: user.name,
            email: user.email,
            account_type: user.accountType,
            locked: false,
            active: true,
            balance: {
                free: balance.EKRFREE ? balance.EKRFREE : "0",
                postpaid: balance.EKR ? balance.EKR : "0"
            }
        });
    }    
    catch(ex){
        console.log(ex);
        res
            .status(500)
            .send("Request Failed");
    }
};<file_sep>const registerUser = require("../src/database").registerUser;
const stackerAmqp = require("../src/message-queue/amqp-stacker");

const handleFreeTokens = (_err, _data) => {
    if (data1 === "Transferred Tokens") {
        await registerUser.changeAccountStatus({
            userId,
            accountStatus: "Completed"
        });
        //Calling email Services
        stackerAmqp.addEmailDataInQueue({ name: userData.name, email: userData.email, userRegistration:true,freeTokens:10 })

        res.json({
            status: true,
            Result: "User registered"
        });
    }
};

const handleCreateAccount = async (_err, _data) => {
    userData.name, async (err, data) => {
        const stellarAccount = JSON.parse(data);

        await registerUser.updateStellarAccount({
            userId,
            account: stellarAccount.account,
            encryptedMnemonic: stellarAccount.mnemonic
        });

        stackerAmqp.sendFreeToken(data, handleFreeTokens);
    }
}

const handleFacebookResponse = async (_err, _data) => {
   
    const queueData = JSON.parse(data);
    userData = queueData.data;

    if(queueData.error === null){
        console.log(`\nRegister Services`);                
        const user = await registerUser.addUser({ userId: userData.id, name: userData.name, email: userData.email });
        console.log(`User registered in DB`);
        console.log(user);

        stackerAmqp.createAccount(handleCreateAccount);
    }
    else{
        console.log(`Error from Facebook Auth Services`);
        console.log(queueData.error);
        res.json({
            status: false,
            message: "Error authenticating user"
        });
    }            
};

module.exports = async (req, res) => {

    const { userId, name, email, inputAccessToken } = req.body;

    try {        
        const message = {
            fbUID: userId,
            inputAccessToken
        }

        let userData = null;
        stackerAmqp.validateUserByFBGraph(message, async (err, data) => {
            console.log(`\nFrom "Facebook Auth Services"`);
            console.log(`Data: ${JSON.stringify(data, null, 2)}`);
            
            const queueData = JSON.parse(data);
            userData = queueData.data;

            if(queueData.error === null){
                console.log(`\nRegister Services`);                
                const user = await registerUser.addUser({ userId: userData.id, name: userData.name, email: userData.email });
                console.log(`User registered in DB`);
                console.log(user);

                stackerAmqp.createAccount(userData.name, async (err, data) => {
                    const stellarAccount = JSON.parse(data);

                    await registerUser.updateStellarAccount({
                        userId,
                        account: stellarAccount.account,
                        encryptedMnemonic: stellarAccount.mnemonic
                    });

                    stackerAmqp.sendFreeToken(
                        data,
                        async (err, data1) => {
                            if (data1 === "Transferred Tokens") {
                                await registerUser.changeAccountStatus({
                                    userId,
                                    accountStatus: "Completed"
                                });
                                //Calling email Services
                                stackerAmqp.addEmailDataInQueue({ name: userData.name, email: userData.email, userRegistration:true,freeTokens:10 })

                                res.json({
                                    status: true,
                                    Result: "User registered"
                                });
                            }
                        }
                    );

                });
            }
            else{
                console.log(`Error from Facebook Auth Services`);
                console.log(queueData.error);
                res.json({
                    status: false,
                    message: "Error authenticating user"
                });
            }            
        });
    }
    catch (ex) {
        console.log("\nError sending response\n");
        console.log(ex);
        res.json({
            status: false,
            message: "Internal Server Error"
        });
    }

};
<file_sep>const EntitySchema = require("typeorm").EntitySchema; // import {EntitySchema} from "typeorm";
const AccountTypeModel = require("../model/AccountType");

module.exports = new EntitySchema({

    name :"AccountType",
    target:AccountTypeModel,
    columns:{
        accountTypeId:{
            primary :true,
            type:"int",
            objectId:true
        },
       accountTypeName:{
           type:"varchar"
       }
    }
})<file_sep>const { MongoClient } = require("mongodb");
const env = require("../config/env_variables").getEnv();

class StackerMongoConnect {    

    async connect(connectionString, dbName){
        const connection = await MongoClient.connect(connectionString, { useNewUrlParser: true });
        const database = connection.db(dbName);

        this.collections()
            .map(colName => database.collection(colName))
            .forEach(col => {
                let name = col.collectionName;
                let modCollectionName = name.slice(0, 1).toLowerCase() + name.slice(1, name.length);            
                this[modCollectionName] = col;
            });
    }

}

module.exports = StackerMongoConnect;
<file_sep>const env = require("../../config/env_variables").getEnv();
const pubsub = require("../../config/pubsub");

exports.FBServices_Authentication = 
    async (data, correlationId, requestId) =>  await pubsub(
        "FBService_Authentication",
        env.rabbitmq.queue.req.authFacebook, 
        env.rabbitmq.queue.res.authFacebook, 
        data, 
        correlationId,
        requestId
    );

exports.StellarServices_CreateAccount = 
    async (data, correlationId, requestId) =>  await pubsub(
        "StellarService_CreateAccount",
        env.rabbitmq.queue.req.accountCreation, 
        env.rabbitmq.queue.res.accountCreation, 
        data, 
        correlationId,
        requestId
    );

exports.StellarServices_FreeTokens = 
    async (data, correlationId, requestId) => await pubsub(
        "StellarService_FreeTokens",
        env.rabbitmq.queue.req.freeTokens,
        env.rabbitmq.queue.res.freeTokens,
        data,
        correlationId,
        requestId
    );
<file_sep>### Environment Variables

```
# Database
MongoDB_Url=mongodb://localhost:27017
MongoDB_Name=StackerUsers

# RabbitMQ
AMPQ_Url=amqp://localhost
AMPQ_Queue_Req_AccountCreation=@request/accountCreation
AMPQ_Queue_Res_AccountCreation=@response/accountCreation
AMPQ_Queue_Req_FreeTokens=@request/freeTokens
AMPQ_Queue_Res_FreeTokens=@response/freeTokens
AMPQ_Queue_Req_AuthFacebook=@request/authUser_Facebook
AMPQ_Queue_Res_AuthFacebook=@response/authUser_Facebook
AMPQ_Queue_SendEmail=@sendEmail/registerUser
AMPQ_Queue_Req_Balance=@request/balance
AMPQ_Queue_Res_Balance=@response/balance

# General
Privacy_Version=1.0
Terms_Version=1.0
PORT=7000
```<file_sep>const rabbitMQ = require("../utils/RabbitMQ");
const logger = require("./logger");
const chalk = require("chalk").default;

const log = message => logger.info(chalk.yellow(message));

module.exports = async (requestName, requestQueue, responseQueue, data, correlationId, requestId,exchange) => {    

    const [consumer, producer] = [rabbitMQ.getConsumer(), rabbitMQ.getProducer()];    
    const _data = typeof data === "object" ? JSON.stringify(data) : data;

    log(`request ${requestId} calls ${requestName}`)

    log(`${requestId} RabbitMQ requests ${requestName} with correlationId(${correlationId})`); 
    log(`${requestId} RabbitMQ requests ${requestName} with exchange(${exchange})`); 

    producer.assertExchange(exchange,"topic",{durable:true});   
    producer.assertQueue(requestQueue);
    producer.sendToQueue(requestQueue, Buffer.from(_data), { correlationId });

    return new Promise((resolve, reject) => {
        consumer.assertExchange(exchange,"topic",{durable:true});
        consumer.assertQueue(responseQueue);
        consumer.consume(responseQueue, (msg) => {
            consumer.ack(msg);
            consumer.cancel(msg.fields.consumerTag);
            log(`${requestId} RabbitMQ received response from ${requestName}`);
            log(`${requestId} comparing correlationId from rabbitmq ${msg.properties.correlationId} with requests correlationId ${correlationId}`);
            //if(msg.properties.correlationId === correlationId){  
                const _msg = JSON.parse(msg.content.toString());
                console.log(_msg);
                if(_msg.data){
                    console.log("msg.data true  >>> ");
                    resolve([_msg.data,msg.properties.correlationId]);
                }
                else if(_msg.error){
                    console.log("msg.error true  >>> ");
                    reject([_msg.error,msg.properties.correlationId]);
                }
            //}
        });
    });    
};<file_sep>require("dotenv").config({ path: "../.env" });
require("../src/config/env_variables").parse();

const express = require("express");
const app = express();
const env = require("../src/config/env_variables").getEnv();
const registerUser = require("../src/database");
const amqp = require("./rabbit");
const fb = require("./facebook");
const uuid = require("uuid/v4");

require("../src/express-middlewares")(app);

app.post("/user/v1/register", async (req, res) => {
    const { accessToken, authProvider, signedRequest } = req.body;
    req.uuid = uuid();
    const v = uuid();
    console.log(`Incoming request: ${req.uuid}`);
    fb.request(amqp.producer, { correlationId: req.uuid, accessToken, authProvider, signedRequest });
    fb.response(amqp.consumer, v, (msg) => {     
        console.log(msg.fields);
        console.log(req.uuid);
        console.log(msg.properties.correlationId);           
        // if(msg.properties.correlationId === correlationId){
            res.json({
                data: msg
            });
        // }
    });
});

process.on('uncaughtException', function (err) {    
    console.log(err.message);
    console.log(err.stack);
});

(async () => {
    try {
        await registerUser.connect(env.mongodb.url, env.mongodb.dbName);
        await amqp.config();
        
        app.listen(env.port, () => console.log("Registration Services started at port %s", env.port));
    }
    catch (ex) {
        console.log(`\nError starting the service\n`);
        console.log(ex);
        process.exit(0);
    }
})()
<file_sep>class AccountType {
    constructor(id, name) {

        this.accountTypeId = id;
        this.accountTypeName = name;
    }
}
module.exports = AccountType;