Error uploading file: TypeError: source is not async iterable - ipfs

Is there an issue with IPFS. nothing works
I get this ERROR when running ipfs daemon
2022-11-05T01:21:38.715+0100 ERROR tcp-tpt tcp/tcp.go:59 failed set keepalive period {"error": "set tcp4 192.168.1.6:4001->34.211.25.159:41218: setsockopt: invalid argument"}
import * as IPFS from 'ipfs-core'
const setURI = async (file, callback) => {
try {
const ipfs = await IPFS.create()
const { cid } = await ipfs.add(file)
console.info(cid)
// callback(url)
} catch (error) {
console.error('Error uploading file: ', error)
}
}
export {
setURI
}

This is a bug in the latest version of Babel: https://github.com/babel/babel/issues/15145
A workaround is to downgrade by adding this to package.json:
"resolutions": {
"#babel/plugin-transform-async-to-generator": "7.17.12"
},

Related

req.file.stream is undefined

I'm having troubles with node 16 and ES6. I'm trying to make a upload file controller but i'm stuck with req.file.stream which is undefined
I'm using multer to handle upload files.
The first issue was __dirname undefined that I was able to fix with path and New Url.
The error I got with pipeline
node:internal/process/promises:246
triggerUncaughtException(err, true /* fromPromise */);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "source" argument must be of type function or an instance of Stream, Iterable, or AsyncIterable. Received undefined
my userRoutes.js
import express from "express";
import { signin, signup, logout } from "../Controller/AuthController.js";
import {
getUsers,
getUser,
updateUser,
deleteUser,
follow,
unfollow,
} from "../Controller/UserController.js";
import { upload } from "../Controller/UploadController.js";
import multer from "multer";
const router = express.Router();
// Auth
router.post("/signin", signin);
router.post("/signup", signup);
router.post("/logout", logout);
// users
router.get("/", getUsers);
router.get("/:id", getUser);
router.patch("/:id", updateUser);
router.delete("/:id", deleteUser);
router.patch("/follow/:id", follow);
router.patch("/unfollow/:id", unfollow);
// upload
router.post("/upload", multer().single("file"), upload);
export default router;
And my UploadController.js
import fs from "fs";
import { promisify } from "util";
import stream from "stream";
const pipeline = promisify(stream.pipeline);
// const { uploadErrors } = require("../utils/errors.utils");
import path from "path";
const __dirname = path.dirname(new URL(import.meta.url).pathname);
export const upload = async (req, res) => {
try {
// console.log(req.file);
console.log(__dirname);
if (
!req.file.mimetype == "image/jpg" ||
!req.file.mimetype == "image/png" ||
!req.file.mimetype == "image/jpeg"
)
throw Error("invalid file");
if (req.file.size > 2818128) throw Error("max size");
} catch (err) {
const errors = uploadErrors(err);
return res.status(201).json({ err });
}
const fileName = req.body.name + ".jpg";
await pipeline(
req.file.stream,
fs.createWriteStream(
`${__dirname}/../client/public/uploads/profil/${fileName}`
)
);
try {
await User.findByIdAndUpdate(
req.body.userId,
{ $set: { picture: "./uploads/profil/" + fileName } },
{ new: true, upsert: true, setDefaultsOnInsert: true },
(err, docs) => {
if (!err) return res.send(docs);
else return res.status(500).send({ message: err });
}
);
} catch (err) {
return res.status(500).send({ message: err });
}
};
Multer gives you the file as a Buffer, not a Stream. req.file.stream is not valid property, but req.file.buffer is: https://github.com/expressjs/multer#file-information.
From the look of your code, you're trying to save the file on disk. You can use multer's DiskStorage for that. Create a storage instance and pass it to the multer instance as a configuration:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, `${__dirname}/../client/public/uploads/profil/`);
},
filename: function (req, file, cb) {
cb(null, req.body.name + '.jpg');
},
});
const upload = multer({ storage });
router.post('/upload', upload.single('file'), upload);
Have a look at this free Request Parsing in Node.js Guide for working with file uploads in Node.js.
if you want to use req.file.stream, you will need to install this version of multer:
npm install --save multer#^2.0.0-rc.1
and your code will work perfectly, just change your req.file.mimetype to req.file.detectedMimeType !!

Getting "Client does not support authentication protocol requested by server; consider upgrading MySQL client" in Cypress

I was trying to connect to Mysql DB from cypress, did the following steps for the same.
Step 1: Added MySQL library in cypress
Step 2: Added following code in plugins/index.js file (This I have got while searching in google)
const mysql = require('mysql')
function queryTestDb(query, config) {
// creates a new mysql connection using credentials from cypress.json
env's
const connection = mysql.createConnection(config.env.db)
// start connection to db
connection.connect()
// exec query + disconnect to db as a Promise
return new Promise((resolve, reject) => {
connection.query(query, (error, results) => {
if (error) reject(error)
else {
connection.end()
// console.log(results)
return resolve(results)
}
})
})
}
module.exports = (on, config) => {
// Usage: cy.task('queryDb', query)
on('task', {
queryDb :query => {
return queryTestDb(query, config)
},
})
}
Step 3: Added the following dependencies in cypress.json
"env" : {
"db": {
"host": "name",
"user": "user",
"password": "password"
}
}
Step 4: Added the following code in the spec.js file
it('Verify the retrieved data', () => {
cy.task('queryDb','select * from soandso where soandso = value').then((resp) => {
console.log(resp.rows)
})
})
But while running the spec file getting the below error
cy.task('queryDb') failed with the following error: > ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
Please help me to fix this error.
can you check your dependency in the package.json?
It should have sth like below.
"dependencies": {
"mysql": "^2.18.1"
}
If you do not have this dependency, you need to run 'npm install mysql'

