I am working on setting up Stampery. I am unable to figure out where to set the string API key in this API.JS file. The documentation says to set the STAMPERY_TOKEN as the API key not sure how to do this. Any help would be appreciated.
The link for Stampery is https://github.com/stampery/office.
'use strict';
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser')
const Stampery = require('stampery');
const development = process.env.NODE_ENV !== 'production';
const stamperyToken = process.env.STAMPERY_TOKEN;
var proofsDict = {}
if (!stamperyToken) {
console.error('Environment variable STAMPERY_TOKEN must be set before running!');
process.exit(-1);
}
//var stampery = new Stampery(process.env.STAMPERY_TOKEN, development ? 'beta' : false);
// For now, always use production Stampery API due to not making it work against beta.
var stampery = new Stampery(process.env.STAMPERY_TOKEN);
router.use(bodyParser.json());
router.post('/stamp', function (req, res) {
var hash = req.body.hash;
// Throw error 400 if no hash
if (!hash)
return res.status(400).send({error: 'No Hash Specified'});
// Transform hash to upper case (Stampery backend preferes them this way)
hash = hash.toUpperCase()
// Throw error 422 if hash is malformed
var re = /^[A-F0-9]{64}$/;
if (!(re.test(hash)))
return res.status(422).send({error: 'Malformed Hash'});
stampery.stamp(hash, function(err, receipt) {
if (err)
res.status(503).send({error: err});
else
res.send({result: receipt.id, error: null});
});
});
router.get('/proofs/:hash', function (req, res) {
var hash = req.params.hash;
stampery.getByHash(hash, function(err, receipts) {
if (err)
res.status(503).send({error: err});
else
if (receipts.length > 0)
res.send({result: receipts[0], error: null});
else
res.status(200).send({error: 'Oops! This email has not yet been attested by any blockchain.'});
});
});
module.exports = router;
I have added the following in Azure website. Should this suffice :
You need to set up STAMPERY_TOKEN environment veriable before starting your server.
You can do this like this for example (in Windows) set STAMPERY_TOKEN=your-token&& node app.js
There are 2 ways to add this to environment (For Ubuntu).
Add to bashrc File. Like:
export STAMPERY_TOKEN="YOUR-TOKEN"
Pass these params before running server. Like:
STAMPERY_TOKEN=YOUR-TOKEN node server.js
To access this variable you can get by:
console.log(process.env["STAMPERY_TOKEN"]);
Related
I'm kinda new to module creation and was wondering about module.exports and waiting for async functions (like a mongo connect function for example) to complete and exporting the result. The variables get properly defined using async/await in the module, but when trying to log them by requiring the module, they show up as undefined. If someone could point me in the right direction, that'd be great. Here's the code I've got so far:
// module.js
const MongoClient = require('mongodb').MongoClient
const mongo_host = '127.0.0.1'
const mongo_db = 'test'
const mongo_port = '27017';
(async module => {
var client, db
var url = `mongodb://${mongo_host}:${mongo_port}/${mongo_db}`
try {
// Use connect method to connect to the Server
client = await MongoClient.connect(url, {
useNewUrlParser: true
})
db = client.db(mongo_db)
} catch (err) {
console.error(err)
} finally {
// Exporting mongo just to test things
console.log(client) // Just to test things I tried logging the client here and it works. It doesn't show 'undefined' like test.js does when trying to console.log it from there
module.exports = {
client,
db
}
}
})(module)
And here's the js that requires the module
// test.js
const {client} = require('./module')
console.log(client) // Logs 'undefined'
I'm fairly familiar with js and am still actively learning and looking into things like async/await and like features, but yeah... I can't really figure that one out
You have to export synchronously, so its impossible to export client and db directly. However you could export a Promise that resolves to client and db:
module.exports = (async function() {
const client = await MongoClient.connect(url, {
useNewUrlParser: true
});
const db = client.db(mongo_db);
return { client, db };
})();
So then you can import it as:
const {client, db} = await require("yourmodule");
(that has to be in an async function itself)
PS: console.error(err) is not a proper error handler, if you cant handle the error just crash
the solution provided above by #Jonas Wilms is working but requires to call requires in an async function each time we want to reuse the connection. an alternative way is to use a callback function to return the mongoDB client object.
mongo.js:
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://<user>:<pwd>#<host and port>?retryWrites=true";
const mongoClient = async function(cb) {
const client = await MongoClient.connect(uri, {
useNewUrlParser: true
});
cb(client);
};
module.exports = {mongoClient}
then we can use mongoClient method in a diffrent file(express route or any other js file).
app.js:
var client;
const mongo = require('path to mongo.js');
mongo.mongoClient((connection) => {
client = connection;
});
//declare express app and listen....
//simple post reuest to store a student..
app.post('/', async (req, res, next) => {
const newStudent = {
name: req.body.name,
description: req.body.description,
studentId: req.body.studetId,
image: req.body.image
};
try
{
await client.db('university').collection('students').insertOne({newStudent});
}
catch(err)
{
console.log(err);
return res.status(500).json({ error: err});
}
return res.status(201).json({ message: 'Student added'});
};
I tried to to that with a random generated string but the route was not created.
The snippet below gives you an idea on how it can be implemented with temporary token. Basically you need to use a path param as a token, verify if that token exists and then discard it after first usage. You can test this code with:
http://localhost:3000/temporary-link/d5407341-3a54-4e30-acf1-09d2174b3e23
After hitting it a second time, it won't work.
var express = require('express');
var app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//get from database or something like it
const allowedUUIDs = ['d5407341-3a54-4e30-acf1-09d2174b3e23',
'7811c8bf-ddf7-4439-a193-93dca12a0656',
'cef82390-9c0a-43e9-93e8-1a80aa5eced5',
'86520485-9d09-48ba-b65c-9bab0ff2e3a2'
];
//test your UUID (access token)
function checkSingleAccess(requestUUID) {
const index = allowedUUIDs.indexOf(requestUUID);
const UUIDExists = index > -1;
if(UUIDExists){
//remove from array, or your database
allowedUUIDs.splice(index, 1);
}
console.log(UUIDExists);
return UUIDExists;
}
//set a path parameter with :uuid
app.use('/temporary-link/:uuid', function(req, res, next) {
//get your path parameter
const requestUUID = req.params.uuid;
//test if allowed
if(checkSingleAccess(requestUUID)){
res.send(`UUID ${requestUUID} allowed` );
}else{
//if not build an error
const errorResponse = `UUID ${requestUUID} not allowed`;
res.status(403, errorResponse);
res.send(errorResponse);
}
});
module.exports = app;
I'm building my first node/express app and am following this tut.
I am at a point where I am trying to get all JSON data and put it in an array to be sent to the template and rendered. When I try to run the app via CLI, I get the following error:
Directory Structure
The data output at the var blogsurlall location
hellotest.js
var routes = require('./routes/index');
var express = require('express');
var app = express();
var request = require("request");
var blogsurlall = "https://[JSON export URL location configured in a Drupal 8 view]";
app.set('view engine','ejs');
var server = app.listen (2000, function(){ console.log('Waiting for you on port 2000'); });
/* Get all global blogs data */
request({
url: blogsurlall,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
blogsdata_all = body;
}
// Create blogs array for footer.
var blogs = [];
// Fill up the array with blogs.
blogsdata_all.blogs.forEach(function(item){
blogs = blogs.concat(item);
});
app.locals.blogsdata = blogs;
});
app.use('/', routes);
index.js
var express = require('express');
var routes = express.Router();
routes.get('/', function(req, res){ res.render('default',{title: 'Home', body: 'blogsdata'}); });
routes.get('/about-us', function(req, res){ res.send('<h1>Lucius Websystems</h1>Amsterdam, The Netherlands'); });
routes.get('/about/:name?', function(req, res){ var name = req.params.name; res.send('<h1>' +name +'</h1>About text'); });
/* GET Blog detail page. */
routes.get('/blog/:blogid', function(req, res, next) {
// Place json data in a var.
var blogsdata = req.app.locals.blogsdata;
// Create array.
var blogItem = [];
// Check and build current URL
var currentURL = '/blog/' + req.params.blogid;
// Lop through json data and pick correct blog-item based on current URL.
blogsdata.forEach(function (item) {
if (item.title == currentURL) {
blogItem = item;
}
});
if (blogItem.length == 0) {
// Render the 404 page.
res.render('404', {
title: '404',
body: '404'
});
} else {
// Render the blog page.
res.render('blog-detail', {
blog: blogItem
});
}
});
module.exports = routes;
From the CLI error, it appears no blog data is even returned to be read into the array.
I have carefully gone through the tutorial several times and I think there are steps that may be implied that I am missing.
Can someone please help me understand how to get the blog data so that it can be read into the array and output to my template?
Also open to troubleshooting suggestions in comments.
Thanks for reading!
The error is raising in this line:
blogsdata_all.blogs.forEach(function(item){
As the error says, blogs is undefined.
If there is an error in the request or status code isn't 200, the body is not assigned to the variable, but you are not finishing the execution, so the variable in that case would be undefined.
Other possible problem is the json received doesn't have blogs as key of the body.
Check this both things and let us know if you found the problem
I'm studying a build full stack JavaScript apps with the MEAN stack, using Node.js, AngularJS, Express and MongoDB.
I'm in the third section where I have to retrieve all the hotels in my database.
When in the browser I type http: // localhost: 3000 / api / hotels /, my database returns an empty array, but the hotel.data.json file is full.
I also tried a copied section5's teacher's final work, but I have the same result, my database is empty [].
This is the code of the hotels.controllers file:
var mongoose = require('mongoose');
var Hotel = mongoose.model('Hotel');
module.exports.hotelsGetAll = function(req, res) {
console.log('GET the hotels');
console.log(req.query);
var offset = 0;
var count = 5;
if (req.query && req.query.offset) {
offset = parseInt(req.query.offset, 10);
}
if (req.query && req.query.count) {
count = parseInt(req.query.count, 10);
}
Hotel
.find()
.skip(offset)
.limit(count)
.exec(function(err, hotels) {
console.log("Found hotels", hotels.length);
res
.json(hotels);
});
};
module.exports.hotelsGetOne = function(req, res) {
var id = req.params.hotelId;
console.log('GET hotelId', id);
Hotel
.findById(id)
.exec(function(err, doc) {
res
.status(200)
.json(doc);
});
};
module.exports.hotelsAddOne = function(req, res) {
console.log("POST new hotel");
var db = dbconn.get();
var collection = db.collection('hotels');
var newHotel;
if (req.body && req.body.name && req.body.stars) {
newHotel = req.body;
newHotel.stars = parseInt(req.body.stars, 10);
collection.insertOne(newHotel, function(err, response) {
console.log("Hotel added", response);
console.log("Hotel added", response.ops);
res
.status(201)
.json(response.ops);
});
// console.log(newHotel);
// res
// .status(200)
// .json(newHotel);
} else {
console.log("Data missing from body");
res
.status(400)
.json({
message: "Required data missing from body"
});
}
};
Thanks for the reply.
This is the file of routes:
var express = require('express');
var router = express.Router();
var ctrlHotels = require('../controllers/hotels.controllers.js');
// Hotel routes
router
.route('/hotels')
.get(ctrlHotels.hotelsGetAll);
router
.route('/hotels/:hotelId')
.get(ctrlHotels.hotelsGetOne);
router
.route('/hotels/new')
.post(ctrlHotels.hotelsAddOne);
module.exports = router;
My console.log() tell:
GET /api/hotels
Requested by: undefined
GET the hotels
{}
(node:2780) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library ins
null
[]
Found hotels 0
I have a hothel-data.json file with all the hotels, the professor in the video at the command prompt when he connects to the db type mongod, but he gave me an error, so when I plug in the db type: mongod --dbpath = data.
I have a main folder, inside I have an API folder with 3 folders inside.
1 CONTROLLERS folder, with hotels-controllers.js, 2 DATA folder with db.js, dbconnection.js, hotel-data.json, hotels.model.js, and 3 ROUTES folder with index.js.
I solved importing the hotel-data.json file, now it's ok, when typing ocalhost: 3000 / api / hotels I see all the hotels.
Thanks anyway.
Aurora
I'm using Node.JS + Express.JS + Multer to handle file uploads. The problem is that I need to query the database to see if a file with this name has been uploaded in the past. If it hasn't been uploaded, then it should be accepted. Otherwise, the file should not be accepted. I'm trying to get this to work using the onFileUploadStart function; however, the database query is asynchronous and I see no way to return false given that the result of the query appears in a callback. If there is a way to execute the query synchronously, my goal will be easy to accomplish. Here is the code:
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var connection = mysql.createConnection({
//connection details
});
router.post('/upload', multer({
onFileUploadStart: function(file, req, res) {
var queryString = "SELECT count(fileName) as count FROM table WHERE fileName = ?;",
queryInserts = [file.originalname];
queryString = mysql.format(queryString, queryInserts);
connection.query(queryString, function(err, rows) {
if (err) {
// handle error
} else {
if (rows[0].count > 0) {
// file should not be accepted
} else {
// file should be accepted
}
}
});
},
dest: "./uploads/"
}), function(req, res) {
// do other stuff
});
Any ideas of how I can accomplish this will be greatly appreciated. Thanks.
My quick reaction would be to use promises. You could have your onFileUploadStart handler create a deferred, assign its promise to the active request object and handle the resolution or rejection of the promise. Then in the main handler for the upload route, you could use then.
I believe this would basically be the new code as applied to your current code. I Note that I am using the Q promises library, but there are other options (promises are also built into ES6 if you are using it).
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var Q = requires('q');
var connection = mysql.createConnection({
//connection details
});
router.post('/upload', multer({
onFileUploadStart: function(file, req, res) {
var deferred = Q.defer();
req.fileUploadPromise = deferred.promise;
var queryString = "SELECT count(fileName) as count FROM table WHERE fileName = ?;",
queryInserts = [file.originalname];
queryString = mysql.format(queryString, queryInserts);
connection.query(queryString, function(err, rows) {
if (err) {
// handle error
deferred.reject('You had an error...');
} else {
if (rows[0].count > 0) {
// file should not be accepted
deferred.reject('You had a duplicate file');
} else {
deferred.resolve(file); // ?? or something useful
// file should be accepted
}
}
});
},
dest: "./uploads/"
}), function(req, res) {
req.fileUploadPromise
.then(function(successResult){
// do other stuff
res.status(200).send('success');
})
.catch(function(errorResult){
// read the error result to provide correct code & error message for user
})
.done();
});