How to use credentials to work with nodegit.push on Windows - javascript

Edit: I'm changing the question to suit my current understanding of the problem which has changed significantly.
Original Title: Nodegit seems to be asking for wrong credentials on push
When trying to push using nodegit nothing seems to work on Windows (while they work fine on Linux).
Using SSH
sshKeyFromAgent - error authenticating: failed connecting agent
sshKeyNew - credentials callback is repeatedly (looks like an infinite loop
but I can't be sure)
sshKeyMemoryNew: credentials is called twice and then node exits with no diagnostic (the exit and beforeExit events on process aren't signalled)
Using HTTPS
userpassPlaintextNew: [Error: unknown certificate check failure] errno: -17
Original question follows.
I'm trying to get nodegit to push and the following question seems to address this situation. However I'm not able to get it to work.
I've cloned a repository using SSH and when I try to push, my credentials callback is being called with user git and not motti (which is the actual git user).
try {
const remote = await repository.getRemote("origin");
await remote.push(["refs/head/master:refs/heads/master"], {
callbacks: {
credentials: (url, user) => {
console.log(`Push asked for credentials for '${user}' on ${url}`);
return git.Cred.sshKeyFromAgent(user);
}
}
});
}
catch(err) {
console.log("Error:", err);
}
I get the following output:
Push asked for credentials for 'git' on git#github.[redacted].net:motti/tmp.git
Error: { Error: error authenticating: failed connecting agent errno: -1, errorFunction: 'Remote.push' }
If I try to hardcode motti to the sshKeyFromAgent function the error changes to:
Error: { Error: username does not match previous request errno: -1, errorFunction: 'Remote.push' }
This my first time trying to programmatically use git so I may be missing something basic...
Answer for some questions from comments:
I'm running on windows 10
node v8.9.4
git version 2.15.0.windows.1
nodegit version 0.24.1
the user running node is my primary user which when I use for git in command line works correctly

Instead of using git.Cred.sshKeyFromAgent - you could use git.Cred.sshKeyNew and pass your username / keys along.
const fs = require('fs');
// ...
const username = "git";
const publickey = fs.readFileSync("PATH TO PUBLIC KEY").toString();
const privatekey = fs.readFileSync("PATH TO PRIVATE KEY").toString();
const passphrase = "YOUR PASSPHRASE IF THE KEY HAS ONE";
const cred = await Git.Cred.sshKeyMemoryNew(username, publickey, privatekey, passphrase);
const remote = await repository.getRemote("origin");
await remote.push(["refs/head/master:refs/heads/master"], {
callbacks: {
credentials: (url, user) => cred
}
});

You need to run an ssh agent locally and save your password there. Follow these steps to make it work:
Enable the ssh agent locally (automatically runs on OS X): https://code.visualstudio.com/docs/remote/troubleshooting#_setting-up-the-ssh-agent
Run 'ssh-add' in the same CLI as you're running your nodegit actions and enter your passphrase
I hope this helps because I also struggled a lot with it and it can be very frustrating.

Related

can't load chrome driver with selenium, in the firebase cloud functions

im trying use the chrome driver, with selenium in the firebase cloud functions.
while deploying the index.js file on to a local host, using the terminal cmd
'firebase serve --only functions' from the functions folder(which has the chromedriver file, every thing work like in supposed to, im getting a response.
But,
when I deploying the index.js file to the firebase real servers using the
'firebase deploy --only functions' ,
and then trigger the function from my app, or from a url,
im getting an error in the firebase cloud functions logs telling me
'Function execution took 1774 ms, finished with status: 'crash' '
so since there were not details about what was causing this 'crash' I uses the consoled.log() function, and printed each line that was executed successfully.
this lead me into the line of
let driver = await new Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless().windowSize(screen)).build();
its seems like in the firebase cloud function I can't for some reason create a chrome driver successfully , although in the local host version, it's working as expected.
here the full code of the function:
exports.initializedChromeDriver = functions.https.onRequest((request, response) => {
async function start_chrome_driver() {
functions.logger.info('Hello logs!', {structuredData: true});
console.log("did enter the function")
const dic = {};
const google_site = "https://www.gooogle.com";
const { WebDriver } = require('selenium-webdriver');
const {Builder, By} = require('selenium-webdriver');
console.log("did creat WebDriver,Builder, By, constans")
const chrome = require('selenium-webdriver/chrome');
console.log("chrome constans was created")
const screen = {
width: 1024,
height: 1024
};
let driver = await new Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless().windowSize(screen)).build();
console.log("driver was set");
await driver.get(google_site);
console.log("succ loading google");
return "succ loading google"
}
const p = start_chrome_driver().then((value,reject) => {
dic['status'] = 200;
dic['data'] = {"message": value};
response.send(dic);
});
and here are the logs in the firebase cloud console:
UPDATE
well after searching for answers in the web, ,i found that I didn't have a suitable 'driver' for linux systems,
so I replace the chrome driver for mac(which work on my machine, on the local host version),
with a chrome driver, for linux. and try again, well that doesn't work either , but at lest I was getting a new log with an Error, not just a 'crash' , here it his:
so now I know that I need to install the chrome browser binary for linux on the project,
any ideas to how can I do this, Im trying to install the chrome binary driver on to my project in firebase, there a few ways im trying now, like installing the chrome binary using the google shell some how, any help or idea to I do does, even so, I don't sure that after the binary will be install , this will be it, and the driver will work on the firebase servers..

TypeError: key must be a string, a buffer or an object at typeError with GCP file exists

I'm trying to simply test for an existence of a file on our Google Cloud Platform (GCP) storage. I'm using GCP buckets on express js servers. Below is essentially a very simple exampled copied off of https://googleapis.dev/nodejs/storage/latest/File.html#exists
EDIT: This is how I authenticate the GCP key:
const { Storage } = require('#google-cloud/storage');
const storage = new Storage({
projectId: 'my-cloud',
keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS,
});
const bucketName = 'my-ci';
(With small changes, I realise you are supposed to return data[0])
const bucket = storage.bucket(bucketName);
const file = bucket.file(path);
const exists = await file.exists().then(data => {
return data
})
But when I try run this, I get the error:
[nodemon] starting `node --inspect server/server.js`
Debugger listening on ws://127.0.0.1:9229/9a677766-4a93-4499-b57c-55f5f05096d7
For help, see: https://nodejs.org/en/docs/inspector
Server listening on port 4000!
/opt/node_modules/jwa/index.js:115
return new TypeError(errMsg);
^
TypeError: key must be a string, a buffer or an object
at typeError (/opt/node_modules/jwa/index.js:115:10)
at checkIsPrivateKey (/opt/node_modules/jwa/index.js:61:9)
at Object.sign (/opt/node_modules/jwa/index.js:147:5)
at Object.jwsSign [as sign] (/opt/node_modules/jws/lib/sign-stream.js:32:24)
at JWTAccess.getRequestHeaders (/opt/node_modules/google-auth-library/build/src/auth/jwtaccess.js:87:31)
at JWT.getRequestMetadataAsync (/opt/node_modules/google-auth-library/build/src/auth/jwtclient.js:76:51)
at JWT.getRequestHeaders (/opt/node_modules/google-auth-library/build/src/auth/oauth2client.js:238:37)
at GoogleAuth.authorizeRequest (/opt/node_modules/google-auth-library/build/src/auth/googleauth.js:593:38)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Since the error message did not give a useful traceback, I did some digging on my own. Through putting console.log statements everywhere, I narrowed it down to the line
const exists = await file.exists().then(data => {
return data
})
and tried various approaches from removing the .then(...) clause, to removing the await (which, does work until the promise is resolved). None of these seemed to have worked.
What may be potential causes of this?
Eventually figured it out - it was due to the GCP key being an older version of the key. If you get an error like above, try to check that your key is correct.

Cant solve Error 1251 in mysql using node.js [duplicate]

I can't make a simple connection to the server for some reason. I install the newest MySQL Community 8.0 database along with Node.JS with default settings.
This is my node.js code
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
insecureAuth : true
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
Below is the error found in Command Prompt:
C:\Users\mysql-test>node app.js
C:\Users\mysql-test\node_modules\mysql\lib\protocol\Parse
r.js:80
throw err; // Rethrow non-MySQL errors
^
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
at Handshake.Sequence._packetToError (C:\Users\mysql-
test\node_modules\mysql\lib\protocol\sequences\Sequence.js:52:14)
at Handshake.ErrorPacket (C:\Users\mysql-test\node_mo
dules\mysql\lib\protocol\sequences\Handshake.js:130:18)
at Protocol._parsePacket (C:\Users\mysql-test\node_mo
dules\mysql\lib\protocol\Protocol.js:279:23)
at Parser.write (C:\Users\mysql-test\node_modules\mys
ql\lib\protocol\Parser.js:76:12)
at Protocol.write (C:\Users\mysql-test\node_modules\m
ysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (C:\Users\mysql-test\node_modul
es\mysql\lib\Connection.js:103:28)
at Socket.emit (events.js:159:13)
at addChunk (_stream_readable.js:265:12)
at readableAddChunk (_stream_readable.js:252:11)
at Socket.Readable.push (_stream_readable.js:209:10)
--------------------
at Protocol._enqueue (C:\Users\mysql-test\node_module
s\mysql\lib\protocol\Protocol.js:145:48)
at Protocol.handshake (C:\Users\mysql-test\node_modul
es\mysql\lib\protocol\Protocol.js:52:23)
at Connection.connect (C:\Users\mysql-test\node_modul
es\mysql\lib\Connection.js:130:18)
at Object.<anonymous> (C:\Users\mysql-test\server.js:
11:5)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Function.Module.runMain (module.js:701:10)
I've read up on some things such as:
https://dev.mysql.com/doc/refman/5.5/en/old-client.html
https://github.com/mysqljs/mysql/issues/1507
But I am still not sure how to fix my problem.
Execute the following query in MYSQL Workbench
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
Where root as your user
localhost as your URL
and password as your password
Then run this query to refresh privileges:
flush privileges;
Try connecting using node after you do so.
If that doesn't work, try it without #'localhost' part.
Summary
If you just want to get rid of the error, at the cost of risking the security of the project (e.g. it's just a personal project or dev environment), go with #Pras's answer -- ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password' and then flush privileges
If you want to have a fix for it, without knowing why, just install and use mysql2 (instead of mysql) and use it -- npm i mysql2, and mysql = require('mysql2');.
If you are a curious developer who is always eager to learn, keep reading ... :)
What's going on?
Let's first make it clear what's going on.
MySQL 8 has supports pluggable authentication methods. By default, one of them named caching_sha2_password is used rather than our good old mysql_native_password (source). It should be obvious that using a crypto algorithm with several handshakes is more secure than plain password passing that has been there for 24 years!
Now, the problem is mysqljs in Node (the package you install with npm i mysql and use it in your Node code) doesn't support this new default authentication method of MySQL 8, yet. The issue is in here: https://github.com/mysqljs/mysql/issues/1507 and is still open, after 3 years, as of July 2019.
UPDATE June 2019: There is a new PR in mysqljs now to fix this!
UPDATE Feb 2020: Apparently it's scheduled to come in version 3 of mysqljs.
UPDATE July 2020: Apparently it's still not in yet (as of April 2020 at least), but it's claimed that node-mysql2 is supporting Authentication switch request. Please comment below if node-mysql2 is working fine for this issue -- I will test it later myself.
UPDATE April 2021: It seems like the issue is still there and just 3 days ago, someone created a fork and made it there -- yet not official in the mysql.js package. Also, as per the comments below, it seems like mysql2 package is working fine and supporting Authentication-switch properly.
Your Current Options
Option 1) [NOT RECOMMENDED] Downgrade "MySQL" to authenticate using good old "mysql_native_password"
That's what everybody suggests here (e.g. top answer above). You just get into mysql and run a query saying root is fine using old mysql_native_password method for authentication:
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password ...
The good thing is, life is going to be simple and you can still use good old tools like Sequel Pro without any issue. But the problem is, you are not taking advantage of a more secure (and cool, read below) stuffs available to you.
Option 2) [Meh...] Replace "Node" package with MySQL Connecter X DevAPI
MySQL X DevAPI for Node is a replacement to Node's Mysqljs package, provided by http://dev.mysql.com official guys.
It works like a charm supporting caching_sha2_password authentication. (Just make sure you use port 33060 for X Protocol communications.)
The bad thing is, you have left our old mysql package that everyone is so used to and relies on.
The good thing is, your app is more secure now and you can take advantage of a ton of new things that our good old friends didn't provide! Just check out the tutorial of X DevAPI and you'll see it has a ton of new sexy features that can come in handy. You just need to pay the price of a learning curve, which expectedly comes with any technology upgrade. :)
PS. Unfortunately, this XDevAPI Package doesn't have types definition (understandable by TypeScript) yet, so if you are on typescript, you will have problems. I tried to generate .d.ts using dts-gen and dtsmake, but no success. So keep that in mind.
Option 3) [RECOMMENDED] Replace "mysql.js" with "mysql2.js" package
As mentioned above, mysql package (NPM package link) is still having this issue (as of April 2021). But mysql2 package (NPM package link) is not. So probably the following should be the one-liner answer!
npm un mysql && npm i mysql2
Please note that mysql2 is a forked work off of the popular mysql, but its popularity (620K downloads per week for mysql2 in April 2020) has got close to the original package (720K download per week for mysql in April 2021) that making the switch seems reasonable!
Using the old mysql_native_password works:
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'YourRootPassword';
-- or
CREATE USER 'foo'#'%' IDENTIFIED WITH mysql_native_password BY 'bar';
-- then
FLUSH PRIVILEGES;
This is because caching_sha2_password is introduced in MySQL 8.0, but the Node.js version is not implemented yet. You can see this pull request and this issue for more information. Probably a fix will come soon!
Full Steps For MySQL 8
Connect to MySQL
$ mysql -u root -p
Enter password: (enter your root password)
Reset your password
(Replace your_new_password with the password you want to use)
mysql> ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password';
mysql> FLUSH PRIVILEGES;
mysql> quit
Then try connecting using node
Although the accepted answer is correct, I'd prefer creating a new user and then using that user to access the database.
create user nodeuser#localhost identified by 'nodeuser#1234';
grant all privileges on node.* to nodeuser#localhost;
ALTER USER 'nodeuser'#localhost IDENTIFIED WITH mysql_native_password BY 'nodeuser#1234';
If you ran upon this issue but continued to wish to utilise version 8 of MySQL, you can. When creating the database using Docker, you can accomplish this by instructing MySQL Server to implement the legacy authentication plugin.
Thus, your compose file will seem as follows:
# Use root/example as user/password credentials
version: '3.1'
services:
db:
image: mysql:8.0.15
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'pass'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'pass'
ports:
- 3318:3306
# Change this to your local path
volumes:
- ~/Database/ORM_Test:/var/lib/mysql
If the ALTER USER ... command line doesn't work for you AND if you are using Windows 10 then try to follow those steps:
1) Type MySQL in the windows search bar
2) Open the MySQL Windows Installer - Community
3) Look for "MySQL server" and click on Reconfigure
4) Click on "Next" until you reach the "Authentification Method" phase
5) On the "Authentification Method" phase check the second option "Use Legacy Authentication Method"
6) Then follow the steps given by the Windows installer until the end
7) When it's done, go into "Services" from the Windows search bar, click on "start" MySql81".
Now, try again, the connection between MySQL and Node.js should work!
Simplest answer is :-
Use mysql2 instead of mysql in node
install mysql2 in node
npm install mysql2
Don't downgrade your mysql db.
You are good to go.
Happy Coding!
In Mysql Latest docker container
ALTER USER root IDENTIFIED WITH mysql_native_password BY 'password';
Downgrading might not be a good option as:
Its upgraded for a reason (To provide better authentication).
You might not have enough permissions to make such changes.
You can use mysql2 package in place of mysql. Its mostly API compatible with mysqljs.
Also, it has promises support.
Use it like:
const mysql = require('mysql2/promise') (for promise based methods)
You can read more about mysql2 here: https://www.npmjs.com/package/mysql2
In MySQL 8.0, caching_sha2_password is the default authentication
plugin rather than mysql_native_password. ...
Most of the answers in this question result in a downgrade to the authentication mechanism from caching_sha2_password to mysql_native_password. From a security perspective, this is quite disappointing.
This document extensively discusses caching_sha2_password and of course why it should NOT be a first choice to downgrade the authentication method.
With that, I believe Aidin's answer should be the accepted answer. Instead of downgrading the authentication method, use a connector which matches the server's version instead.
If you are using docker, it worked for me!
in the docker-compose.yml add the following lines:
mysql:
...
command: --default-authentication-plugin=mysql_native_password
restart: always
after that, down the container and up again.
For existing mysql 8.0 installs on Windows 10 mysql,
launch installer,
click "Reconfigure" under QuickAction (to the left of MySQL Server), then
click next to advance through the next 2 screens until arriving
at "Authentication Method", select "Use Legacy Authentication Method (Retain MySQL 5.x compatibility"
Keep clicking until install is complete
For MySql 8 instead of changing the authentication for the root user create a new user with all privileges and change the authentication method from caching_sha2_password to mysql_native_password.
Please check the documentation by Ochuko Ekrresa for detailed steps.
Summary of Steps:
Login as root mysql -u root -p
Create new user CREATE USER 'newuser'#'localhost' IDENTIFIED BY 'password';
Grand all permission GRANT ALL PRIVILEGES ON *.* TO 'newuser'#'localhost';
Check the above-mentioned document link to get details on giving specific privileges.
Reload the privileges FLUSH PRIVILEGES;
Quit MySql quit; and login again with mysql -u [newuser] -p;
Last step change the authentication ALTER USER 'newuser'#'localhost' IDENTIFIED WITH mysql_native_password by 'password';
Additional Info:
For me after changing authentication for root, I was faced with Authentication issues and was unable to login. So I reset my password(Reset password doc).
Original documentation you can find here : https://dev.mysql.com/doc/dev/connector-nodejs/8.0/
'use strict';
const mysqlx = require('#mysql/xdevapi');
const options = {
host: 'localhost',
port: 33060,
password: '******',
user: 'root',
schema: 'yourconference'
};
mysqlx.getSession(options)
.then(session => {
console.log(session.inspect());
session.close();
}).catch(err => {
console.error(err.stack);
process.exit(1);
});
I have MYSQL on server and nodejs application on another server
Execute the following query in MYSQL Workbench
ALTER USER 'root'#'%' IDENTIFIED WITH mysql_native_password BY 'password'
With MySQL 8+ the new default authentication is caching_sha2_password instead of mysql_native_password. The new and more secure authentication method is not supported by the native mysql package yet, but you should consider using the package #mysql/xdevapi instead, which is officially supported and maintained by Oracle.
To install the new package, run:
npm install #mysql/xdevapi --save --save-exact
To connect to the database and INSERT some VALUES:
const mysqlx = require('#mysql/xdevapi');
var myTable;
mysqlx
.getSession({
user: 'root',
password: '*****',
host: 'localhost',
port: 33060
})
.then(function (session) {
// Accessing an existing table
myTable = session.getSchema('Database_Name').getTable('Table_Name');
// Insert SQL Table data
return myTable
.insert(['first_name', 'last_name'])
.values(['John', 'Doe'])
.execute()
});
The official package documentation can be found here:
https://dev.mysql.com/doc/dev/connector-nodejs/8.0/
In addition to the above answers ;
After executing the below command
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
If you get an error as :
[ERROR] Column count of mysql.user is wrong. Expected 42, found 44. The table is probably corrupted
Then try in the cmd as admin; set the path to MySQL server bin folder in the cmd
set path=%PATH%;D:\xampp\mysql\bin;
and then run the command :
mysql_upgrade --force -uroot -p
This should update the server and the system tables.
Then you should be able to successfully run the below commands in a Query in the Workbench :
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
then remember to execute the following command:
flush privileges;
After all these steps should be able to successfully connect to your MySQL database.
Hope this helps...
I just run into this problem too, with all the MySQL re-config mentioned above the error still appears. It turns out that I misspelled the database name.
So be sure you're connecting with the right database name especially the case.
I would recommend to use Knexjs with MySQL2.
And you have good to go with caching_sha2_password auth method.
Query with Knex:
const response = await knex.raw("SELECT * FROM USERS");
OR
If you don't have a remote user then use CREATE keyword instead of ALTER and just put the below command on the terminal.
ALTER USER 'root'#'%' IDENTIFIED WITH mysql_native_password BY 'yourpass';
GRANT ALL ON *.* TO 'root'#'%';
Flush privileges;
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpass';
GRANT ALL ON *.* TO 'root'#'localhost';
Flush privileges;
All done :)
simple i uninstall mysql and install mysql2 for this issues and
problem solved.
npm uninstall mysql && npm i mysql2
Check privileges and username/password for your MySQL user.
For catching errors it is always useful to use overrided _delegateError method. In your case this has to look like:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
insecureAuth : true
});
var _delegateError = con._protocol._delegateError;
con._protocol._delegateError = function(err, sequence) {
if (err.fatal)
console.trace('MySQL fatal error: ' + err.message);
return _delegateError.call(this, err, sequence);
};
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
This construction will help you to trace fatal errors.
Just figured this out after trying numerous things. What finally did it for me was adding require('dotenv').config() to my .sequelizerc file. Apparently sequelize-cli doesn't read env variables.
You can skip the ORM, builders, etc. and simplify your DB/SQL management using sqler and sqler-mdb.
-- create this file at: db/mdb/read.table.rows.sql
SELECT TST.ID AS "id", TST.NAME AS "name", NULL AS "report",
TST.CREATED_AT AS "created", TST.UPDATED_AT AS "updated"
FROM TEST TST
WHERE UPPER(TST.NAME) LIKE CONCAT(CONCAT('%', UPPER(:name)), '%')
const conf = {
"univ": {
"db": {
"mdb": {
"host": "localhost",
"username":"admin",
"password": "mysqlpassword"
}
}
},
"db": {
"dialects": {
"mdb": "sqler-mdb"
},
"connections": [
{
"id": "mdb",
"name": "mdb",
"dir": "db/mdb",
"service": "MySQL",
"dialect": "mdb",
"pool": {},
"driverOptions": {
"connection": {
"multipleStatements": true
}
}
}
]
}
};
// create/initialize manager
const manager = new Manager(conf);
await manager.init();
// .sql file path is path to db function
const result = await manager.db.mdb.read.table.rows({
binds: {
name: 'Some Name'
}
});
console.log('Result:', result);
// after we're done using the manager we should close it
process.on('SIGINT', async function sigintDB() {
await manager.close();
console.log('Manager has been closed');
});
I had this error for several hours an just got to the bottom of it, finally. As Zchary says, check very carefully you're passing in the right database name.
Actually, in my case, it was even worse: I was passing in all my createConnection() parameters as undefined because I was picking them up from process.env. Or so I thought! Then I realised my debug and test npm scripts worked but things failed for a normal run. Hmm...
So the point is - MySQL seems to throw this error even when the username, password, database and host fields are all undefined, which is slightly misleading..
Anyway, morale of the story - check the silly and seemingly-unlikely things first!
If you have access to create a new user privilege then do so to connect normally with node.js, that is worked for me
UPDATE mysql.user SET authentication_string = PASSWORD('MY_NEW_PASSWORD')
WHERE User = 'root' AND Host = 'localhost';
FLUSH PRIVILEGES;
This worked for me.
If you're on Mac OS, and would like to use the legacy password encryption without using terminal.
Go to System Settings -> Find "My SQL" -> Click "Initialize Database" -> Select "Use legacy password encryption" and enter your database user password in the textfield and click "Ok"
Just Run MySQL Server Installer and Reconfigure the My SQL Server...This worked for me.
you should use whatever schema you use for your mysql connection for your session
(async () => {
const connection = await db.connection();
sessionStore = new MySQLStore({
}, connection); //just pass your connection here
})();
I just copy paste this here but your probably have implemented something similar to this to deal with your queries
const mysql = require('mysql')
if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
require('dotenv').config();
}
const dbConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
connectionLimit: process.env.DB_CONNECTION_LIMITS
}
const pool = mysql.createPool(dbConfig);
const connection = () => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
reject(err);
}
const query = (sql, binding) => {
return new Promise((resolve, reject) => {
connection.query(sql, binding, (err, result) => {
if (err) {
reject(err);
}
resolve(result);
});
});
};
const release = () => {
return new Promise((resolve, reject) => {
if (err) {
reject(err);
}
resolve(connection.release());
});
};
resolve({ query, release });
});
});
};
const query = (sql, binding) => {
return new Promise((resolve, reject) => {
pool.query(sql, binding, (err, result, fields) => {
if (err) {
reject(err);
}
resolve(result);
});
});
};
module.exports = { pool, connection, query };

