Cannot get sessions in apollo server context? - javascript

I ran into that issue:
I cannot get the access the session object in the request object inside the apollo server context, so I get undefined as output.
Otherwise I can access the session object in the request object inside express routes as normal.
How can I solve that?
import express, { Application, Request, Response } from 'express';
import bodyParser from "body-parser";
import helmet from "helmet";
import xss from 'xss';
import moment from "moment";
import passport from "passport";
import { connect } from "mongoose";
import "reflect-metadata";
import { ApolloServer } from 'apollo-server-express';
import { buildSchema, ResolverData } from "type-graphql";
// Import resolvers
import main_config from './main.config';
import AuthenticationRoutes from './Authentication/Authentication.routes';
import './Authentication/Authentication.strategies';
import {
topicResolver, docsResolver, courseResolver, articleResolver, projectIdeaResolver
} from './Graphql/Topics/Topics.resolvers';
import cookieSession from 'cookie-session';
import expressSession from 'express-session';
// const expGql = require("express-graphql");
const app : Application = express();
// Init cookie cookie-session
app.use(cookieSession({
keys : ["IDFVBHNIOVFFBUE"],
name : 'DBDIUN',
secret : "IDFVBHNIOVFFBUE"
}));
async function runapp (){
// Ïnit passport app and routes
app.use(passport.initialize());
app.use(passport.session())
// Run apollo server
const apollo = new ApolloServer({
schema : await buildSchema({
resolvers : [
topicResolver, docsResolver, courseResolver, articleResolver, projectIdeaResolver
],
globalMiddlewares: [],
}),
context: ({ req, res }) =>{
console.log("context")
console.log(req.session.passport) // cannot get session object then Get undefined
return {
getUser: () => req.user,
logout: () => req.logout(),
}
},
playground : true
})
apollo.applyMiddleware({ app });
// Init body parser and helmet
app.use(helmet());
app.use(bodyParser.json());
app.use('/auth', AuthenticationRoutes)
}
runapp();

Don´t deconstruct req work for me:
context: (req, res) => {
return {
req: req,
res: res,
}
};

Related

How to pass pusher to utility classes in node.js

I am using Node.js here with Pusher,
but it's not a pusher related question, it's more of a Node.js question.
In Server.js (declare pusher, and used pusher once for authentication)
import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser'
import Pusher from 'pusher'
const PORT = 4001;
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
const pusher = new Pusher({
appId: "ddsd",
key: "afdafa",
secret: "asdfasdfasfadsf",
cluster: "mt1",
useTLS: true
});
app.post("/pusher/user-auth", (req, res) => { //<--pusher is used once here for authentication
const socketId = req.body.socket_id;
const user = {id: '12345'};
const authResponse = pusher.authenticateUser(socketId, user);
res.send(authResponse);
});
I have a utility file call controllers/messagesWebsocketController
class messagesWebsocketController()
async sendMessageToClients (message) {
pusher.sendToUser("12345", "my-event1", { message}); //<--how do I pass pusher in?
}
const messagesWebsocketController = new MessagesWebsocketController();
export default messagesWebsocketController;
So other classes can simply
import messagesWebsocketController from 'controllers/messagesWebsocketController'
...
messagesWebsocketController.sendMessageToClients("hello");
The question is for controllers/messagesWebsocketController, how do I pass the pusher instance in from server.js?
You can create separate file for pusher, export it and you can use it wherever you like in your app.
const pusher = new Pusher({
appId: 'ddsd',
key: 'afdafa',
secret: 'asdfasdfasfadsf',
cluster: 'mt1',
useTLS: true
});
export default pusher;
then use it like this
import pusher from 'pusher.js'

ES import passport

