I want to verify incoming token and I try to find user by Id:
module.exports = function (req) {
var decodeToken = jwt.decode(req.cookies.token, JwtOptions.secretOrKey);
db.users.findById(decodeToken.id).then(function (foundUser) {
//It's example checking for self-learning
if (foundUser.username == req.cookies.username) {
return foundUser;
}
//Or more logic for token authentication
}), function (error) {
return error;
}
But I get "return false". I view foundUser variable for debuggindg, and it has message
'Reference Error: foundUser is nor defined'
In console I can see query:
Executing (default): SELECT "id", "username", "email", "password",
"createdAt", "updatedAt" FROM "users" AS "users" WHERE "users"."id" =
2;
And I have the user with id=2 in a db.
Why it doesn't work?
Addition:
I tried MWY's modified example:
module.exports = function (req) {
var decodeToken = jwt.decode(req.cookies.token, JwtOptions.secretOrKey);
findUserById().then(function(foundUser) {
//It's example checking for self-learning
if (foundUser.username == req.cookies.username) {
return foundUser;
}
//Or more logic for token authentication
}), function (error) {
return error;
}
function findUserById() {
return db.users.findById(decodeToken.id).then(function (foundUser) {
return foundUser;
}), function (error) {
return error;
}
}
}
And get error:
TypeError: findUserById(...).then is not a function
Be sure to remember asynchronously
Because asynchronously! you will get false first, then get the result!
So you can write like this, In ty.js file
module.exports = function (req) {
var decodeToken = jwt.decode(req.cookies.token, JwtOptions.secretOrKey);
return db.users.findById(decodeToken.id).then(function (foundUser) {
//It's example checking for self-learning
if (foundUser.username == req.cookies.username) {
return foundUser;
}
//Or more logic for token authentication
}).catch(function (err) {
return err;
})
};
In tu.js file:
var user = require('./ty');
user().then(function (result) {
//search findById result
console.log(result)
});
Related
I am making a call to a callable firebase function from my iOS app and am getting a return value of null. The correct value was returned just a few days ago, but now it's always returning null. The data is logging correctly in the console just before the return line, and there is no error appearing within the iOS call.
exports.startPlaylist = functions.https.onCall((data, context) => {
const uid = context.auth.uid;
const signature = data.signature;
return axios.post('---url----', {
data: signature
}).then(function(response) {
const val = response.data;
const ref = database.ref().push();
ref.set({
host: {
uid: uid
},
users: {
uid: uid
},
books: val
}, function(error) {
if(error) {
console.log('Not set');
} else {
const info = { id: ref.key };
console.log(info) //Correct log value appears in console
return info; //Return null, however
}
});
}).catch(function(err) {
console.log(err);
});
});
Firebase call
Functions.functions().httpsCallable("startPlaylist").call(["signature": signature]) { (result, error) in
guard let result = result, error == nil else { return }
print(result.data) //<-- prints "null"
}
As stated you should work with the promise returned by set:
ref.set({
host: {
uid: uid
},
users: {
uid: uid
},
books: val
}).then(function() {
const info = { id: ref.key };
console.log(info)
return info;
})
.catch(function(error) {
console.log('Not set');
});
I am writing a node app's REST API using Sqlite3. The app will have accounts, and the user should be able to create and update one. My code for creating and fetching accounts works as intended, but my update function throws the error: "TypeError: callback is not a function"
The backend is split in two files; db.js – where I set up the database and create the base function for get/post/put/delete, and app.js – where I call the function from db and perform validation checks.
when i run the function in postman, i get error code 500. in vscode, the terminal reads:
Project/rbrneck/rbrneck-backend/db.js:124
callback([], updatedAccount)
^
TypeError: callback is not a function
at Statement.db.run
code:
//in db.js
exports.updateAccountById = (id, updatedAccount, callback) => {
const query = 'UPDATE accounts SET username = ?, password = ? WHERE id = ?'
const values = [
id,
updatedAccount.username,
updatedAccount.password
]
db.run(query, values, (error) => {
if(error) {
if(error.message == "SQLITE_CONSTRAINT: UNIQUE constraint failed: accounts.username") { //username taken
callback(['usernameTaken'])
} else {
callback(['databaseError'])
}
} else {
//const accountUpdated = (this.changes == 1)
callback([], updatedAccount) //HERE IS THE CALLBACK THE ERROR IS REFERRING TO
}
})
}
// in app.js:
app.put('/accounts/:id', (req, res, next) => {
const id = req.params.id
const updatedAccount = req.body
//errors and validation
//type of input
if(typeof(updatedAccount.username) !== 'string' && typeof(updatedAccount.password) !== 'string') {
res.status(422).json({
message: 'Unprocessable Entry'
}).end()
return
}
//does the account exist?
db.getAccountById(id, (errors, oldAccount) => {
if(errors.length > 0) {
res.status(500).json({
message: 'Internal Server Error'
}).end()
return
} else if (!oldAccount) {
res.status(404).end()
return
}
})
//validation:
const validationErrors = []
if(updatedAccount.username.length < USERNAME_MIN_LENGTH) {
validationErrors.push('Username too short')
} else if (updatedAccount.username.length > USERNAME_MAX_LENGTH) {
validationErrors.push('Username too long')
}
if(updatedAccount.password.length < PASSWORD_MIN_LENGTH) {
validationErrors.push('Password too short')
} else if (updatedAccount.password.length > PASSWORD_MAX_LENGTH) {
validationErrors.push('Password too long')
}
if(validationErrors.length > 0) {
res.status(400).json(validationErrors).end()
return
}
db.updateAccountById(updatedAccount, (errors, userId) => {
if(errors.length == 0) {
res.setHeader('Location', '/accounts/' + userId)
res.status(201).end()
} else if (errors.includes('usernameTaken')) {
res.status(400).json(errors).end()
} else {
res.status(500).end()
}
})
})
I am trying to create a record in dynamodb(Using dynamoose). code is
class Test {
constructor() {
this.table = dynamoose.model(tableName, tableSchema);
}
// userdata object - {
// cusotmerEmail: 'tushar.gaurav+testf40#accionlabs.com',
// customerBusinessName: 'DoogleDnd',
// customerFirstName: 'Tushar',
// customerId: 101211,
// customerLastName: 'Gaurav',
// isDeleted: false,
// sku: '100',
// userId: '5c1776e94bea867c3f896236'
// }
async createUser(userData) {
try {
const res = await this.table.create(userData);
console.log('Update user record - ', res);
return res;
} catch (error) {
throw new Error(error);
}
}
}
*input values to the create function are correct as the same input I tried with batchPut(), it's working.
And even update call to the table is also working.
async updateUser(userData) {
try {
const res = await this.table.update(userData);
console.log('Updated user record - ', res);
return res;
} catch (error) {
throw new Error(error);
}
}
This is the error I am getting -
Error - {"message":"The conditional request failed", "code":"ConditionalCheckFailedException", "statusCode":400}
This is the calling function -
module.exports.subscribeUser = async (event) => {
let inputBody = (typeof event.body === 'object' ? event.body :
JSON.parse(event.body));
inputBody.userId = event.pathParameters.id;
try {
// Validate input
await asisvc.validateInput(inputBody);
inputBody = await UserSvc.constructUserObject(inputBody);
console.log('Constructed object - ', JSON.stringify(inputBody));
const userData = await testObj.createUser(inputBody);
return Utils.buildResp(codes.ok, { userData }, {});
} catch (error) {
console.log(error);
return Utils.buildResp(codes.badrequest, { Error:
Utils.getErrString(error) }, {});
}
};
I tried googling it, but didn't find any proper document.
Thanks in advance.
In Dynamoose by default we check to see if the primary key already exists in the table when using the Model.create method.
So your error:
{"message":"The conditional request failed", "code":"ConditionalCheckFailedException", "statusCode":400}
Indicates that the primary key already exists in the table. So you are trying to create a duplicate item.
In the documentation there is an options property that you can use to allow overriding the object.
For example the following code will allow overrides:
const res = await this.table.create(userData, {overwrite: true});
I'm writing a React Redux CRUD App with Node.js API. I'm struggling with DELETE part.
I'm receiving the successful delete message but nothing has changed in my database. Successful Message in Console
I just wonder why it's not deleting any data?
user.reducer :
import { userConstants } from '../_constants';
export function users(state = {}, action) {
switch (action.type) {
case userConstants.GETALL_REQUEST:
return {
loading: true
};
case userConstants.GETALL_SUCCESS:
return {
items: action.users
};
case userConstants.GETALL_FAILURE:
return {
error: action.error
};
case userConstants.DELETE_REQUEST:
// add 'deleting:true' property to user being deleted
return {
...state,
items: state.items.map(user =>
user.id === action.id
? { ...user, deleting: true }
: user
)
};
case userConstants.DELETE_SUCCESS:
// remove deleted user from state
return {
items: state.items.filter(user => user.id !== action.id)
};
case userConstants.DELETE_FAILURE:
// remove 'deleting:true' property and add 'deleteError:[error]' property to user
return {
...state,
items: state.items.map(user => {
if (user.id === action.id) {
// make copy of user without 'deleting:true' property
const { deleting, ...userCopy } = user;
// return copy of user with 'deleteError:[error]' property
return { ...userCopy, deleteError: action.error };
}
return user;
})
};
default:
return state
}
}
user_actions:
export const userService =
{
delete: _delete,
};
function _delete(id) {
const requestOptions = {
method: 'DELETE',
// headers: authHeader(),
};
return fetch(`/removeadmin/${id}` , requestOptions).then(handleResponse);
}
AdminListPage component :
delete(){
this.props.dispatch(userActions.delete(this.state.delete_user._id));
}
Also, in server-side I'm receiving a successful delete status
ServerSide Console(200)
Server_Side router:
app.delete('/removeadmin/:id', function(req, res)
{
var sent_url = url.parse(req.url, true),
qdata = sent_url.query,
sent_id = qdata.id;
console.log('id ' + sent_id);
admin.removeadmin(sent_id, function(err, user) {
if (err)
throw err;
});
Server_Side delete function:
module.exports.removeadmin = function(id, callback){
var query = { _id: id };
Admin.remove(query, callback);
};
I have deleted a user by simple fetch command in the component without redux and I have sent id in the body of delete request and it was working but with redux just successful message.
Thank you for any help
Your code in the post should work except for the fetch request the url should be prepended with the backend url so if the backend url is localhost:3000 your fetch should be:
return fetch(`http://localhost:3000/removeadmin/${id}`,
requestOptions).then(handleResponse);
and in your serverside router you can access your id param like so:
app.delete('/removeadmin/:id', function(req, res)
{
var send_id = req.params.id;
admin.removeadmin(sent_id, function(err, user) {
if (err)
throw err;
});
I have found that I made a mistake in URL. So on the server in URL I can't have access to my id and it showed me undefined.
Just I have changed these lines :
user_action:
return fetch(`/removeadmin?id=${id}` , requestOptions).then(handleResponse);
and server_side router:
app.delete('/removeadmin?:id', function(req, res){
I've never had to do this before. I've created myModule.GetRecord() and I can see the recordset successfully has the expected record.
However, ret in router.get() is undefined.
I believe because I need to catch the returned value in a callback.
I don't know how to define this module/function for a callback (if that is what I am appropriately looking to do) or how to call this function for a callback.
I've tried a few different things i.e. the typical GetRecord(ret, function () { ... }); But didn't see anything that appeared to work. And I read a bunch on the line but didn't find what I believe I'm looking for.
I really don't care to much about how I get there, but all I'm really trying to do is have mm.GetRecord()'s returned value in some usable form in the router.get()
--- myModulefile.js ---
'use strict';
module.exports = {
GetRecord: function (id) {
var sql = require('mssql');
sql.connect({ user: 'sa', ... database: 'name' }, function (err) {
if (err) { console.log(err); return null; }
var cmd = new sql.Request();
cmd.query('select * from Records where id = ' + id, function (err, rs) {
if (err) { console.log(err); return null; }
if (rs.recordset.length > 0) {
console.log('rs[0]', rs.recordset[0]);
return rs.recordset[0];
} else {
return null;
}
});
});
}
};
--- myRouter.js ----
const express = require('express');
const router = express.Router();
const mm = require('../myModule');
router.get('/:id', function (req, res) {
var id = req.params.id;
var ret = mm.GetRecord(id)
console.log('ret', ret);
if (ret == null)
ret = JSON.stringify({ ID: -1, f1: 'unknown' });
res.send(ret);
});
module.exports = router;
Of course I find the answer after having placed the question on here.
GetRecord() has to be defined with a parameter that recieves the callback passed to it. And the callback paramater's variable fn is used in place of return
GetRecord: function (id, fn) {
var sql = require('mssql');
sql.connect({ user: 'sa', ... database: 'name' }, function (err) {
if (err) { console.log(err); fn(null); }
var cmd = new sql.Request();
cmd.query('select * from Records where id = ' + id, function (err, rs) {
if (err) { console.log(err); fn(null); }
if (rs.recordset.length > 0) {
console.log('rs[0]', rs.recordset[0]);
fn(rs.recordset[0]);
} else {
fn(null);
}
});
});
}
and
GetRecord(id, function(ret) {
console.log('ret', ret);
});