Setting Stormpath Configuration Options - configuration

I am trying to customize the registration page with Stormpath and I can't figure out why the configuration options are not working. The enableXXX and requireXXX work, but none of the info inside web:{...} is showing up. I've tried reordering the options, but that doesn't work either.
Specifically, I want to:
-- Register users at /signup instead of /register. Right now only /register is working.
-- I want to redirect them to another site after registration. I randomly put google.com in there, but I'm still redirected to "/" after registration is complete.
-- I want to reorder the registration fields. I want email to be the first field, but username is currently first.
Here's app.js:
// Import required modules.
var express = require('express');
var stormpath = require('express-stormpath');
var path = require('path');
var engine = require('ejs-mate');
var app = express();
// use ejs-locals for all ejs templates:
app.engine('ejs', engine);
// Configure public views
app.set('views','./views');
app.use(stormpath.init(app, {
apiKeyFile: process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + ~removed
secretKey: '~removed',
application: '~removed',
enableRegistration: true,
enableGivenName: false,
requireGivenName: false,
enableSurname: false,
requireSurname: false,
website: true,
api: true,
web: {
register: {
uri: '/signup', // Use a different URL
nextUri: 'http://google.com', // Where to send the user to, if auto login is enabled
fields: {
passwordConfirm: {
enabled: true,
required: true
}
},
fieldOrder: [ "email", "username", "password", "passwordConfirm" ],
}
},
enableUsername: true,
requireUsername: true,
enableConfirmPassword: true,
requireConfirmPassword: true
}
));
app.get('/', function(req, res) {
res.render('home.ejs', {
title: 'Welcome'
});
});
app.get('/', function(req, res) {
res.send('home page!');
});
app.listen(process.env.PORT || 3000);
Other possibly relevant info:
-- The site is hosted on Heroku, but I'm not using the Stormpath add-on because I couldn't get it to work.
-- I'm on a Mac.
I've been stuck on this for days and I haven't been able to figure out what I'm doing wrong. Any help would be much appreciated.

The issue is likely this: we released a new version of this library recently which has new configuration options, and it appears you are using our OLD docs as a reference.
Here's what you'll want to do:
Update to the latest express-stormpath release. Then use the code below: (I converted your example to work with the latest release):
app.use(stormpath.init(app, {
client: {
apiKey: {
file: process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + '~removed'
}
},
application: {
href: '~removed',
},
web: {
register: {
enabled: true,
uri: '/signup',
nextUri: 'http://google.com', // don't send them here =)
fields: {
username: {
enabled: true,
required: true
},
givenName: {
enabled: false,
required: false
},
surname: {
enabled: false,
required: false
},
passwordConfirm: {
enabled: true,
required: true
}
},
fieldOrder: ['username', 'email', 'password', 'passwordConfirm']
}
},
website: true,
api: true
}));

Related

Why my session are not setting on my network?

I'm currently working on my sessions for my app. Whenever i use the link
TAKE NOTE OF MY LINKS
as you can see on my localhost:3000/login after logging in my cookies and sessions are being set successfully.
This are my cookies after logging in successfully.
HOWEVER, when i wanted to access my app on the built server and after logging in.
My sessions are not able to persists on the cookies tab.
This is my code on setting the session for users
app.use(
cors({
// Change the origin to
// 192.168.254.100
//DEPENDS ON YOUR LOCAL NETWORK OR
// localhost
//origin: ["http://localhost:3000"],
origin: ["http://192.168.254.100:3000"],
methods: ["GET", "POST", "PUT", "DELETE"],
credentials: true,
optionSuccessStatus: 200,
})
);
app.use(
session({
key: "userId",
secret: "subscribe",
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 24 * 60 * 60 * 1000,
},
})
);
this is my routes on setting the session:
app.get("/login", (req, res) => {
if (req.session.user) {
res.send({ loggedIn: true, user: req.session.user });
} else {
res.send({ loggedIn: false });
}
});

Connect MySQL to Fullcalendar

