Router is not defined in KOA2 - node.js

I have two files, one of them is the app.js and the otherone is api.js.
In the first file I have :
app.use(setHeader)
app.use(api.routes())
app.use(api.allowedMethods())
And in api.js I have:
import KoaRouter from 'koa-router';
const api = new Router();
//Validatekey
const validateKey = async (ctx, next) => {
const { authorization } = ctx.request.headers;
console.log(authorization);
if (authorization !== ctx.state.authorizationHeader) {
return ctx.throw(401);
}
await next();
}
api.get('/pets', validateKey, pets.list);
When I run the project a error message is throw: Router is not defined.
But If I write both files together, the application go fine.
Anybody knows the problem?
I have solved with var Router = require('koa-router')

The import is currently not implemented in nodejs, neither is it supported in the latest ES2015(ES6).
You will need to use a transpiler like Babel to use import in code.I advice that avoid transpiler as it cause performance issues on production just go with require and it will work.

Obviously Nodejs does not support import / export syntax and using require will solve your problem.
However it is possible to make import work on Node.js by using babel transformers.
Look the following answer for more information https://stackoverflow.com/a/37601577/972240

Related

How to use mysql2 library with Sapper?

I am creating an application in Svelte Sapper. I have a routes/account/login.js API route where I am trying to use mysql2. The route itself works (I checked with Postman), but as soon as I import mysql, the server crashes and an error appears:
[rollup-plugin-svelte] The following packages did not export their `package.json` file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.
- mysql2
import mysql from "mysql2/promise";
export async function post(req, res) {
//route test
const { login, password } = req.body;
res.end(`${login}, ${password}`);
}
What can I do to make this import work?
What can I do to make this import work?
The Sapper documentation doesn't say anything about whether you need to change something in the configuration additionally. https://sapper.svelte.dev/docs#Server_routes
I found a solution. I had to create a #lib folder in the src/node_modules folder and there file eg. db.js. In that file instead of import you need to use require()! and then you have to export the function that connects to the database. and then you can import that in the path
//src/node_modules/#lib/db.js
const mysql = require("mysql2");
export async function connectToDatabase() {
return mysql.createConnection({
host: "localhost",
....
})
}
//routes/account/login.js
import { query } from "#lib/db";
export async function post(req, res) {
...
}

typescript express get does not work in separate files

I'm currently converting my node code to node-ts to help our development flow for someone that is going to help out.
I tried using this information (typescript node.js express routes separated files best practices) initially but that didn't work, so as of right now I have this below
In my index.ts I have this on the bottom
import Auth from "./routes/Auth";
app.use('/auth', Auth.Routing());
export = app;
Then in my ./routes/Auth.ts I have this
const Routing = function() {
app.get('/session', User.session);
return app;
}
export = { Routing };
When I try to access /auth/session all it returns is index_1.default.get.
Using the link above, I attempted to use const router = express.Router(); and then export = router and what not but was unable to get it to work for that either with the same error.

How to remove authentication for introspection query in Graphql

so may be this is very basic question so please bear with me. Let me explain what I am doing and what I really need.
EXPLANATION
I have created a graphql server by using ApolloGraphql (apollo-server-express npm module).
Here is the code snippet to give you an idea.
api.js
import express from 'express'
import rootSchema from './root-schema'
.... // some extra code
app = express.router()
app.use(jwtaAuthenticator) // --> this code authenticates Authorization header
.... // some more middleware's added
const graphQLServer = new ApolloServer({
schema: rootSchema, // --> this is root schema object
context: context => context,
introspection: true,
})
graphQLServer.applyMiddleware({ app, path: '/graphql' })
server.js
import http from 'http'
import express from 'express'
import apiRouter from './api' // --> the above file
const app = express()
app.use([some middlewares])
app.use('/', apiRouter)
....
....
export async function init () {
try {
const httpServer = http.createServer(app)
httpServer
.listen(PORT)
.on('error', (err) => { setTimeout(() => process.exit(1), 5000) })
} catch (err) {
setTimeout(() => process.exit(1), 5000)
}
console.log('Server started --- ', PORT)
}
export default app
index.js
require('babel-core')
require('babel-polyfill')
require = require('esm')(module/* , options */)
const server = require('./server.js') // --> the above file
server.init()
PROBLEM STATEMENT
I am using node index.js to start the app. So, the app is expecting Authorization header (JWT token) to be present all the times, even for the introspection query. But this is not what I want, I want that introspection query will be resolvable even without the token. So that anyone can see the documentation.
Please shed some light and please guide what is the best approach to do so. Happy coding :)
.startsWith('query Introspection') is insecure because any query can be named Introspection.
The better approach is to check the whole query.
First import graphql and prepare introspection query string:
const { parse, print, getIntrospectionQuery } = require('graphql');
// format introspection query same way as apollo tooling do
const introspectionQuery = print(parse(getIntrospectionQuery()));
Then in Apollo Server configuration check query:
context: ({ req }) => {
// allow introspection query
if (req.body.query === introspectionQuery) {
return {};
}
// continue
}
There's a ton of different ways to handle authorization in GraphQL, as illustrated in the docs:
Adding middleware for express (or some other framework like hapi or koa)
Checking for authorization inside individual resolvers
Checking for authorization inside your data models
Utilizing custom directives
Adding express middleware is great for preventing unauthorized access to your entire schema. If you want to allow unauthenticated access to some fields but not others, it's generally recommended you move your authorization logic from the framework layer to the GraphQL or data model layer using one of the methods above.
So finally I found the solution and here is what I did.
Let me first tell you that there were 2 middle-wares added on base path. Like this:
app //--> this is express.Router()
.use(jwtMw) // ---> these are middlewares
.use(otherMw)
The jwtMw is the one that checks the authentication of the user, and since even introspection query comes under this MW, it used to authenticate that as well. So, after some research I found this solution:
jwtMw.js
function addJWTMeta (req, res, next) {
// we can check for null OR undefined and all, then check for query Introspection, with better condition like with ignore case
if (req.body.query.trim().startsWith('query Introspection')) {
req.isIntrospection = true
return next()
}
...
...
// ---> extra code to do authentication of the USER based on the Authorization header
}
export default addJWTMeta
otherMw.js
function otherMw (req, res, next) {
if (req.isIntrospection) return next()
...
...
// ---> extra code to do some other context creation
}
export default otherMw
So here in jwtMw.js we are checking that if the query is Introspection just add a variable in req object and move forward, and in next middleware after the jwtMw.js whosoever wants to check for introspection query just check for that variable (isIntrospection, in this case) and if it is present and is true, please move on. We can add this code and scale to every middleware that if req.isIntrospection is there just carry on or do the actual processing otherwise.
Happy coding :)

