I have a form with a uploader input to get an image "angular-file-uploader" npm library. but in the function that receive the data, it receive the data undefined, I can't do a JSON.parse() with the data.
I don't know if the problem is in the backend (nodejs) but with postman the backend works.
<angular-file-uploader #fileUpload1
[config]="afuConfig"
[resetUpload]=resetVar
(ApiResponse)="avatarUpload($event)">
</angular-file-uploader>
this.afuConfig = {
multiple: false,
formatsAllowed: '.jpg, .jpeg, .png, .gif',
maxSize: '50',
uploadAPI:{
url: this.url+'upload-avatar',
headers:{
// 'Content-Type' : 'text/plain;charset=UTF-8',
'Authorization': this.token
}
},
theme: 'attachPin',
hideProgressBar: false,
hideResetBtn: true,
hideSelectBtn: false,
attachPinText:'Sube la imagen'
};
}
avatarUpload(book)
{
console.log(book); //here the error is TypeError: Cannot read property 'length' of undefined
let data = JSON.parse(book.response);// here core.js:6228 ERROR SyntaxError: Unexpected token T in JSON at position 0
this.book.image = data.book.image;
console.log(data);
}
backend nodejs function uploadAvatar()
uploadAvatar: function(req, res){
// Configurar el modulo multiparty (md) routes/user.js
// Recoger el fichero de la petición
var file_name = 'imagen no subida...';
if(!req.files){
return res.status(404).send({
status: 'error',
message: file_name
});
}
// Conseguir el nombre y la extension del archivo
var file_path = req.params.file0.path;
// var file_split = file_path.split('\\');
// ** Adventencia ** En linux o mac
var file_split = file_path.split('/');
// Nombre del archivo
var file_name = file_split[2];
// Extensión del archivo
var ext_split = file_name.split('\.');
var file_ext = ext_split[1];
// Comprobar extension (solo imagenes), si no es valida borrar fichero subido
if(file_ext != 'png' && file_ext != 'jpg' && file_ext != 'jpeg' && file_ext != 'gif'){
fs.unlink(file_path, (err) => {
return res.status(200).send({
status: 'error',
message: 'La extensión del archivo no es valida.'
});
});
}else{
// Sacar el id del libro
var params = req.body;
var bookId = req.params.bookId;
// Buscar y actualizar documento bd
Book.findOneAndUpdate({_id: bookId}, {image: file_name}, {new:true}, (err, bookUpdated) => {
if(err || !bookUpdated){
// Devolver respuesta
return res.status(500).send({
status: 'error',
message: 'Error al guardar la imagen'
});
}
// Devolver respuesta
return res.status(200).send({
status: 'success',
image: book.image,
user: bookUpdated
});
});
}
},
Edited
console.log(book);
TypeError: Cannot read property 'length' of undefined
at http.js:168
at Array.forEach (<anonymous>)
at HttpHeaders.lazyInit (http.js:156)
at HttpHeaders.init (http.js:277)
at HttpHeaders.forEach (http.js:379)
at Observable._subscribe (http.js:2398)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at subscribeToResult (subscribeToResult.js:9)
avatarUpload(book)
{
console.log(book); //here the error is TypeError: Cannot read property 'length' of undefined
let data = JSON.parse(book.response);// here core.js:6228 ERROR SyntaxError: Unexpected token T in JSON at position 0
this.book.image = data.book.image;
console.log(book);
}
at MergeMapSubscriber._innerSub (mergeMap.js:59)
book.response is not a json object. That is why you getting the following error while trying to parse it.
let data = JSON.parse(book.response);
// here core.js:6228 ERROR SyntaxError: Unexpected token T in JSON at position.
Can you please update question with book data?
Related
I have a frontend Angular.ts and a backend Express.js. I am decrypting user credentials in the frontend using RSA and sending all the data as an encrypted string to the backend.
When I try to catch the data in the backend to decrypt it, it reads the received object as [object Object] which makes it impossible to decrypt. This is the code =>:
FRONTEND httpService.ts:
sendmail(user: { name: any; email: any; host: any }) {
console.log(user);
const encJsonUser = this.rsaHelper.encryptWithPublicKey(
JSON.stringify(user)
);
console.log(encJsonUser);
return this.http.post(environment.apiUrl + '/sendemail', encJsonUser);
}
BACKENDemail.js:
router.post('/', async (req, res) => {
let path = null;
const encryptedData = req.body;
console.log("RECEIVED ENCRYPTED BODY: " + encryptedData);
const privateKey = fs.readFileSync("privateKey.key.pem", "utf8");
console.log("toDecryptData::: " + encryptedData);
const decryptedData = decryptedDataFromAngular(encryptedData, privateKey);
console.log("DECRYPTED-DATA: " + decryptedData);
axios.post("http://localhost:8080/pdf", {host: encryptedData.host}).then(async function (response) {
path = response.data.scan_id;
}).then(() => {
emailPdfGenerator(encryptedData);
});
})
function decryptedDataFromAngular(encryptedData, privateKey) {
// encryptedData = Buffer.from(encryptedData, "base64");
const body = JSON.parse(encryptedData);
// console.log("ENCRYPTED DATA 2222:::: " + encryptedData);
console.log("ENCRYPTED DATA 2222:::: " + body);
const decryptedData = crypto.privateDecrypt(
{
key: privateKey,
// In order to decrypt the data, we need to specify the
// same hashing function and padding scheme that we used to
// encrypt the data in the previous step
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
},
body
);
console.log("decrypted data: ", decryptedData.toString());
console.log("DE RAW DATA" + decryptedData);
return decryptedData;
}
error message:
RECEIVED ENCRYPTED BODY: [object Object] toDecryptData::: [object Object] undefined:1 [object Object] ^
SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse ()
at decryptedDataFromAngular (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\routes\email.js:60:23)
at C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\routes\email.js:31:27
at Layer.handle [as handle_request] (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\route.js:144:13)
at Route.dispatch (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\route.js:114:3)
at Layer.handle [as handle_request] (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\index.js:284:15
at Function.process_params (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\index.js:346:12)
at next (C:\Users\hayan\Desktop\HSLeiden\Year2-IN2B\IPSEN5\Security-Check-Express-User\node_modules\express\lib\router\index.js:280:10)
[nodemon] app crashed - waiting for file changes before starting...
I stopped using crypto, and I am using forge to solve the problem because crypto just didn't help me.
This is my code:
async function decryptUser(encryptedUserData) {
const name = await decryptString(encryptedUserData.name);
const email = await decryptString(encryptedUserData.email);
const host = await decryptString(encryptedUserData.host);
const decryptedUser = {
name: name,
email: email,
host: host,
}
return decryptedUser
}
async function decryptString(encryptedString) {
const rsa = forge.pki.privateKeyFromPem(PRIVATE_KEY);
return await rsa.decrypt(encryptedString);
}
I'm trying to remove message notification. but this error appear "SyntaxError: Unexpected token S in JSON at position 0 at JSON.parse" , is there any relation with the type defined in the headers? How can i resolve this error?
Front-End Angular 12
public removeNotificationForUser(onlineUserModel: OnlineUserModel) {
let targetUsername = onlineUserModel.userName;
const url_ = `${this.baseUrlRemoveNotifications}?targetUsername=${targetUsername}`;
const url = this.baseUrlRemoveNotifications + "/" + targetUsername;
const body = {};
const options = {
headers: new HttpHeaders({
"Content-Type": "application/json",
"X-XSRF-TOKEN": this.cookieService.get("XSRF-TOKEN"),
}),
};
return this.http.patch<any>(url_, body, options).subscribe(
(val) => {
console.log("PATCH call successful value returned in body", val);
},
(response) => {
console.log("PATCH call in error", response);
},
() => {
console.log("The PATCH observable is now completed.");
}
);
}
Back-End Asp.net Core
[HttpPatch("[action]/{targetUsername}")]
[Route("removeNotifications")]
public async Task<IActionResult> RemoveNotifications( [FromQuery] string targetUsername)
{
try
{
var sender = await _userManager.FindByNameAsync(targetUsername);
var reciever = await _userManager.FindByNameAsync(User.Identity.Name);
// Find The Connection
var RecieverResetNotification= _userInfoInMemory.GetUserInfo(User.Identity.Name);
var SenderResetNotification = _userInfoInMemory.GetUserInfo(targetUsername);
var notificationToBeRemoved = _context.Notifications.Where(N => ((N.ReceiverId == reciever.Id) && (N.SenderId == sender.Id) && (N.IsSeen == false))).ToList();
//Send My reset notification to the the others sessions :
var mySessions = _context.Connections.Where(C => ((C.ConnectionID != RecieverResetNotification.ConnectionID) && (C.Username == reciever.UserName) && (C.Connected == true))).Select(MyCID => MyCID.ConnectionID).ToList();
if (mySessions != null)
{
await _hubContext.Clients.Clients(mySessions).SendAsync("MyResetNotification", RecieverResetNotification);
}
//Test if notificationToBeRemoved
if (notificationToBeRemoved != null)
{
notificationToBeRemoved.ForEach(NR => NR.IsSeen = true);
_context.SaveChanges();
}
// My Methode to update Notification Table => change Iseen column to true //
return Ok("Success");
}
catch (Exception ex)
{
Log.Error("An error occurred while seeding the database {Error} {StackTrace} {InnerException} {Source}",
ex.Message, ex.StackTrace, ex.InnerException, ex.Source);
}
return BadRequest("Failed");
}
I have an axios interceptor for cases, where I need the user to be authorized, but he isn't. For example, because the token is expired.
Now, after a token refresh, the original request should be retried.
However, currently the original requests, seems to be changed, so that the Server gives me a JSON.parse error.
SyntaxError: Unexpected token " in JSON at position 0
at JSON.parse (<anonymous>)
at createStrictSyntaxError (/var/app/current/node_modules/body-parser/lib/types/json.js:158:10)
at parse (/var/app/current/node_modules/body-parser/lib/types/json.js:83:15)
at /var/app/current/node_modules/body-parser/lib/read.js:121:18
at invokeCallback (/var/app/current/node_modules/raw-body/index.js:224:16)
at done (/var/app/current/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/var/app/current/node_modules/raw-body/index.js:273:7)
at IncomingMessage.emit (events.js:314:20)
at IncomingMessage.EventEmitter.emit (domain.js:483:12)
at endReadableNT (_stream_readable.js:1241:12)
This is because, instead of the original request, that is JSON, it seems to process it again, puts it in quotes etc., so it becomes a string and the bodyparser, throws the error above.
So the request content, becomes:
"{\"traderaccount\":\"{\\\"traderaccountID\\\":\\\"undefined\\\",\\\"traderID\\\":\\\"2\\\",\\\"name\\\":\\\"Conscientious\\\",\\\"order\\\":99,\\\"myFxLink\\\":\\\"\\\",\\\"myFxWidget\\\":\\\"\\\",\\\"copyFxLink\\\":\\\"83809\\\",\\\"tokenLink\\\":\\\"\\\",\\\"tradertext\\\":{\\\"tradertextID\\\":\\\"\\\",\\\"traderaccountID\\\":\\\"\\\",\\\"language\\\":\\\"\\\",\\\"commission\\\":\\\"\\\",\\\"affiliateSystem\\\":\\\"\\\",\\\"leverage\\\":\\\"\\\",\\\"mode\\\":\\\"\\\",\\\"description\\\":\\\"\\\"},\\\"accountType\\\":\\\"\\\",\\\"accountTypeID\\\":1,\\\"minInvest\\\":2000,\\\"currency\\\":\\\"\\\",\\\"currencySymbol\\\":\\\"\\\",\\\"currencyID\\\":1,\\\"affiliateSystem\\\":1}\"}"
instead of
{"traderaccount":"{\"traderaccountID\":\"undefined\",\"traderID\":\"2\",\"name\":\"Conscientious\",\"order\":99,\"myFxLink\":\"\",\"myFxWidget\":\"\",\"copyFxLink\":\"83809\",\"tokenLink\":\"\",\"tradertext\":{\"tradertextID\":\"\",\"traderaccountID\":\"\",\"language\":\"\",\"commission\":\"\",\"affiliateSystem\":\"\",\"leverage\":\"\",\"mode\":\"\",\"description\":\"\"},\"accountType\":\"\",\"accountTypeID\":1,\"minInvest\":2000,\"currency\":\"\",\"currencySymbol\":\"\",\"currencyID\":1,\"affiliateSystem\":1}"}
from the original axios request content.
Both are the unformated request contents, that I can see in the developer network console.
The content type, is application/json in both cases.
Below is the Interceptor code:
Axios.interceptors.response.use(
(response) => {
return response;
},
(err) => {
const error = err.response;
if (
error !== undefined &&
error.status === 401 &&
error.config &&
!error.config.__isRetryRequest
) {
if (this.$store.state.refreshToken === "") {
return Promise.reject(error);
}
return this.getAuthToken().then(() => {
const request = error.config;
request.headers.Authorization =
Axios.defaults.headers.common[globals.AXIOSAuthorization];
request.__isRetryRequest = true;
return Axios.request(request);
});
}
return Promise.reject(error);
}
);
private getAuthToken() {
if (!this.currentRequest) {
this.currentRequest = this.$store.dispatch("refreshToken");
this.currentRequest.then(
this.resetAuthTokenRequest,
this.resetAuthTokenRequest
);
}
return this.currentRequest;
}
private resetAuthTokenRequest() {
this.currentRequest = null;
}
// store refreshToken
async refreshToken({ commit }) {
const userID = this.state.userID;
const refreshToken = Vue.prototype.$cookies.get("refreshToken");
this.commit("refreshLicense");
commit("authRequest");
try {
const resp = await axios.post(serverURL + "/refreshToken", {
userID,
refreshToken,
});
if (resp.status === 200) {
return;
} else if (resp.status === 201) {
const token = resp.data.newToken;
const newRefreshToken = resp.data.newRefreshToken;
Vue.$cookies.set(
"token",
token,
"14d",
undefined,
undefined,
process.env.NODE_ENV === "production",
"Strict"
);
Vue.$cookies.set(
"refreshToken",
newRefreshToken,
"30d",
undefined,
undefined,
process.env.NODE_ENV === "production",
"Strict"
);
axios.defaults.headers.common[globals.AXIOSAuthorization] = token;
commit("authSuccessRefresh", { newRefreshToken });
} else {
this.dispatch("logout");
router.push({
name: "login",
});
}
} catch (e) {
commit("authError");
this.dispatch("logout");
}
So, can you help me to prevent Axios on the retried request to change the request content. So it doesn't put it into quotes and quote the already exisitng quotes?
Thanks to the comment I found a solution.
Try to parse the content before resending it:
axios.interceptors.response.use(
(response) => response,
(error) => {
const status = error.response ? error.response.status : null;
if (status === 401 && error.config && !error.config.__isRetryRequest) {
return refreshToken(useStore()).then(() => {
const request = error.config;
request.headers.Authorization =
axios.defaults.headers.common["Authorization"];
request.__isRetryRequest = true;
try {
const o = JSON.parse(request.data);
if (o && typeof o === "object") {
request.data = o;
}
} catch (e) {
return axios.request(request);
}
return axios.request(request);
});
}
return Promise.reject(error);
});
Hello everybody !!
Here I have a big problem, I would like to do a registration in back with Node.js sequelize and mySql.
I looked here and there but I did not find the answer to my problem so I came to ask you for help.
With mongoDb, it was easier but I admit that I am going in circles.
Here is my code:
// Importation :
// Bcrypt:
const bcrypt = require("bcrypt");
// Jsonwebtoken d'authentification:
const jwt = require("jsonwebtoken");
// Import du models user:
const models = require("../models/user")
//////////////////////////////////////////////////////////////////////////////////////////////
// Fonction/
// Incription:
exports.signup = (req, res) => {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
const bio = req.body.bio;
const admin = req.body.admin;
console.log(req.body)
try {
models.User.findOne({
attributes: ['email'],
where: {
email: email
}
})
.then((userFound => {
if (!userFound) {
bcrypt.hash(password, 10, function (err, bcryptPassword) {
const newUser = models.User.create({
username : username,
email : email,
password : bcryptPassword,
bio : bio,
admin : false
})
.then(newUser => {
res.status(201).json({
'userId': newUser.id
})
})
.catch(err => {
res.status(500).json({
'error': 'Impossible d\'ajouter un utilisateur'
})
})
})
} else {
return res.status(409).json({
error: 'Ce compte existe déjà '
})
}
})
.catch((err) =>
res.status(500).json({
'err': err + 'Impossible de vérifier l\'utilisateur',
})
)
)
}catch (error) {
res.status(400).json({
error: error.message
});
}
}
And the model User:
'use strict'
const { db } = require('../config/connexion')
const { Sequelize, DataTypes } = require('sequelize')
const user = db.define('User', {
// Model attributes are defined here
username: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING,
bio: DataTypes.TEXT,
admin: DataTypes.BOOLEAN,
})
module.exports = user
and connexion.js:
// Connexion de sequelize à mysql:
const {
Sequelize
} = require('sequelize')
const db = new Sequelize(
process.env.NAMEDB,
process.env.USERDB,
process.env.PASSWORDDB, {
host: process.env.HOSTDB,
dialect: process.env.DIALECTDB,
pool: {
min: 0, // nombre minimum de connexion dans le pool
max: 5, // nombre maximum de connexion dans le pool
acquire: 30000, // durée maximale, en millisecondes, pendant laquelle ce pool essaiera d'obtenir la connexion avant de lancer une erreur
idle: 10000, // temps maximum, en millisecondes, pendant lequel une connexion peut être inactive avant d'être libérée
},
}
)
//////////////////////////////////////////////////////////////////////////////////////////////
// Etablit la connexion à mysql:
const dbConnect = async (db) => {
await db
.authenticate()
.then(() => {
db.sync()
console.log('Connecté à la base de données MySQL!')
})
.catch((err) => {
console.error('error: ' + err.message)
setTimeout(() => {
dbConnection(db)
}, 5000)
})
}
//////////////////////////////////////////////////////////////////////////////////////////////
// Exportation:
module.exports = {
db,
dbConnect,
}
Certainly there is still a lot to do, but being a beginner I improve as I go.
Do not be angry with me if my English is not at the top, I admit that it is not my strong point.
Thanking you in advance for all the help provided.
You are directly setting the export object equal to the user object.
When you do this const models = require("../models/user"), models is equal to the user value directly.
You can directly use models.findOne. Read this
You are setting the user variable to be the export of the file
module.exports = user
You then import the user variable as models.
const models = require("../models/user")
this means that you do not need to access user as a property. Instead use:
models.findOne({ // Changed from models.User to models
attributes: ["email"],
where: {
email: email,
},
});
This should stop your current error, but you will keep on getting errors until you change all instances of models.User to models.
Your main file should end up looking like this:
// Importation :
// Bcrypt:
const bcrypt = require("bcrypt");
// Jsonwebtoken d'authentification:
const jwt = require("jsonwebtoken");
// Import du models user:
const models = require("../models/user");
//////////////////////////////////////////////////////////////////////////////////////////////
// Fonction/
// Incription:
exports.signup = (req, res) => {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
const bio = req.body.bio;
const admin = req.body.admin;
console.log(req.body);
try {
models
.findOne({
attributes: ["email"],
where: {
email: email,
},
})
.then(
((userFound) => {
if (!userFound) {
bcrypt.hash(password, 10, function (err, bcryptPassword) {
const newUser = models
.create({
username: username,
email: email,
password: bcryptPassword,
bio: bio,
admin: false,
})
.then((newUser) => {
res.status(201).json({
userId: newUser.id,
});
})
.catch((err) => {
res.status(500).json({
error: "Impossible d'ajouter un utilisateur",
});
});
});
} else {
return res.status(409).json({
error: "Ce compte existe déjà ",
});
}
}).catch((err) =>
res.status(500).json({
err: err + "Impossible de vérifier l'utilisateur",
})
)
);
} catch (error) {
res.status(400).json({
error: error.message,
});
}
};
Check your "model" file to see if the "User" model exists there. Also check if you are using the 'module.exports'
You are exporting the User model directly, but calling it like it is in an object property named User. You can either access it directly, changing:
models.User.findOne
to:
models.findOne
and then you'd probably want to rename models to User.
Or change your export to:
module.exports = { User: user };
I would like to explain my problem of the day.
error 500 , id = undefined, no idea why ,
I try to post whatever you may need
how can I fix this issue?
thats is function
handleSubmit = (e, id) => {
e.preventDefault();
const userIdData = { id };
const config = {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({userIdData, livree: new Date().toISOString().slice(11, 16)}),
};
const url = entrypoint + "/alluserpls";
fetch(url, config)
.then(res => res.json())
.then(res => {
if (res.error) {
alert(res.error);
else {
alert(`ajouté avec l'ID ${res}!`);
}
}).catch(e => {
console.error(e);
}).finally(() => this.setState({ redirect: true })); }
my routes
app.put('/api/alluserpls', (req, res, ) => {
const formData = req.body;
const userId = req.body.id;
const deleteQuery = `UPDATE alluserpls SET ? WHERE id = ${userId}`;
connection.query(deleteQuery, err => {
if (err) {
console.log(err)
res.status(500).send("Erreur lors de la modification des users");
} else {
res.sendStatus(200);
}
});
});
my button
<form onSubmit={(e) => this.handleSubmit(e, datass.id)}>
<button type="submit">PUT</button>
</form>
console.log result
errno: 1064,
sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to
your MariaDB server version for the right syntax to use near '? WHERE id = undefined' at
line 1",
sqlState: '42000',
index: 0,
sql: 'UPDATE alluserpls SET ? WHERE id = undefined'
}
PUT /api/alluserpls 500 14.354 ms - 40
Replace the userId line with this:
const userId = req.body.userIdData.id;
with ES6 Object Destructring:
const { id } = req.body.userIdData
Also, it'll be cleaner if you remove the formData declaration since it's not used in the route handler.