I try to retrieve data from SQL Server using npm mssql package. When I used postman to make a request, I got same data (resultset) at every time although data was changed.
My SQL Server connection config and code is here:
const sql = require('mssql');
const config = {
user: 'XXXX',
password: 'XXXX',
server: 'XXXX',
database: 'XXXX',
pool: {
max: 50,
min: 0,
idleTimeoutMillis: 10
},
options: {
trustServerCertificate: true
}
}
const getConnection = async () => {
try {
const conn = await sql.connect(config);
return {pool: conn, err: false, errorMSG: null};
} catch (err) {
return {conn: null, err: true, errorMSG: err}
}
};
And my db function :
const conn = await getConnection();
if (conn.err == false) {
try {
let result = await conn.pool.request()
.input('registryNumber', sql.NVarChar(50), registryNumber)
.input('password', sql.NVarChar(50), password)
.query('SELECT role FROM [OperatorLogin].[dbo].[TBL_users]' +
'WHERE [TBL_users].[registryNumber] = #registryNumber AND [TBL_users].[password] = #password AND [TBL_users].[isActive] = 1 ')
if (result.rowsAffected[0] >= 1) {
return { Execution: true, ExecutionCode: 1, ExecutionMessage: "Record is available", ExecutionData: result.recordset }
}
else {
return { Execution: true, ExecutionCode: 2, ExecutionMessage: "No records", ExecutionData: "" }
}
}
catch (err) {
return { Execution: false, ExecutionCode: -1, ExecutionMessage: "DB pool request error : " + err, ExecutionData: "" }
}
}
else {
return { Execution: false, ExecutionCode: -1, ExecutionMessage: " DB error : " + conn.errorMSG, ExecutionData: "" }
}
On the other hand, I use pm2 and reverse proxy on Windows server.
What may be problem ? What am I missing ?
Related
Using these libraries to connect to ews and get emails:
"ews-javascript-api": "^0.10.3"
"ews-javascript-api-auth": "^1.2.1"
Locally it works and I can connect to email boxes but when I run it on Jenkins I get this error:
SoapFaultDetails {
message: 'read ECONNRESET',
InnerException: null,
faultCode: null,
faultString: null,
faultActor: null,
responseCode: 127,
errorCode: 0,
exceptionType: null,
lineNumber: 0,
positionWithinLine: 0,
errorDetails: DictionaryWithStringKey {
keys: [],
keysToObjs: {},
objects: {},
keyPicker: [Function (anonymous)]
},
HttpStatusCode: undefined
}
A function which connects and read the email:
function getEws(user, password, host, subject) {
ews.ConfigurationApi.ConfigureXHR(new ewsAuth.ntlmAuthXhrApi(user, password))
const service = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013_SP1)
service.Credentials = new ews.WebCredentials(user, password)
service.Url = new ews.Uri(host)
service
.SubscribeToStreamingNotifications(
[new ews.FolderId(ews.WellKnownFolderName.Inbox)],
ews.EventType.NewMail,
ews.EventType.Created,
ews.EventType.Deleted,
ews.EventType.Modified,
ews.EventType.Moved,
ews.EventType.Copied,
ews.EventType.FreeBusyChanged
)
.then(function (streamingSubscription) {
var connection = new ews.StreamingSubscriptionConnection(service, 1)
connection.AddSubscription(streamingSubscription)
connection.OnNotificationEvent.push(function (obj) {
ews.EwsLogging.Log(obj, true, true)
const searchFilter = new ews.SearchFilter.SearchFilterCollection(ews.LogicalOperator.And, [
new ews.SearchFilter.ContainsSubstring(ews.ItemSchema.Subject, subject)
])
const itemview = new ews.ItemView(1)
const foundItems = service.FindItems(ews.WellKnownFolderName.Inbox, searchFilter, itemview)
const adinationalProps = []
adinationalProps.push(ews.ItemSchema.TextBody)
foundItems.then(function (response) {
for (const item of response.Items) {
item
.Load(new ews.PropertySet(ews.BasePropertySet.FirstClassProperties, adinationalProps))
.then(function () {
fs.writeFileSync('cypress/fixtures/email.txt', item.TextBody.text)
})
.catch(error => {
console.log(' ----- Load error start ----- ')
console.error(error)
console.log(' ----- Load error end ----- ')
})
}
})
})
connection.OnDisconnect.push(function (connection, subscriptionErrorEventArgsInstance) {
ews.EwsLogging.Log(subscriptionErrorEventArgsInstance, true, true)
})
connection.Open()
})
.catch(error => {
console.log(' ----- SubscribeToStreamingNotifications error start ----- ')
console.error(error)
console.log(' ----- SubscribeToStreamingNotifications error end ----- ')
})
}
I would be grateful for any ideas on how to solve this issue on Jenkins.
That was an issue with expired SSL certificates on Travis's side.
Hi i am trying to setup LDAP authentication for my meteorJS app and i am following the steps listed in here https://janikvonrotz.ch/2017/02/08/meteor-register-ldap-login-request-handler/
i changed the search filter from mail to username and pushed everything inside of Meteor.startup() here is my code set up
UI code written in /imports/ui/loginform.jsx
let loginUserWithLDAP = (username, password, callback) => {
var loginRequest = {
ldap: true,
username: username,
email: username+"#company.com",
pass: password,
}
Accounts.callLoginMethod({
methodArguments: [loginRequest],
userCallback: callback
})
}
in my /server/ldap.js
Meteor.startup(() => {
var ldapAuth = {
url: 'ldap://company.com:389',
searchOu: 'ou=Employees,ou=\'company Users\', dc=company,dc=com',
searchQuery: (username) => {
return {
filter: '(&(objectclass=user)(samaccountname='+username+'))',
scope: 'sub'
}
}
}
ldapAuth.checkAccount = (options) => {
options = options || {}
ldapAuth.client = ldap.createClient({
url: ldapAuth.url
})
let dn = ['company', 'com']
var future = new Future()
ldapAuth.client.search(
ldapAuth.searchOu,
ldapAuth.searchQuery(options.username),
(error, result)=> {
assert.ifError(error)
result.on('searchEntry', (entry) => {
dn.push(entry.objectName)
return ldapAuth.profile = {
firstname: entry.object.cn,
lastname: entry.object.sn
}
})
result.on('error', function(error){
throw new Meteor.Error(500, "LDAP server error")
})
result.on('end', function(){
if (dn.length === 0) {
future['return'](false)
return false
}
return ldapAuth.client.bind(dn[0], options.pass, (error) =>{
if (error){
future['return'](false)
return false
}
return ldapAuth.client.unbind((error) => {
assert.ifError(error)
return future['return'](!error)
});
})
})
})
return future.wait()
}
Accounts.registerLoginHandler('ldap', (loginRequest)=>{
if (!loginRequest.ldap) {
return undefined
}
if (ldapAuth.checkAccount(loginRequest)){
var userId = null
var user = Meteor.users.findOne({"username": loginRequest.username })
if (!user) {
userId = Accounts.createUser({
username: loginRequest.username,
password: loginRequest.pass,
profile: ldapAuth.profile,
roles: ['user'],
})
Meteor.users.update(userId, { $set: { 'emails.0.verified': true } })
} else {
userId = user._id
}
let stampedToken = Accounts._generateStampedLoginToken()
let hashStampedToken = Accounts._hashStampedToken(stampedToken)
Meteor.users.update(userId,
{ $push: {'services.resume.loginTokens': hashStampedToken } }
)
return {
userId: userId,
token: stampedToken.token
}
}
})
});
In my debugging i found that its erroring out at
result.on('error', function(error){
throw new Meteor.Error(500, "LDAP server error")
})
due to '000004DC: LdapErr: DSID-0C0907E9, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v2580' what does this mean?
What is my code missing?
In short you need to define a search user that does the binding with the LDAP directory.
The post is outdated, I've got you this example: https://github.com/janikvonrotz/Zenkom/blob/0583f01abca96847178a248ff446d84c754965e9/server/actions/ldap.js#L18
Setup the search user like this:
"searchUser": {
"dn": "CN=username,OU=org,DC=company,DC=ch",
"password": "password"
}
The bind user is simply for search the directory. Another bind is executed to authenticate the found user.
How can i abort an update operation using beforeUpdate hook on sequelize and return a object as the result from a aborted update,
if i have something like:
User.beforeUpdate(function(user, options) {
if (user.name == "example_name") {
// abort operation here
// return object to the update caller
}
}
throw from before hooks does prevent the update
E.g.:
beforeUpdate: (integerName, options) => {
if (integerName.value === 5) {
throw new Error('beforeUpdate')
}
},
and throws on .update caller.
But remember from why sequelize beforeUpdate hook doesn't work? that the before only fires if the caller uses:
Model.update({}, {individualHooks: true})
which would be annoying to remember to pass every time.
The beforeValidate hook however fires even without individualHooks, so maybe that's the way to go.
The fact that throwing works for create is documented at: https://sequelize.org/master/manual/hooks.html#instance-hooks
User.beforeCreate(user => {
if (user.accessLevel > 10 && user.username !== "Boss") {
throw new Error("You can't grant this user an access level above 10!");
}
});
The following example will throw an error:
try {
await User.create({ username: 'Not a Boss', accessLevel: 20 });
} catch (error) {
console.log(error); // You can't grant this user an access level above 10!
};
The following example will be successful:
const user = await User.create({ username: 'Boss', accessLevel: 20 });
console.log(user); // user object with username 'Boss' and accessLevel of 20
Also mentioned at: https://github.com/sequelize/sequelize/issues/11298
Minimal runnable example:
main.js
#!/usr/bin/env node
const assert = require('assert')
const path = require('path')
const { DataTypes, Sequelize } = require('sequelize')
let sequelize
if (process.argv[2] === 'p') {
sequelize = new Sequelize('tmp', undefined, undefined, {
dialect: 'postgres',
host: '/var/run/postgresql',
})
} else {
sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'tmp.sqlite',
})
}
function assertEqual(rows, rowsExpect) {
assert.strictEqual(rows.length, rowsExpect.length)
for (let i = 0; i < rows.length; i++) {
let row = rows[i]
let rowExpect = rowsExpect[i]
for (let key in rowExpect) {
assert.strictEqual(row[key], rowExpect[key])
}
}
}
;(async () => {
const IntegerNames = sequelize.define('IntegerNames',
{
value: { type: DataTypes.INTEGER },
name: { type: DataTypes.STRING },
},
{
hooks: {
beforeCreate: (integerName, options) => {
if (integerName.value === 42) {
throw new Error('beforeCreate')
}
},
beforeValidate: (integerName, options) => {
if (integerName.value === 43) {
throw new Error('beforeValidate')
}
},
beforeUpdate: (integerName, options) => {
if (integerName.value === 5) {
throw new Error('beforeUpdate')
}
},
}
},
)
await IntegerNames.sync({ force: true })
async function reset() {
await sequelize.truncate({ cascade: true })
await IntegerNames.create({ value: 2, name: 'two' })
await IntegerNames.create({ value: 3, name: 'three' })
await IntegerNames.create({ value: 5, name: 'five' })
}
async function assertUnchanged() {
const rows = await IntegerNames.findAll()
assertEqual(rows, [
{ id: 1, value: 2, name: 'two', },
{ id: 2, value: 3, name: 'three', },
{ id: 3, value: 5, name: 'five', },
])
}
await reset()
let rows, exc
await assertUnchanged()
// beforeCreate
exc = undefined
try {
await IntegerNames.create({ value: 42, name: 'forty-two' })
} catch (e) {
exc = e
}
assert.strictEqual(exc.message, 'beforeCreate')
await assertUnchanged()
// beforeValidate
exc = undefined
try {
await IntegerNames.create({ value: 43, name: 'forty-three' })
} catch (e) {
exc = e
}
assert.strictEqual(exc.message, 'beforeValidate')
await assertUnchanged()
// beforeUpdate
exc = undefined
try {
await IntegerNames.update(
{ name: 'five hacked', },
{
where: { value: 5 },
individualHooks: true,
},
);
} catch (e) {
exc = e
}
assert.strictEqual(exc.message, 'beforeUpdate')
await assertUnchanged()
// using the beforeValidate
exc = undefined
try {
await IntegerNames.update(
{ value: 43, },
{
where: { value: 5 },
},
);
} catch (e) {
exc = e
}
assert.strictEqual(exc.message, 'beforeValidate')
await assertUnchanged()
})().finally(() => { return sequelize.close() })
package.json
{
"name": "tmp",
"private": true,
"version": "1.0.0",
"dependencies": {
"pg": "8.5.1",
"pg-hstore": "2.3.3",
"sequelize": "6.14.0",
"sql-formatter": "4.0.2",
"sqlite3": "5.0.2"
}
}
GitHub upstream. Tested on Ubuntu 21.10, PostgreSQL 13.5.
Below is my code (under file db.js)
function connection() {
try {
const mysql = require('mysql2');
const pool = mysql.createPool({
host: "mydb.abcd1234.ap-southeast-1.rds.amazonaws.com",
database: "mydatabase",
user: "user",
password: "password",
connectionLimit: 11,
waitForConnections: true,
queueLimit: 0,
namedPlaceholders: true
});
const promisePool = pool.promise();
return promisePool;
} catch (error) {
return console.log(`Could not connect - ${error}`);
}
}
const pool = connection();
module.exports = {
connection: async () => pool.getConnection(),
execute: (...params) => pool.execute(...params)
};
And to use it, I simply add var db = require('./../db.js'); at the top of the files that requires it. Additionally, below is how I'd execute any sql statements
const myResult = await db.execute("Select COUNT(*) AS dataCount from teachers WHERE username = ?", [username]);
But now I need to separate my database according to countries. So my database would be named with mydatabase_ + the country code, for example mydatabase_my , mydatabase_jp, mydatabase_uk etc etc. So how do I pass the country code to the function connection() ?
I tried something like
function connection(country) {
try {
const mysql = require('mysql2');
const pool = mysql.createPool({
host: "mydb.abcd1234.ap-southeast-1.rds.amazonaws.com",
database: "mydatabase_" + country,
user: "user",
password: "password",
connectionLimit: 11,
waitForConnections: true,
queueLimit: 0,
namedPlaceholders: true
});
const promisePool = pool.promise();
return promisePool;
} catch (error) {
return console.log(`Could not connect - ${error}`);
}
}
const pool = connection(country);
module.exports = {
connection: async (country) => pool.getConnection(country),
execute: (...params) => pool.execute(...params)
};
and at the calling page, I did
var db = require('./../db.js');
db.connection("my")
but for the above, I will get ReferenceError: country is not defined which refers to country at the line const pool = connection(country);
Here's how I did it:
const mysql = require('mysql2');
const pool = function(country){
var mydb = mysql.createPool({
host: "mydb.abcd1234.ap-southeast-1.rds.amazonaws.com",
database: "mydatabase_" + country,
user: "user",
password: "password",
connectionLimit: 11,
waitForConnections: true,
queueLimit: 0,
namedPlaceholders: true
});
return mydb;
}
const promisePool = function(country){
return pool(country).promise();
}
module.exports = {
connection: async (country) => promisePool(country).getConnection(),
execute: (country,...params) => promisePool(country).execute(...params)
};
And in the page that uses mysql will have something like this:
db.connection(country)
const myResult = await db.execute(country, "Select * from schools");
I created funnction app and service bus (with topic and its subscriptions), then added function (triggered by new message in topic's sub.). I wanted to write that message to DB (created that db and sql server for it - tried and i coudl connect with my local scripts and clients). Then, I added script's code into index.js in that new function:
module.exports = function(context, mySbMsg) {
context.log('EVENT : ', mySbMsg);
const dbConfig = {
client: 'mssql',
connection: {
server: '---',
user: '---',
password: '---',
options: {
database: '---',
port: 1433,
encrypt: true
}
}
}
const knex = require('knex')(dbConfig);
const newRow = {MessageRecived:mySbMsg}
context.log(' New row : ', newRow);
var res;
return knex.insert(newRow).into('MyEvents').timeout(3000)
.then((output)=>{
context.log(' result : ');
context.log(output);
res = { status: 201, body: "Insert succeeded." };
})
.catch((error) => {
context.log(' error : ');
context.log(error);
res = { status: 500, body: "Error occured" };
})
.finally(() => {
console.log('>> FINALLY');
knex.destroy();
context.done(null, res);
});
};
I dont understand why each request just "hangs" until Fucntion App itself decide it wont finsih, mark it as timeout and leaves. I thought it is becouse of knex, but I added "Destroy"... Still i don't know - Why isn't it working?