Having control flow issue with mongoose model's find

I'm completely new to node and it's frameworks Koa and express. I've a mongoose model called Drawing and a router module for that.
Problem is with express routers I was able the get the data from database using Drawing.find method but with Koa, control is not even going into Drawing.find. And I'm not able to get the data at all. Please find the following related code and help me understand the things better.
This is my router module
import * as Router from "koa-router";
import Drawing from "../../models/drawing";
function getRoutesForDrawing(): Router {
console.log("Inside getRoutes for drawing");
let route = new Router();
route.get("/drawing", function(context,next) {
console.log("Inside /drawing");
Drawing.find(function(err,drawings) {
console.log("Not gettig executed");
context.body = "Welcome";
});
//context.body = "Welcome";
});
}
export default getRoutesForDrawing();
And the model is
import mongoose = require("mongoose");
export interface IDrawing extends mongoose.Document {
drawingId:Number,
drawingName:String,
updatedOn:Date,
updatedBy:Number
};
export const DrawingSchema = new mongoose.Schema({
drawingId:Number,
drawingName:String,
updatedOn:Date,
updatedBy:Number
});
const Drawing = mongoose.model<IDrawing>('Drawing', DrawingSchema);
export default Drawing;
As you can see in my router module, the control is actually coming for /drawing and it's printing in console "Inside /drawing" but then control isn't coming to Drawing.find. I'm getting difficulty in understanding this.
It's a little bit hard to figure out what's going on because it looks like you have problems all over the place. Let me point out the things that stand out:
getRoutesForDrawing is declared to return a router and doesn't return anything
Koa routes are not like express. In particular they are not callback based. They take either generator functions (Koa 1.x) or async functions (Koa 2.x). You seem to expect that it's wanting a callback function which won't work. Assuming koa 2.x, its router.get('/drawing', async(context) => {...});
Assuming koa 2.x, you need to await the result of the mongoose methods, e.g. context.body = await Drawing.find({})

Connect and Express utils

I'm new in the world of Node.js
According to this topic: What is Node.js' Connect, Express and “middleware”?
I learned that Connect was part of Express
I dug a little in the code, and I found two very interesting files :
./myProject/node_modules/express/lib/utils.js
and better :
./myProject/node_modules/express/node_modules/connect/lib/utils.js
These two files are full of useful functions and I was wondering how to invoke them correctly.
As far, in the ./myProject/app.js, that's what I do:
var express = require('express')
, resource = require('express-resource')
, mongoose = require('mongoose')
, expresstUtils =
require('./node_modules/express/lib/utils.js');
, connectUtils =
require('./node_modules/express/node_modules/connect/lib/utils.js');
But I found it a little clumsy, and what about my others files?
e.g., here is one of my routes:
myResources = app.resource(
'myresources',
require('./routes/myresources.js'));
and here is the content of myresources.js:
exports.index = function(req, res)
{
res.render('./myresources.jade', { title: 'My Resources' });
};
exports.show = function(req, res)
{
fonction resourceIsWellFormatted(param)
{
// Here is some code to determine whether the resource requested
// match with the required format or not
// return true if the format is ok
// return false if not
}
if (resourceIsWellFormatted(req.params['myresources']))
{
// render the resource
}
else
{
res.send(400); // HEY! what about the nice Connect.badRequest in its utils.js?
}
};
As you can see in the comment after the res.send(400), I ask myself if it is possible to use the badRequest function which is in the utils.js file of the Connect module.
What about the nice md5 function in the same file?
Do I have to place this hugly call at the start of my myresources.js to use them?:
var connectUtils =
require('../node_modules/express/node_modules/connect/lib/utils.js');
or, is there a more elegant solution (even for the app.js)?
Thank you in advance for your help!
the only more elegant way i came up with is (assuming express is inside your root "node_modules" folder):
require("express/node_modules/connect/lib/utils");
the node installation is on windows, node version 0.8.2
and a bit of extra information:
this way you don't need to know where you are in the path and be forced to use relative paths (./ or ../), this can be done on any file nesting level.
i put all my custom modules inside the root "node_modules" folder (i named my folder "custom_modules") and call them this way at any level of nesting:
require("custom_modules/mymodule/something")
If you want to access connect directly, I suggest you install connect as a dependency of your project, along with express. Then you can var utils = require('connect').utils.

Resources