Couchbase how to transfer an existing user to a new install - couchbase

I am working on a script to download all of the user data from one Couchbase database and transfer it to another. I am having an issue with transferring the user's roles and password data since it is generated by Couchbase and not something I enter in directly.
For example, when I create a new user, I have this data in a file
newuserdata.txt:
{
"name":"myuser",
"admin_channels":[
"myorganization",
"myorganization/auth",
"myorganization/config"
],
"all_channels":[
"!",
"myorganization",
"myorganization/auth",
"myorganization/config"
],
"email":"myuser#email.com",
"password":"password123"
}
Then, to insert it:
curl -sXPUT -H'Content-Type:application/json' -d"#newuserdata.txt" localhost:4985/mydatabase/_user/myuser
Then when I look up the user in the database:
select * from my_database where name="myuser"
I get
"my_database": {
"admin_channels": {
"my_organization": 1,
"my_organization/auth": 1,
"my_organization/config": 1
},
"all_channels": {
"!": 1,
"my_organization": 1,
"my_organization/auth": 1,
"my_organization/config": 1
},
"name": "myuser",
"passwordhash_bcrypt": "<<hashed password>>",
"rolesSince": {},
"sequence": 20
}
When I access it from a url:
http://localhost:4985/mydatabase/_user/myuser
{"name":"myuser","admin_channels":["myorganization","myorganization/auth","myorganization/config"],"all_channels":["!","myorganization","myorganization/auth","myorganization/config"],"email":"myuser#email.com"}
So far, so good.
However, now I want to download this user, preserve their hashed password and data, and transfer this user to a new database. Basically, I am replicating the organization and all of its users on a new server with a new Couchbase database.
I can pull the user record down to a local file, but I can't insert it into the new database since I don't have a raw text version of the password, only the hashed version.
Is there a command or method that I am missing that allows this to be done? Or a workaround?
Thanks for any help.

Related

ExpressJS / MYSQL / Prisma - Save DB' entities changes

I'm looking for a way to save database entities changes for some entities. I mean I need to save in a database table all changes that are done on some tables (add, modify / delete) with ability to track user which did the change.
I'm working on NextJS with a custom ExpressJS server and MYSQL database were I use Prisma as ORM. I think it's maybe possible to write an ExpressJS middleware but I have yet no idea how to do it and asking myself if any library already exist.
Usually I work on PHP Symfony and used to manage this StofDoctrineExtensionsBundle which is great and works as expected. But my current project is a Typescript project only with Express/NextJS/React/Prisma/MYSQL.
Any feedback from your knowledge will be very appreciate.
Thank's in advance.
Regards,
Gulivert
EDIT: My current API which has to be moved to Express/NextJS is still running on Symfony and the table where all changes is logged looks like this :
{
"id": 59807,
"user": "ccba6ad2-0ae8-11ec-813f-0242c0a84005",
"patient": "84c3ef66-548a-11ea-8425-0242ac140002",
"action": "update",
"logged_at": "2021-11-02 17:55:09",
"object_id": "84c3ef66-548a-11ea-8425-0242ac140002",
"object_class": "App\\Entity\\Patient",
"version": 5,
"data": "a:2:{s:10:\"birth_name\";s:2:\"--\";s:10:\"profession\";s:2:\"--\";}",
"username": "johndoe",
"object_name": "patient",
"description": null
}
Explanation about database columns:
user => relation to user table
patient => relation to patient table
action => can be "create"/"update"/delete"
logged_at => date time where the change was done
object_id => entity row ID where an entity get a change
object_class => the entity updated
version => how many time the object was change
data => all data changed during the modification
username => the username of logged user did the change
object_name => a string to identify the object modified without
using the namespace of object_class
description => a value that can be update on some specific change * during usually the action delete to keep a trace what was deleted for instance
You might find prisma middleware useful for this.
Check out the example with session data middleware which is somewhat similar to what you're doing.
For your use-case the middleware might look like something like this:
const prisma = new PrismaClient()
const contextLanguage = 'en-us' // Session state
prisma.$use(async (params, next) => {
// you can find all possible params.action values in the `PrismaAction` type in `.prisma/client/index.d.ts`.
if (params.model == '_modelWhereChangeIsTracked_' && (params.action == 'create' || params.action == "update")) {
// business logic to create an entry into the change logging table using session data of the user.
}
return next(params)
})
// this will trigger the middleware
const create = await prisma._modelWhereChangeIsTracked_.create({
data: {
foo: "bar"
},
})
However, do note that there are some performance considerations when using Prisma middleware.
You can also create express middleware for the routes where you anticipate changes that need to be logged in the change table. Personally, I would prefer this approach in most cases, especially if the number of API routes where changes need to be logged is known in advance and limited in number.

email verification from database using express js node js and angular 6 with mysql database