Can anyone help me use ES import version of the: require('./config/passport')(passport);. I cant get this to work. I don't think you can use both ES import and require at the same time. I get and error that require is undefined.
import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import cors from 'cors';
import dotenv from 'dotenv';
import { createRequire } from 'module';
const URL = createRequire(import.meta.url);
import passport from 'passport'
import postRoutes from './routes/posts.js'
import userRoutes from './routes/user.js'
import loginRoutes from './routes/login.js'
const app = express();
dotenv.config();
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
Yes, we can not use require which is commonjs modules with import which is ES6 modules.
Though the solution is really simple. Basically, you have to pass passport as an argument to the function exported from ./config/passport.
All you have to do is just import the function as is and pass passport as an argument.
So here's what you need to do:-
config/passport.js
export default = (passport) => {
/* use passport here */
}
index.js
import passport from "passport";
import passportConfig from "./config/passport";
passportConfig(passport);
Aryaman is correct but I would like to offer a slightly different solution.
I would recommend that you keep passports logic out of the main app.js/ index.js file as much as possible. I create a config folder with the main passport.js and then a strategies folder that has logic for how users will login.
in your main entry point file eg app.js
pull in passport's config passing app.
import express from 'express';
const app = express();
require('./src/config/passport')(app);
Your config file eg:passport.js should look like this
import passport from 'passport';
require('./strategies/local.strategy')(); //Or whatever strategy you are using
const passportConfig = (app) => {
app.use(passport.initialize());
app.use(passport.session());
// stores user to session
passport.serializeUser((user, done) => {
done(null, user);
});
// retrieves user from session
passport.deserializeUser((user, done) => {
done(null, user);
});
};
export default passportConfig;
Example local strategy aka custom strategy
import passport from 'passport';
import { Strategy } from 'passport-local';
import axios from 'axios';
const localStrategy = () => {
passport.use(new Strategy(
{
usernameField: 'userName',
passwordField: 'password',
},
(username, password, done) => {
const loginUrl = `${process.env.base_url}/api/core/security/login`;
const body = {
InstanceName: process.env.instance_name,
Username: username,
UserDomain: process.env.user_domain,
Password: password,
};
axios.post(loginUrl, body)
.then((response) => {
if (response.data.IsSuccessful === true) {
const user = {
token: response.data.RequestedObject.SessionToken,
userId: response.data.UserId,
userName: username,
};
done(null, user);
} else {
// handle failed login
}
})
.catch((error) =>
//Handle the error
}
))
}
export default localStrategy;

Nodejs Express simple import js file router

how to import the user.json json file into my user.js ? when i type / user the json should be displayed? new version of node I don't understand
index.js
import express from 'express';
import bodyParser from 'body-parser';
import usersRoutes from './routes/users.js';
const app = express();
const PORT = 5000;
app.use(bodyParser.json());
app.use('/users', usersRoutes);
app.get('/', (req, res) => {
res.send('hello');
});
app.listen(PORT, () => console.log(`Server running on port: http://localhost:${PORT}`));
user.js
import express from 'express';
const router = express.Router();
router.get('/', (res, req) => {
res.send();
});
export default router;
import express from 'express';
import userJSON from '../user.json' // < ------- here
const router = express.Router();
router.get('/', (res, req) => {
res.send();
});
export default router;
Depending of the version you are using you either has to use babel or include the --experimental-json-modules flag for the module to work. ** node v.14 does not need anything.
node --experimental-json-modules about.js
import express from 'express';
import userfile from '../user.json' // import the json file
const router = express.Router();
router.get('/', (res, req) => {
res.send(userfile); //this line sends the json
});
export default router;
Instead use the fs module:
const user = require('fs').readFileSync('../user.json', 'utf-8');
You can do it by simply:
import express from 'express';
import user from '../user'; // <---- Don't need even the .json extension.
const router = express.Router();
router.get('/', (res, req) => {
res.send(user);
});
export default router;

nodejs with Graphql

I am facing an issue, while trying graphQL. I guess I am doing something wrong at schema or resolver. Everything according to docs but still not able to get the data.
What Do I need is very simple user model to run its queries in graphiql.
Here is my code: Download code (zip file) (code for node-7.5)
and then just run npm install and npm run build.
Main files: server.js, schema.js, models/user.js and resolvers/user.js.
models/user.js
const typeDefinitions = `
type User {
id: String!
name: String
type: Int
isActive: Boolean
clients: [String]
}
schema {
query: User
}
`;
export default [typeDefinitions]
resolvers/user.js:-
const resolverMap = {
User: {},
};
export default resolverMap
schema.js
import { makeExecutableSchema } from 'graphql-tools';
import resolver from '../resolvers/user'
import User from './user';
export default makeExecutableSchema({
typeDefs: User,
resolvers: resolver,
});
server.js:-
import express from 'express';
import bodyParser from 'body-parser';
import routes from './app/routers/index';
import { graphqlExpress } from 'graphql-server-express';
import schema from './app/models/schema'
var app = express(); // create our app w/ express
var database = require('./app/configs/database');
var port = process.env.PORT || 8888; // set the port
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.urlencoded({ 'extended': 'true' })); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use('/graphql', bodyParser.json(), graphqlExpress({
graphiql: true,
pretty: true,
schema: schema
}));
app.listen(port);
console.log("App listening on port : " + port);
import { graphiqlExpress } from 'graphql-server-express';
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
}));
You need to use above code,
graphiql: true is not supported anymore I guess,
You need to import a graphiql method and pass an endpoint for the same