Good day everyone.
I try to feed resources from MySQL db to FullCalendar app. The example in its official docs uses PHP script and effectively all examples I found here also utilize PHP. I just started learning web development and haven't touched PHP and wonder if it's possible to tell the calendar to fetch data from db using node.js and EJS. Here's what I've accomplished so far (please be empathic and forbearing with my mistakes):
In app.js file I put a connection to MySQL, then in GET route it queries data from db and converts it to JSON object (resources).
app.js renders scheduler.ejs and I assume that JSON data is stored in resourcesFeed.
app.js
var express = require('express'),
app = express(),
PORT = process.env.PORT || 3000,
bodyParser = require('body-parser'),
mysql = require('mysql');
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/node_modules'));
app.use(bodyParser.urlencoded({extended: true}));
app.set('view engine', 'ejs');
// create connector to DB
var con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'gdp_scheduler'
});
// connect to DB
con.connect(function(err) {
if (err) throw err;
console.log('Connection to DB established')
});
app.get('/scheduler', function(req,res){
// query the DB
con.query('SELECT id, given_name, level, color FROM resources',
function (err, getResources) {
if (err) throw err;
// convert to JSON
resources = JSON.parse(JSON.stringify(getResources));
console.log(resources);
return resources;
});
// render scheduler page
res.render('scheduler', {resourcesFeed: resources});
});
app.listen(PORT, () => {
console.log('Server is up on port:' ,PORT);
});
scheduler.ejs
<%- include("partials/header") %>
<div class="container-fluid">
<!-- Header -->
<div>
<h1>GDP Projects Timeline</h1>
</div>
<div>
<div id='calendar'></div>
</div>
</div>
<%- include("partials/footer") %>
The scheduler.ejs header has a link to scheduleSetup.js file.
In scheduleSetup.js file, I try to make the calendar to fetch resources from resourcesFeed. And it doesn't work.
scheduleSetup.js
document.addEventListener('DOMContentLoaded', function() {
//Initialize calendar
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source', //hide lices=nc=se warning
plugins: [ 'resourceTimeline', 'bootstrap', 'interaction' ], //connect plugins to page
defaultView: 'resourceTimelineMonth', //define timeline view
editable: true, //enable draggable events
droppable: true, //it allows things to be dropped onto the container
resourceGroupField: 'level', //grouping
resources:
'resourcesFeed',
// [
// { id: 2, title: 'John', level: 'Personnel', color: null },
// { id: 3, title: 'TEST', level: 'Projects', color: 'red' }
// ],
resourcesInitiallyExpanded: true, //the way how resources show up
events: {
url: '/sources/events.json',
}, //link to event json file
defaultTimedEventDuration: '24:00', //deafult event duration
weekNumberCalculation: 'ISO', //first day of week Monday
resourceAreaWidth: '10%', //resource column width
resourceLabelText: 'Projects/Personnel', //resource label
//header layout
header: {
left: 'promptProject today prev,next',
center: 'title',
right: 'resourceTimelineMonth, resourceTimelineYear,'
},
//footer
footer: true,
footer: {
left: 'promptPersonnel'
},
height: 'auto', //calendar window size (including header and ffoter)
//text on standard buttons
buttonText: {
today: 'Today',
month: 'Month',
year: 'Year'
},
//create custom buttns
customButtons: {
promptProject: {
text: 'Add project',
click: function() {
var title = prompt('Project name');
if (title) {
calendar.addResource({
title: title,
level: "Projects"
});
}
}
},
promptPersonnel: {
text: 'Add personnel',
click: function() {
var name = prompt('Name');
if (name) {
calendar.addResource({
title: name,
level: "Personnel"
});
}
}
}
}
});
calendar.render();
});
I try to comprehend the general sequence of how data is transmitted back and forth between backend and client-side, and what methods are used for this, however apparently have no clear picture yet. Any suggestions, tips, and help would be very much appreciated.
Thank you

Sequelize Error: Include unexpected. Element has to be either a Model, an Association or an object

