Cannot POST ajax request - ajax

can anyone explain to me why i cannot post the ajax request. When i run this code the console appear POST http://localhost:8080/api/users 404 (Not Found), and in the networth part the preview is 404 not found
In the index.js file
var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.config.dev.js');
var app = express();
var compiler = webpack(config);
var bodyParser = require('body-parser');
var users = require('./server/routes/users');
app.use(bodyParser.json());
app.use('/api/users', users);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath
}));
app.use(require('webpack-hot-middleware')(compiler));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.listen(8080, 'localhost', function(err) {
if (err) {
console.log(err);
return;
}
console.log('Listening at http://localhost:8080');
});
and the users file
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
function validateInput(data) {
let errors = {};
if (Validator.isNull(data.username)){
errors.username = "This field is required";
}
if (Validator.isEmail(data.email)) {
errors.email = "Email is invalid";
}
if (Validator.isNull(data.password)){
errors.password = 'This field is required';
}
if (Validator.isNull(data.passwordConfirmation)){
errors.passwordConfirmation = 'This field is required';
}
if (Validator.equals(data.password, data.passwordConfirmation)){
errors.passwordConfirmation = 'Password must match';
}
return {
errors,
isValid: isEmpty(errors)
}
}
router.post('/api/users', (req, res) => {
console.log('runiing the router/post');
console.log(req.body);
const {errors, isValid} = validateInput(req.body);
if (!isValid) {
res.status(400).json(errors);
}
});
module.exports = router

in users.js file the function should be
router.post('/', (req, res) => {
console.log('runiing the router/post');
console.log(req.body);
const {errors, isValid} = validateInput(req.body);
if (!isValid) {
res.status(400).json(errors);
}
});
Because index.js have already resolved /api/users part in the request url http://localhost:8080/api/users at this point. So you only have to map after the /api/users in your users js file.
For example, if you have following function in users.js file
router.post('/:id', (req, res) => {
...
}
It will resole to the path http://localhost:8080/api/users/1
Edit
In your existing version,
router.post('/api/users', (req, res) => {
...
}
will resolve as http://localhost:8080/api/users/api/users

Related

SocketIO 4 - won't emit to the room

I have following server code:
const path = require("path");
const http = require("http");
const express = require("express");
const {instrument} = require('#socket.io/admin-ui')
const {jwtDecode, jwtVerify, resignJwt} = require('jwt-js-decode')
const secret =
"xxxxxxx";
const app = express()
const server = http.createServer(app)
const io = require("socket.io")(server, {
cors: {
origin: ["https://admin.socket.io", "http://localhost:3001"],
credentials: true
},
});
let servantID = ''
io.use((socket, next) => {
const header = socket.handshake.headers["authorization"];
jwtVerify(header, secret).then((res) => {
if (res === true)
{
const jwt = jwtDecode(header);
servantID = jwt.payload.iss;
return next()
}
return next(new Error("authentication error"));
});
});
instrument(io, { auth: false });
server.listen(3000, () =>
console.log('connected')
)
io.on('connection', socket => {
socket.on("join", (room, cb) => {
console.log('Joined ' + room);
socket.join(room);
cb(`Joined the best room ${room}`)
});
socket.on('newOrder', function (data) {
socket.to('servant').emit('this', data);
console.log(data);
})
socket.on("thisNew", function (data) {
console.log('this new');
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
})
And client side code:
socket.emit('join', 'servant', message => {
console.log(message)
})
socket.on('this', () => {
console.log('this event')
})
socket.emit('newOrder', 'data')
When I emit like this:
socket.to('servant').emit('this', data);
the client doesn't receive anything, but if I emit without room:
socket.emit('this', data);
the event and data are received on the client side.
What am I doing wrong here?

Speech Service Authentication With 'Credentials' Via Webchat on Bot Framework V4

My bot is working fine while calling Speech Services using an authorization token + region pair.
Code snipped below.
webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({ authorizationToken, region });
However, the following warning message shows up on the browser:
botframework-webchat: "authorizationToken", "region", and "subscriptionKey" are deprecated and will be removed on or after 2020-12-17. Please use "credentials" instead.
How can migrate my authentication code to the new method?
Code samples are appreciated. Thx
This is the code I use. I run a server locally for calling the speech API that returns the token (and region).
In the Web Chat code, you simply need to pass the returned token and region in to createCognitiveServicesSpeechServicesPonyfillFactory(). Your code doesn't need to match mine, specifically. It is enough to do something like:
const webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory( {
credentials: {
authorizationToken: authorizationToken,
region: region
}
} );
or, depending how you structure your credentials object,
{ credentials: credentials }
Sample code:
const path = require('path');
const restify = require('restify');
const request = require('request');
const bodyParser = require('body-parser');
const corsMiddleware = require('restify-cors-middleware');
const cors = corsMiddleware({
origins: ['*']
});
const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });
// Create HTTP server.
const server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
server.use(bodyParser.json({
extended: false
}));
server.listen(process.env.port || process.env.PORT || 3500, function() {
console.log(`\n${ server.dl_name } listening to ${ server.url }.`);
});
server.post('/speechservices/token', async (req, res) => {
const options = {
method: 'POST',
uri: `https://${ process.env.SPEECH_SERVICES_REGION }.api.cognitive.microsoft.com/sts/v1.0/issueToken`,
headers: {
'Ocp-Apim-Subscription-Key': process.env.SPEECH_SERVICES_SUBSCRIPTION_KEY
}
};
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
body = { region: process.env.SPEECH_SERVICES_REGION, authorizationToken: body };
res.send({
authorizationToken: body.authorizationToken,
region: body.region
});
console.log(`Someone requested a speech token...(${ response.statusCode })`);
} else if (response.statusCode >= 400 && response.statusCode < 500) {
res.send(response.statusCode);
} else if (response.statusCode >= 500) {
res.status(response.statusCode);
res.send('Call to retrieve token failed');
}
});
});
const getSpeechToken = async (credentials = {}) => {
const response = await fetch( `http://localhost:3500/speechservices/token`, {
method: 'POST',
} );
if ( response.status === 200 ) {
const { authorizationToken, region } = await response.json();
credentials['authorizationToken'] = authorizationToken;
credentials['region'] = region;
return credentials;
} else {
console.log('error')
}
}
const webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory( {
credentials: await getSpeechToken()
} );
render(
<div>
<ReactWebChat
directLine={directLine}
selectVoice={( voices, activity ) =>
activity.locale === 'en-US' ?
voices.find( ( { name } ) => /KatjaNeural/iu.test( name ) )
:
voices.find( ( { name } ) => /KatjaNeural/iu.test( name ) )
|| voices.find( ( { name } ) => /Apollo/iu.test( name ) )}
webSpeechPonyfillFactory={webSpeechPonyfillFactory}
/>
</div>,
document.getElementById( 'webchat' )
);
Hope of help!