ExpressJs - route params are not showing in the req.params property

New to nodejs world. Trying to create a REST Service with express and I'm stuck trying to debug this issue... I want to call a GET resource that has a route param in router.use('/applications/:appId/messages', messageRoutes);
index.js
import Promise from 'bluebird';
import mongoose from 'mongoose';
import config from './config/env';
import app from './config/express';
// plugin bluebird promise in mongoose
mongoose.Promise = Promise;
// connect to mongo db
mongoose.connect(config.db, { server: { socketOptions: { keepAlive: 1 } } });
mongoose.connection.on('error', () => {
throw new Error(`unable to connect to database: ${config.db}`);
});
const debug = require('debug')('express-mongoose-es6-rest-api:index');
// listen on port config.port
app.listen(config.port, () => {
debug(`server started on port ${config.port} (${config.env})`);
});
export default app;
/config/express.js
import express from 'express';
import bodyParser from 'body-parser';
import routes from '../server/routes';
const app = express();
// parse body params and attache them to req.body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
[...]
// mount all routes on /api path
app.use('/api', routes);
[...]
export default app;
/server/routes/index.js
import express from 'express';
import userRoutes from './user';
import messageRoutes from './message';
import applicationRoutes from './application';
import authRoutes from './auth';
const router = express.Router(); // eslint-disable-line new-cap
// mount message routes at /messages
router.use('/applications/:appId/messages', messageRoutes);
export default router;
/server/routes/message.js
import express from 'express';
import validate from 'express-validation';
import paramValidation from '../../config/param-validation';
import messageCtrl from '../controllers/message';
const router = express.Router(); // eslint-disable-line new-cap
router.route('/')
/** GET /api/applications/:appId/messages - Get list of messages */
.get(messageCtrl.getByAppId);
export default router;
/server/controllers/message.js
import mg from 'mongoose'
import Message from '../models/message';
import moment from 'moment';
function getByAppId(req, res, next) {
//return res.json(req.message);
console.log(req);
}
export default {getByAppId};
The result of console.log(req) is a printout of the request object but the params array is blank.
baseUrl: '/api/applications/57fcf8129eb1d52f1cb10332/messages',
originalUrl: '/api/applications/57fcf8129eb1d52f1cb10332/messages/',
_parsedUrl:
Url {
protocol: null,
slashes: null,
[...]
params: {},
query: {},
Can anyone offer any guidance? Much appreciated. Not sure why the params are blank. Could it be the :appId variable declaration in express router.use() statement?

Categories