Ionic gives error undefined is not an object (evaluating '_co.user.username') when decoding the login user token

This is part of the error message that I am getting:
[Error] ERROR – TypeError: undefined is not an object (evaluating '_co.user.username') TypeError: undefined is not an object (evaluating '_co.user.username')(anonymous function)checkAndUpdateView — core.js:44...
My login process works fine and data of the user is gotten fine, on ionic serve version of my app, but on ios I can see that error message, like json encoding doesn't work fine or something. Why is the JSON working fine on website, but not on the app? Here is content of TokenService :
constructor(private cookieService: CookieService) {}
setToken(token) {
this.cookieService.set("chat_token", token);
}
getToken() {
return this.cookieService.get("chat_token");
}
deleteToken() {
this.cookieService.delete("chat_token");
}
getPayload() {
const token = this.getToken();
let payload;
if (token) {
payload = token.split(".")[1];
payload = JSON.parse(window.atob(payload));
}
return payload.data;
}
and this is the loginUser function in LoginComponent , that is triggered on logging in:
loginUser() {
this.showSpinner = true;
this.authService.loginUser(this.loginForm.value).subscribe(
data => {
this.tokenService.setToken(data.token);
localStorage.setItem("currentUser", JSON.stringify(data));
this.loginForm.reset();
setTimeout(() => {
this.router.navigate(["/streams"]);
}, 200);
},
err => {
this.showSpinner = false;
if (err.error.message) {
this.errorMessage = err.error.message;
}
}
);
}
Now, the server side, I have this rout in routes/ directory, in node express in file authRoutes.js:
router.post('/login', AuthCtrl.LoginUser);
And then I have this in routes/ directory, in file userRoutes.js:
const express = require('express');
const router = express.Router();
const UserCtrl = require('../controllers/users');
const AuthHelper = require('../Helpers/AuthHelper');
router.get('/users', AuthHelper.VerifyToken, UserCtrl.GetAllUsers);
router.get('/user/:id', AuthHelper.VerifyToken, UserCtrl.GetUser);
router.get(
'/username/:username',
AuthHelper.VerifyToken,
UserCtrl.GetUserByName
);
router.post('/user/view-profile', AuthHelper.VerifyToken, UserCtrl.ProfileView);
router.post(
'/change-password',
AuthHelper.VerifyToken,
UserCtrl.ChangePassword
);
module.exports = router;
This is the part of controller auth.js on node server side:
async LoginUser(req, res) {
if (!req.body.username || !req.body.password) {
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: "No empty fields allowed" });
}
await User.findOne({ username: Helpers.firstUpper(req.body.username) })
.then(user => {
if (!user) {
return res.status(HttpStatus.NOT_FOUND).json({ message: "Username not found" });
}
return bcrypt.compare(req.body.password, user.password).then(result => {
if (!result) {
return res
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.json({ message: "Password is incorrect" });
}
const token = jwt.sign({ data: user }, dbConfig.secret, {
expiresIn: "5h"
});
res.cookie("auth", token);
return res.status(HttpStatus.OK).json({ message: "Login successful", user, token });
});
})
.catch(err => {
console.log("Error is:");
console.log(err);
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: "Error occured" });
});
}
I resolved the issue by transferring all the stored data from CookieService, which is the main culprit of the error, to a localStorage. Just instead of storing payload and that cookie in CookieService, just transferred it to localStorage, and I didn't have any more problems. Seems like, the simpler - the better.

Error handler ignored when NODE_ENV=production