Dialogflow v2 Actions on Google response timeout

Hi I have a timeout problem to get a json response; I am using google places API to look for the closest location.
Could anyone help me with this? Thanks.
const PlaceSearch = require("./node_modules/googleplaces/lib/NearBySearch.js");
const PlaceDetailsRequest = require("./node_modules/googleplaces/lib/PlaceDetailsRequest.js");
app.intent('Ask Location', conv => {conv.ask(new Permission({context: 'To start',permissions: 'DEVICE_PRECISE_LOCATION',}));});
app.intent('geolocation.intent', (conv,params,granted) =>{
if(granted){
var coordinates = conv.device.location.coordinates;
var location = [coordinates.latitude, coordinates.longitude];
var searchParameters = {
location: location,
name:'Store Name',
radius:10000
};
var config = {
apiKey:'#####',
outputFormat:'json'
};
var placeSearch = new PlaceSearch(config.apiKey, config.outputFormat);
var placeDetailsRequest = new PlaceDetailsRequest(config.apiKey, config.outputFormat);
placeSearch(searchParameters, function (error, search_response) {
if(search_response.status === 'OK'){
placeDetailsRequest({reference: search_response.results[0].reference}, function (error, details_response) {
conv.ask(`Your closest store is at ${details_response.result.formatted_address}.`);
});
}
});
}
});
I solved the issue using a request to Google API via URL; and using a promise.
const request = require("request");
app.input("geolocation.intent", conv => {
return new Promise((resolve, reject) => {
...
request(options, (error, response, body) => {
...
if (error) {
...
reject(...);
} else {
...
resolve(...);
}
}).then(result => {
const address = result.address;
conv.ask('Your closest store is...');
}).catch(error => {
conv.close('Error in Promise');
});
});
What I learned is that in Dialogflow API v2 you need to use promises when you make a request.

Display image on pug

I'm new to NodeJS world.
I tried to display image from mongodb using pug and node express.
Please see my code and guide me.
customer.pug
extend layouts
block content
h1.container #{title} of #{customer.full_name}
div.container
p Full Name: #{customer.full_name}
p Address: #{customer.address}
p Age: #{customer.age}
img.imageScr1(src=customer.profileimage, alt=customer.full_name)
app.js
const express = require('express');
const path = require('path');
const router = express.Router();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const fs = require('fs');
const multer = require('multer');
// set storage engine
const storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, './uploads/',)
},
filename: function (req, file, cb) {
cb(null, file.fieldname + Date.now() + path.extname(file.originalname));
}
});
// init upload
const upload = multer({
storage: storage
});
// Middlewares
// middleware for Assets - to set public for assets
app.use(express.static(path.join(__dirname, 'public')));
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
// route - homepage
app.get('/', function (req, res) {
Customer.find({}, null, function(err, customers) {
if(err){
console.log(err);
} else{
// customers.profileimage = '/' + customers.profileimage;
// console.log('image prefix::: ' + customer.profileimage);
res.render('index', {
title: 'Customer List',
customers: customers
});
}
});
});
app.post('/customer/add', upload.single('profileimage'), function (req, res) {
var customer = new Customer();
customer.full_name = req.body.full_name;
customer.address = req.body.address;
customer.age = req.body.age;
customer.profileimage = req.file.path;
customer.save(function (err) {
if(err){
console.log(err);
} else{
res.redirect('/');
}
});
});
I got following error when render customer.pug view.
error_console
I found that, if I add '\' before image path 'uploads\profileimage1520473825415.jpg', it displays image.
I tried many ways to do that did not work.
Please help me.
Cheers