i am creating a user, with 'email' field so i want to verify whether that email is already exist or not, if exists error must display. i have my code in express js, node js, angular 6 and mysql database and below is the code to create new user
exports.create = (req, res) => {
// Save to MySQL database
let customer = req.body;
Customer.create(customer).then(result => {
// Send created customer to client
res.json(result);
});
};
where should i use if statement in above code
Thanks in advance
I'm thinking the simplest way of solving your problem is making the email column in the database unique. If you try to insert a new user with an already existing email the query will fail.
Another solution would be that you first do a query that looks in the database if an already existing user has the email (from req.body.email). But that would require having two different SQL queries, which I personally would not prefer.
i think you are using Sequelize ORM.
You can do like this
Customer.findOrCreate({
where: {
email: req.body.email,
},
// other datas needs to inserted
defaults: {
name: req.body.name,
username: req.body.username,
},
}).spread((data, created) => {
if (created) {
// your logics
} else {
res.status(400).send(`${req.body.email} already exists.`);
}
});

Hooks not triggering when inserting raw queries via sequelize.query()

I have the following Employee model for a MySQL database:
var bcrypt = require('bcrypt');
module.exports = (sequelize, DataTypes) => {
const Employee = sequelize.define(
"Employee",
{
username: DataTypes.STRING,
password: DataTypes.STRING,
}, {}
);
return Employee;
};
Seeding the database is done by reading a .sql file containing 10,000+ employees via raw queries:
sequelize.query(mySeedingSqlFileHere);
The problem is that the passwords in the SQL file are plain text and I'd like to use bcrypt to hash them before inserting into the database. I've never done bulk inserts before so I was looking into Sequelize docs for adding a hook to the Employee model, like so:
hooks: {
beforeBulkCreate: (employees, options) => {
for (employee in employees) {
if (employee.password) {
employee.password = await bcrypt.hash(employee.password, 10);
}
}
}
}
This isn't working as I'm still getting the plain text values after reseeding - should I be looking into another way? I was looking into sequelize capitalize name before saving in database - instance hook
Your hooks won't be called until you use model's function for DB operation , so if you are running raw query , hooks will never be fired,
Reason : You can write anything inside your raw query , select/insert/update/delete anything , how does sequelize.js know that
it has to fire the hooks. This is only possible when you use methods
like
Model.create();
Model.bulkCreate();
Model.update();
Model.destroy;
And as per DOC raw query doesn't have hooks option to add.
And for MODEL queries you can check that it has option to
enable/disable hook.

How do you insert / find rows related by foreign keys from different tables using Sequelize?

I think I've done enough research on this subject and I've only got a headache.
Here is what I have done and understood: I have restructured my MySQL database so that I will keep my user's data in different tables, I am using foreign keys. Until now I only concluded that foreign keys are only used for consistency and control and they do not automatize or do anything else (for example, to insert data about the same user in two tables I need to use two separate insert statements and the foreign key will not help to make this different or automatic in some way).
Fine. Here is what I want to do: I want to use Sequelize to insert, update and retrieve data altogether from all the related tables at once and I have absolutely no idea on how to do that. For example, if a user registers, I want to be able to insert the data in the table "A" containing some user information and in the same task insert in the table B some other data (like the user's settings in the dedicated table or whatever). Same with retrievals, I want to be able to get an object (or array) with all the related data from different tables fitting in the criteria I want to find by.
Sequelize documentation covers the things in a way that every thing depends on the previous one, and Sequelize is pretty bloated with a lot of stuff I do not need. I do not want to use .sync(). I do not want to use migrations. I have the structure of my database created already and I want Sequelize to attach to it.
Is it possible insert and retrieve several rows related at the same time and getting / using a single Sequelize command / object? How?
Again, by "related data" I mean data "linked" by sharing the same foreign key.
Is it possible insert and retrieve several rows related at the same
time and getting / using a single Sequelize command / object? How?
Yes. What you need is eager loading.
Look at the following example
const User = sequelize.define('user', {
username: Sequelize.STRING,
});
const Address = sequelize.define('add', {
address: Sequelize.STRING,
});
const Designation = sequelize.define('designation', {
designation: Sequelize.STRING,
});
User.hasOne(Address);
User.hasMany(Designation);
sequelize.sync({ force: true })
.then(() => User.create({
username: 'test123',
add: {
address: 'this is dummy address'
},
designations: [
{ designation: 'designation1' },
{ designation: 'designation2' },
],
}, { include: [Address, Designation] }))
.then(user => {
User.findAll({
include: [Address, Designation],
}).then((result) => {
console.log(result);
});
});
In console.log, you will get all the data with all its associated models that you want to include in the query

Get data from Firebase db, comes back without key value

I am retrieving data from Firebase db using REST call. So i have a data looking like this
user
{
123456:
{
Email: "test#hotmail.com",
Password: "John Doe"
}
654321:
{
Email: "test2#hotmail.com",
Password: "Jane Doe"
}
}
The query I used is
firebaseurl/user.json?orderBy="Email"&equalTo="test#hotmail.com"
Is it possible if I query without the key value 123456 being retrieve? Because whenever I try to use the data, for instance console.log(user.Email), I am getting undefined. But when I do it likeconsole.log(user[123456].Email) then will I get the result I desire.
May I know if there's a way to do it? Or a way to access to the child element without user[keyvalue].
As it is expected only single record in return you can use:
const user = obj[Object.keys(rslt)[0]]
Or you can loop over the keys
const usersArr = Object.keys(rslt).map(usr => {
... manipulate usr
return usr
})