I am receiving the error when I make a call to my API with a get request:
Include unexpected. Element has to be either a Model, an Association or an object.
My Models look like this:
module.exports = (sequelize, Sequelize) => {
const Productions = sequelize.define("productions", {
id: {
type: Sequelize.SMALLINT,
autoIncrement: true,
primaryKey: true
},
setupTime: {
type: Sequelize.DECIMAL(6, 3)
},
notes: {
type: Sequelize.TEXT
}
}, { timestamps: false });
return Productions;
};
module.exports = (sequelize, Sequelize) => {
const ProductionPrints = sequelize.define("productionPrints", {
id: {
type: Sequelize.SMALLINT,
autoIncrement: true,
primaryKey: true
},
compDate: {
type: Sequelize.DATE
}
}, { timestamps: false });
return ProductionPrints;
};
The relationship between the models is defined here:
db.productions = require("./productions.model.js")(sequelize, Sequelize);
db.productionprints = require("./production-prints.model.js")(sequelize, Sequelize);
db.productions.hasOne(db.productionprints, {
foreignKey: {
name: 'productionId',
allowNull: false
}
});
db.productionprints.belongsTo(db.productions, { foreignKey: 'productionId' });
And the sequelize query looks as so:
const db = require("../models");
const Productions = db.productions;
const ProductionPrints = db.productionPrints;
exports.findAll = (req, res) => {
Productions.findAll({
include: [ { model: ProductionPrints, as: 'prints' } ]
})
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "An error occurred while finding the productions."
});
});
};
I have checked around for others with the issue but have had no avail with any solutions posted on those problems. Generally it was caused by typos, or error in the require paths. I have checked those and all my other includes work, just not on any of the models I include on the productions model.
Any feedback is greatly appreciated.
Error was being caused by a typo:
db.productions = require("./productions.model.js")(sequelize, Sequelize);
db.productionprints = require("./production-prints.model.js")(sequelize, Sequelize);
when this was being referenced in the assigned to a constant:
const Productions = db.productions;
const ProductionPrints = db.productionPrints;
shame on me for changing my case use:
db.productionprints != db.productionPrints
I had the same issue , this is usually caused by naming issue , to track the issue you can check one of the following places to resolve it
check if you are calling the correct model class name
when importing models becarefull not to call the file name instead of model name => the one exported
3.check if you got your association correctly by calling the exported model not the file name
check if your cases e.g users vs Users.
a bonus tip is to use same name for model and file name to avoid these issues because the moment you make them different you likely to make these mistakes
Following the answer of Kelvin Nyadzayo, i have the model.findOne(options) method with a
options.include like this:include: [ { } ] in the options parameter
The include has to have the proper syntax: [{model: Model, as: 'assciationName'}]
And the mine was empty
So this, was triggering the same error

Express.js and MySQL model + validation