Redis connection is lost after multiple calls to function

The program I am writing is a status display screen for alarms, each of which is represented by a channel.
When the server is started (run on a vagrant virtual machine), an Influx database is accessed, the data (comprising of 1574 'channels') is processed and put into a Redis database. This runs fine and the GUI is displayed with no issues when the webpage is refreshed, although it takes a long time to load (up to 20s), and nearly all of this time is spent in the method below.
However, after a few refreshes/moving around the site, it often crashes with the following error:
{ AbortError: Redis connection lost and command aborted. It might
have been processed.
at RedisClient.flush_and_error (/vagrant/node_modules/redis/index.js:362:23)
at RedisClient.connection_gone (/vagrant/node_modules/redis/index.js:664:14)
at RedisClient.on_error (/vagrant/node_modules/redis/index.js:410:10)
at Socket. (/vagrant/node_modules/redis/index.js:279:14)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at onwriteError (_stream_writable.js:417:12)
at onwrite (_stream_writable.js:439:5)
at _destroy (internal/streams/destroy.js:39:7)
at Socket._destroy (net.js:568:3) code: 'UNCERTAIN_STATE', command: 'HGETALL', args: [
'vista:hash:Result:44f59707-c873-11e8-93b9-7f551d0bdd1f' ], origin:
{ Error: Redis connection to 127.0.0.1:6379 failed - write EPIPE
at WriteWrap.afterWrite (net.js:868:14) errno: 'EPIPE', code: 'EPIPE', syscall: 'write' } }
This error is displayed 1574 times (once for each channel), and occurs when the program reaches this function:
Result.getFormattedResults = async function (cycle) {
const channels = await Channel.findAndLoad()
const formattedResults = await mapAsyncParallel(channels, async channel => {
const result = await this.findAndLoadByChannel(channel, cycle)
const formattedResult = await result.format(channel)
return formattedResult
})
return formattedResults
}
mapAsyncParallel() is as follows:
export const mapAsyncParallel = (arr, fn, thisArg) => {
return Promise.all(arr.map(fn, thisArg))
}
findAndLoadByChannel() finds the channel and loads it with this line:
const resultModel = await this.load(resultId)
And format() takes the model and outputs the data as in a JSON format
There are two 'fetch(...)' commands (which are needed and cannot be combined) in the front end, and the problem rarely occurs when I comment out one of them (either one). This is making me think it could be a max memory or max connections problem? (increasing maxmemory in the config file didn't help). Or a problem with using so many promises (a concept I am fairly new to).
This has only started to occur as I have added more functionality and I assume the function needs optimizing but I have taken over this project from someone else and am still quite new to node.js and redis.
Versions:
Vagrant: 2.0.1
Ubuntu: 16.04.5
Redis: 4.0.9
Node: 8.12.0
npm: 5.7.1
I've now moved all the 'getting' of the data (from redis) to the server side channels.controller file.
So, where before I would have:
renderPage: async (req, res) => {
res.render('page')
},
I now have a method like:
renderPage: async (req, res) => {
const data1 = getData1()
const data2 = getData2()
res.render('page', {data1, data2})
},
(Don't worry, these aren't my actual variable names)
Where the two 'data' variables were previously retrieved using the 'fetch' method.
I export the data once it's loaded into redis, and import it in the controller file, where I have the getters to combine it all into one return array.
The pages now take milliseconds to refresh and I haven't had any crashes

Node.JS exec git command error: Permission denied (publickey)

Question: How can I run git push from node.js with passphrase.
I'm trying to build a small module where I need to run git push from node.js to a remote repo, but I'm getting an error when I with from node.js exec but not from the terminal.
My code.
./command.ts
import * as util from 'util';
const exec = util.promisify(require('child_process').exec);
export default function command(command: string): Promise<string> {
return exec(command, {cwd: process.cwd()}).then((resp) => {
const data = resp.stdout.toString().replace(/[\n\r]/g, '');
return Promise.resolve(data);
});
}
./index.ts
import command from './command';
async function init() {
try {
await command('git add .');
await command('git commit -m "my commit" ');
conat result = await command('git push');
} catch (e) {
console.log(e);
}
}
init();
and when I run ts-node ./index.ts I get the following error.
Error: Command failed: git push
git#hostname.org: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
But when I run git push from the terminal I get prompt with the passphrase and it works.
Any idea on how to solve this issue, is there a way to run git push with passphrase using node.js?
bear in mind that I will love to fix this without any external libs.
Thanks in advance.
As described here, check if the same program works when:
ssh-agent is launched
your key is ssh-add'ed
Not only the prompt should no longer query for your passphrase (now cached by the agent), but your script might benefit from that cache as well.
You may need to add env: process.env to your exec() options if your key is loaded into an ssh-agent process. There are some environment variables ssh-agent exports that other processes use to find ssh-agent to access its keys.

Categories

Resources