I am building a simple REST API with Node/Express, and I'm having a hard time when I deploy it to production. When NODE_ENV=development, everything works as expected. I get back the JSON error and the correct status code. When NODE_ENV=production, I only get back an HTML page with the default error message and nothing else. I can read the status code, but I need to have access to the full JSON payload to identify the errors better. This is my code:
import Promise from 'bluebird'; // eslint-disable-line no-unused-vars
import express from 'express';
import config from './config';
import routes from './routes';
import { errorMiddleware, notFoundMiddleware } from './middlewares/error.middleware';
import mongoose from './config/mongoose.config';
// create app
const app = express();
(async () => {
// connect to mongoose
await mongoose.connect();
// pretty print on dev
if (process.env.NODE_ENV !== 'production') {
app.set('json spaces', 2);
}
// apply express middlewares
app.use(express.json());
// register v1 routes
app.use('/v1', routes);
// catch errors
app.use(notFoundMiddleware);
app.use(errorMiddleware);
// start server
app.listen(config.port, () => console.info(`server started on port ${config.port}`));
})();
export default app;
This is the notFoundMiddleware:
export default (req, res, next) => next(new Error('Not Found'));
This is the errorMiddleware:
const errorMiddleware = (err, req, res, next) => {
console.log('test'); // this works in development, but not in production
const error = {
status: err.status,
message: err.message
};
if (err.errors) {
error.errors = err.errors;
}
if (process.env.NODE_ENV !== 'production' && err.stack) {
error.stack = err.stack;
}
return res.status(error.status || 500).send({ error });
};
If you are runing on production server, try to use some logging provider like "papertrailapp" to see the error occurs in your app.
I've just stumbled upon the same problem. It turned out it's caused by a transpiler optimization applied when building production bundle - this one: https://babeljs.io/docs/en/babel-plugin-minify-dead-code-elimination
Express' error handlers should have the signature (err, req, res, next) => { ... } (be of arity 4). In your example next is not used anywhere in errorMiddleware function body and thus it gets eliminated (optimized-out) from function signature in production code.
Solution:
use keepFnArgs: true plugin option - possibly through https://webpack.js.org/plugins/babel-minify-webpack-plugin/ webpack configuration:
var MinifyPlugin = require("babel-minify-webpack-plugin")
module.exports = {
// ...
optimization: {
minimizer: [
new MinifyPlugin({
deadcode: {
keepFnArgs: true,
},
}, {}),
],
}
// ...
}
or alternatively pretend in your code that this argument is used:
const errMiddleware = (err, req, res, _next) => {
// ... your code ...
// ...
// cheat here:
_next
}

Google cloud functions - cannot read property 'getApplicationDefault'

I have deployed a cloud function to invoke a dataflow pipeline template and trying to trigger the function by placing the file in cloud storage bucket.
As node.js prerequisite I have done,
npm init
npm install --save googleapis
Index.js
const google = require('googleapis');
exports.goWithTheDataFlow = function(event, callback) {
const file = event.data;
google.auth.getApplicationDefault(function (err, authClient, projectId) {
if (err) {
throw err;
}
console.log(projectId);
if (authClient.createScopedRequired && authClient.createScopedRequired()) {
authClient = authClient.createScoped([
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/userinfo.email'
]);
}
const dataflow = google.dataflow({ version: 'v1b3', auth: authClient });
console.log(`gs://${file.bucket}/${file.name}`);
dataflow.projects.templates.create({
projectId: projectId,
resource: {
parameters: {
inputFile: `gs://${file.bucket}/${file.name}`
},
jobName: 'cloud-fn-dataflow-test',
gcsPath: 'gs://jaison/templates/ApacheBeamTemplate'
}
}, function(err, response) {
if (err) {
console.error("problem running dataflow template, error was: ", err);
}
console.log("Dataflow template response: ", response);
callback();
});
});
callback();
};
Command used to deploy cloud function:
gcloud beta functions deploy goWithTheDataFlow --stage-bucket cf100stage --trigger-bucket cf100
Dataflow(Apache beam):
I was able to execute the dataflow template from console and below is the path of the template,
'gs://jaison/templates/ApacheBeamTemplate'
Function crashes with below error:
TypeError: Cannot read property 'getApplicationDefault' of undefined
at exports.goWithTheDataFlow (/user_code/index.js:11:17) at
/var/tmp/worker/worker.js:695:16 at /var/tmp/worker/worker.js:660:9 at
_combinedTickCallback (internal/process/next_tick.js:73:7) at process._tickDomainCallback (internal/process/next_tick.js:128:9)
Looks like I am missing libraries. Not sure how to fix this. Please help.
My cloud function works with below changes,
1.Setting up GOOGLE_APPLICATION_CREDENTIALS to service account json file
export GOOGLE_APPLICATION_CREDENTIALS="/path/of/svc/json/file.json"
2.index.js
var {google} = require('googleapis');
exports.TriggerBeam = (event, callback) => {
const file = event.data;
const context = event.context;
console.log(`Event ${context.eventId}`);
console.log(` Event Type: ${context.eventType}`);
console.log(` Bucket: ${file.bucket}`);
console.log(` File: ${file.name}`);
console.log(` Metageneration: ${file.metageneration}`);
console.log(` Created: ${file.timeCreated}`);
console.log(` Updated: ${file.updated}`);
google.auth.getApplicationDefault(function (err, authClient, projectId) {
if (err) {
throw err;
}
console.log(projectId);
const dataflow = google.dataflow({ version: 'v1b3', auth: authClient });
console.log(`gs://${file.bucket}/${file.name}`);
dataflow.projects.templates.create({
projectId: projectId,
resource: {
parameters: {
inputFile: `gs://${file.bucket}/${file.name}`
},
jobName: 'cloud-fn-beam-test',
gcsPath: 'gs://jaison/templates/ApacheBeamTemplate'
}
}, function(err, response) {
if (err) {
console.error("problem running dataflow template, error was: ", err);
}
console.log("Dataflow template response: ", response);
callback();
});
});
callback();
};