I am developing application using Node.js and Express framework. I found many examples of modeling data using MongoDB, but my project requires SQL database.
Could someone make simple explanation, what is the best way to make models based on MySQL?
Also I am wondering how to provide later validation of those models. Maybe I should define validation attributes inside each of them?
There is no best way to make models based on MySQL. You could implement your own way to handle models, but there are many ORM modules available for Node.js, I'd suggest using one of those.
I use Sequelize as ORM to define models and interact with the database in several Express applications. Another ORM for Node that I've run into is Bookshelf.js, but there are many others. Wich one to use depends on your preferences and necessities.
EDIT: Example of usage
I suggest the following structure when using Sequelize models: a directory in your project named models with a file for each model and an index.js file to load the Sequelize environment. If you use the Sequelize CLI, it also has several methods that follow this structure.
index.js
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
let sqize = new Sequelize({
host : "1.2.3.4",
port : 1234,
database : "testDb",
username : "pino",
password : "th1S1s#c0mpL3xP4sSw0rD",
dialect: 'mysql',
});
fs.readdirSync(__dirname).filter(function(file) {
return (file.indexOf(".") !== 0) && (file !== "index.js");
}).forEach(function(file) {
let model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if ("associate" in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.op = Sequelize.Op;
module.exports = {
sqize: sqize,
Sequelize: Sequelize,
op: Sequelize.Op
};
users.js
module.exports = function (sequelize, DataTypes) {
let users = sequelize.define('users', {
username: {
type: DataTypes.STRING(255),
allowNull: true
},
firstname: {
type: DataTypes.STRING(255),
allowNull: true
},
secondname: {
type: DataTypes.STRING(255),
allowNull: true
},
email: {
type: DataTypes.STRING(255),
allowNull: true
},
type: {
type: DataTypes.INTEGER(4),
allowNull: true,
references: {
model: 'users_type',
key: 'id'
}
},
password: {
type: DataTypes.STRING(255),
allowNull: true
},
salt: {
type: DataTypes.STRING(255),
allowNull: true
}
}, {
tableName: 'users'
});
users.associate = function (models) {
users.belongsTo(models.user_types, {
foreignKey: "type",
as: "userType"
});
users.hasMany(models.user_logs, {
foreignKey: "user_id",
as: "userLogs"
});
};
return users;
};
For more parameters and details, you can check the Sequelize doc, which is very simple and full of examples and details.
Also, I've used some ECMAScript 6, so change or transpile this code if your version of Node.js does not support them.

How to update migration files when change column or add new column using Sequelize

I'm new in Sequelize, right now I'm creating a RESTful api with NodeJS and Sequelize. I'm trying to figure out how to change my Database Schema like change my Column name using Sequelize
I create a Model like this
sequelize model:create --name MyUser --attributes first_name:string,last_name:string,bio:text
It created a file in Models
'use strict';
module.exports = function(sequelize, DataTypes) {
var Page = sequelize.define('Page', {
name: DataTypes.STRING,
text: DataTypes.TEXT,
url: DataTypes.STRING
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return Page;
};
and one file in Migrations Folder
'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable('Pages', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING
},
text: {
type: Sequelize.TEXT
},
url: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('Pages');
}
};
The problem is how about if I want to add New column and change existing Column Name
Example I want to change to this
'use strict';
module.exports = function(sequelize, DataTypes) {
var Page = sequelize.define('Page', {
fullname: DataTypes.STRING,
text: DataTypes.TEXT,
url: DataTypes.STRING,
email: DataTypes.STRING
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return Page;
};
I have read a few page in Stackoverflow about this, like in this page
How to auto generate migrations with Sequelize CLI from Sequelize models?
and
Sequelize.js: how to use migrations and sync
One of that page has a way to Alter Column automatic using Sequelize-cmd in this link https://www.youtube.com/watch?v=wHTBxtk8ezo but Sequelize-cmd is already deprecated and the other way and the only way I do now is create Migration File using sequelize migration:createand manually write a code to rename and add Column using addColumn and renameColumn
So, my question now is there a way to Creating Migration File with addColumn and renameColumn Automatic like what Sequelize-cmd do without have to write it manually ?
First type sequelize migration:create --name changeColumn into your terminal after navigating to your project directory. This creates a new migration file in your migrations folder called changeColumn with the date of creation prepended.
Then you use the renameColumn method which takes in the table name, original column name and the new column name. Once you have updated the file to the below code, go back to your terminal and type sequelize db:migrate to run the migration.
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.renameColumn('Users',
'beforeName', 'afterName');
},
down: (queryInterface, Sequelize) => {
return queryInterface.renameColumn('Users', 'afterName', 'beforeName');
}
};
Simplest way to do this is
queryInterface.renameColumn('tableName', 'oldName', 'newName');
NOTE: I tries this in down function but not work it's working once I write this code in up function
There is a new npm package for solving this problem by comparing your models files and writing migration files for you
Sequelize-mig
Install it with:
npm install sequelize-mig -g / yarn global add sequelize-mig
then use it like this
sequelize-mig migration:make -n <migration name>
and it will auto generate the migration file for you with all updates read from your models files