Implementing ACL with webhooks for VerneMQ

I am trying to get ACL behavior by implementing my own webhooks for VerneMQ. I am using express and apicache node packages for this. I hope the code is meaningful to non-javascript-programmers as well.
In my vernemq.conf I have set up my hooks, and they get called correctly:
$ vmq-admin webhooks show
+-----------------+------------------------------+-------------+
| hook | endpoint |base64payload|
+-----------------+------------------------------+-------------+
|auth_on_subscribe|http://127.0.0.1:3000/vmq/sub | true |
|auth_on_register |http://127.0.0.1:3000/vmq/auth| true |
| auth_on_publish |http://127.0.0.1:3000/vmq/pub | true |
+-----------------+------------------------------+-------------+
Also I disabled all other plugins and disabled anonymous login.
My webhooks implementation in express (simplified):
const express = require('express');
const apicache = require('apicache');
const bodyparser = require('body-parser');
// short cache times for demonstration
const authcache = apicache.middleware('15 seconds');
const pubcache = apicache.middleware('5 seconds');
const subcache = apicache.middleware('10 seconds');
const app = express();
const jsonparser = bodyparser.json();
app.use((req, res, next) => {
console.log(`${req.connection.remoteAddress}:${req.connection.remotePort} ${req.method} ${req.path}`);
return next();
});
app.post('/vmq/auth', authcache, (req, res) => {
return res.status(200).json({result: 'ok'});
});
app.post('/vmq/pub', pubcache, jsonparser, (req, res) => {
// this gets ignored most of the time because of caching
if (req.body.topic === 'only/allowed/topic') {
return res.status(200).json({result: 'ok'});
}
return res.status(401).end();
});
app.post('/vmq/sub', subcache, (req, res) => {
return res.status(200).json({result: 'ok'});
});
app.use((req, res, next) => {
return res.status(404).end();
});
app.use((err, res, req, next) => {
console.error(err);
return res.status(500).end();
});
const server = app.listen(3000, 'localhost', () => {
const address = server.address();
return console.log(`listening on ${address.address}:${address.port} ...`);
});
Using mqtt.js I wrote a client (simplified):
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://localhost');
client.on('connect', () => {
setInterval(() => {
client.publish('only/allowed/topic', 'working');
client.publish('some/disallowed/topic', 'working too :(');
}, 500);
return client.subscribe('some/disallowed/topic');
});
client.on('message', (topic, message) => {
return console.log(`${topic}:${message}`);
});
What happens is that the client successfully authenticates and then publishes to only/allowed/topic, which is allowed and gets cached as successful by VerneMQ. However, since the successful call to /vmq/pub is now cached, publishing to some/disallowed/topic also works. If I change the order of publishing, both will fail.
I would have expected VerneMQ to map the cached results to all parameters in a call, except the payload of course, and not just to a client connection. However that is not the case. What's a possible way to implement ACL via webhooks while using caching? Not using caching is out of the question, as this kills my performance, and caching is recommended by the docs anways.
Also, will someone with 1500+ rep be so nice and create the tag vernemq? :)
I misunderstood how apicache works and what it actually does. All I needed to do was just setting the appropriate header for caching, as stated in the docs of VerneMQ. Apparently apicache stores the actual result and returns that whenever asked within the specified timeframe, no matter what the client is actually requesting.
This is the working code now:
const express = require('express');
const bodyparser = require('body-parser');
const app = express();
// short cache times for demonstration (in seconds)
const authcachetime = 15;
const pubcachetime = 5;
const subcachetime = 10;
const jsonparser = bodyparser.json();
app.use((req, res, next) => {
console.log(`${req.connection.remoteAddress}:${req.connection.remotePort} ${req.method} ${req.path}`);
return next();
});
app.post('/vmq/auth', (req, res) => {
res.set('cache-control', `max-age=${authcachetime}`);
return res.status(200).json({result: 'ok'});
});
app.post('/vmq/pub', jsonparser, (req, res) => {
res.set('cache-control', `max-age=${pubcachetime}`);
if (req.body.topic === 'only/allowed/topic') {
return res.status(200).json({result: 'ok'});
}
return res.status(401).end();
});
app.post('/vmq/sub', (req, res) => {
res.set('cache-control', `max-age=${subcachetime}`);
return res.status(200).json({result: 'ok'});
});
app.use((req, res, next) => {
return res.status(404).end();
});
app.use((err, res, req, next) => {
console.error(err);
return res.status(500).end();
});
const server = app.listen(3000, 'localhost', () => {
const address = server.address();
return console.log(`listening on ${address.address}:${address.port} ...`);
});
As expected the client now gets an error when it tries to publish to an illegal topic.

Resources