expressjs: How to catch all route parameters even if unknown? - express

Lets say I have this route.
this.app.use('/app/fileasset/ui.html/:view*?', function(req,res) {});
If I have this url: /app/fileasset/ui.html /test/view
Then I can catch them in req.params ==> req.params[0] (root url, 'test') and req.params.view ('view')
The question is: how can I catch an unknown numbers of parameters ?
For example: /app/fileasset/ui.html /test/view/subview/wtv
How to get 'subview' and 'wtv' in req.params ? and having the same route to catch longer url with unknown number of params ?
thanks in advance

ExpressJS routing does allow to use wildcards, if you do something like this:
this.app.use('/app/fileasset/ui.html/*', function(req,res) {});
Then going to a url like /app/fileasset/ui.html/test/view/subview/wtv should populate req.params with "['test/view/subview/wtv']" which you can easily split on the forward slash.

Do you tryed foreach over req.params?
req.params.forEach(function (item) {
someFn(item);
})
or just for
for (var i = 0, len = req.params.length; i < len; i++) {
someFn(req.params[i]);
}

Related

Cypress get the text of an API response parameter

I want to get the number from the URL located in an API response.
For that I get the URL, but I don't know how to convert that in to text to extract the number.
cy.intercept('GET', 'http://viasphere.localhost/documents/page_elements/client/**',).as('response')
goTo.plusClientsButton()
cy.wait('#response', {timeout: 10000})
cy.get('#response').then( xhr => {
const link = xhr.request.headers.referer
cy.log(link)
link has the value: http://viasphere.localhost/documents/page_elements/client/19537
Obviosly const link = xhr.request.headers.referer.text() is not working...
You have to add .replace(/^\D+/g, '') to extract the number from the url.
cy.intercept(
'GET',
'http://viasphere.localhost/documents/page_elements/client/**'
).as('response')
goTo.plusClientsButton()
cy.wait('#response', {timeout: 10000})
cy.get('#response').then((xhr) => {
const client_id = xhr.request.headers.referer.replace(/^\D+/g, '')
cy.log(client_id) //prints 19537
})
Alternatively to the .then() Alapan Das provided, you can use cypress commands to perform the same actions.
cy.intercept('GET', 'http://viasphere.localhost/documents/page_elements/client/**',).as('response')
goTo.plusClientsButton()
cy.wait('#response', {timeout: 10000})
// can access request.headers.referer from .wait()
.its('request.headers.referer')
// returns 'http://viasphere.localhost/documents/page_elements/client/'
.invoke('replace', /^D+/g, '')
// now you have the link and can print it
.then(cy.log)

req.query returns nothing

Trying to get variable from http://localhost:3000/categories/subcategories?category_id=13 but req.query returns empty result.
app.get('/subcategories', (req, res) => {
let category_id = req.query.category_id
console.log(req.query)
db.query('SELECT subcategory_name FROM subcategories WHERE category_id=(?)',
[category_id],
(err, result) =>{
res.send({category_id})
});
})
Is this possibly a problem with the way I've set up my server?
See how you are passing the data , directly entering the data or from another URL you are passing the data.
Ensuring you are not sending data via req.body. Ref :
Empty req.query on ExpressJS
or check res.send({category_id}) . Try printing res.send({"category_id": category_id}) . or see console.log(JSON.stringify(req.query))
Or Extract Query Parameters Without Express
const url = require('url');
const querystring = require('querystring');
let rawUrl = 'https://stackabuse.com/?page=2&limit=3';
let parsedUrl = url.parse(rawUrl);
let parsedQs = querystring.parse(parsedUrl.query);
https://stackabuse.com/get-query-strings-and-parameters-in-express-js/

How "equals" in express-validator works?

I have to validate two fields are equals. In this case both passwords are the same. The problem it is that the "equals" from express-validator is not working.
This is the code:
app.post('/register', [
isNotLogged,
check('email', 'The email must be a valid one').isEmail(),
check('nickname', 'The nickname must be filled').notEmpty(),
check('password', 'The password must contain minimum eight characters, at least one letter and one number')
.matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"),
//This is not working
check('passwordConfirm', 'The passwords must match').equals('password'),
validateResults
], register)
Unfortunately Express-Validator doesn't work with Validator.js's equals(), you'll have to use one of Express-Validator's middlewares and not its Validator.js affility.
Here is an example straight from Express-Validator's website which seems fit your use case:
body('oldPassword')
// if the new password is provided...
.if((value, { req }) => req.body.newPassword)
// OR
.if(body('newPassword').exists())
// ...then the old password must be too...
.notEmpty()
// ...and they must not be equal.
.custom((value, { req }) => value !== req.body.newPassword);
You do not need to use Express-Validator's check middleware as you are throwing away your ability to utilise Validator.js's validators. Instead of check you could use isEmail() and exists() (an Express-Validator validator). Also, you don't need to have your middlewares as part of an array (although you can):
app.post('/register',
isNotLogged,
body('email').isEmail().withMessage('The email must be a valid one').bail().trim(),
body('nickname').exists({ checkNull: true }).withMessage('The nickname must be filled').bail().trim(),
body('password').trim().if((value, { req }) => (typeof req.body.passwordConfirm !== 'undefined')).bail().custom((value, { req }) => value !== req.body.passwordConfirm).withMessage('The email must be a valid one').bail().trim().matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"),
validateResults,
register
);
Here the body() function would come from const { body } = require('express-validator') theres a few others similar for query paramaters, header parameters ect, all are documented here.
I also used some trim()s and bails()s just to be safe. You can read up on those here and here.
I solve this problem like this:
code before:
const registrar = async (req, res) => {
await check('password').isLength({ min:6}).withMessage('password short ').run(req);
await check('repetir_password').equals('password').withMessage('password diferente?').run(req);
let resultado = validationResult(req);
res.json(resultado.array());
};
after:
correct code: change
'password'
by
req.body.password
const registrar = async (req, res) => {
await check('password').isLength({ min: 6 }).withMessage('password corta ').run(req);
await check('repetir_password').equals(req.body.password).withMessage('password diferente?').run(req);
let resultado = validationResult(req);
res.json(resultado.array());
};

Blacklisted words | Filter words discord.bs

I got one error with my blacklisted words, cannot read proprety ".id" of undefined. After "db.get(...)"
Thanks to help me!
// BLACKLISTED words
client.on('message', message => {
if(message.author.bot) return;
let wordarray = message.content.split(" ")
let filterWords = db.get(`blacklistwords_${message.guild.id}_${message.guild.id}`)
for(var i = 0; 1 < filterWords.length; i++) {
if(wordarray.includes(filterwords[i])) {
message.delete()
let Filter = new Discord.MessageEmbed()
.setColor('#FFE90F')
.setAuthor(message.guild.name, message.guild.iconURL())
.setDescription('<a:AttentionPink:706154679796760657> | **This word is blacklisted from this guild!** Do not say that again!')
.setTimestamp()
message.author.send(Filter)
break;
}
}
});![enter image description here](https://i.stack.imgur.com/Gouis.jpg)
I think you should put your Guild ID in a var like so:
var guildID = message.guild.id;
If this is not working, well it's not the prettiest, but try using this line of code:
var guildID = bot.guilds.get(message.guild.id).id;
EDIT: Source
If the bot receives a message via DMs, it will not be able to get message.guild and that's why it says it is undefined. You can add something like if(message.channel.type === 'dm') return; so that the bot will not listen to DMs

apache rewrite all hash tag to slash tag under one directory

How to rewrite all hash tag to slash tag under one directory? (apache)
http://www.domain.com/company/index#about => http://www.domain.com/company/index/about
http://www.domain.com/company/article#123456 => http://www.domain.com/company/article/123456
http://www.domain.com/company/events#October => http://www.domain.com/company/events/October
So, all the pages witch in /company/, rewrite # => /.
$(window).on('hashchange', function() {
//
}
In general all the browsers exclude the fragment part (#) from the request to the server. If you really want do it, you must rewrite the urls before call the server
function addHashtag2Pathname(url){
var a = document.createElement('a');
a.href = url;
if (a.pathname.substr(-1) != "/")
a.pathname = a.pathname + '/';
a.pathname += a.hash.replace(/^#/,'');
a.hash = '';
return a.href.replace(/#$/,'');
}
You can see this function in action here
http://jsfiddle.net/bknE4/43/
Actually I haven't tried this below, but it should work...
$(window).on('hashchange', function() {
var newurl = addHashtag2Pathname(location.href);
location.href = newurl;
})
If you navigate your web browser to http://www.domain.com/company/events#October, it will fetch the URL http://www.domain.com/company/events from the server. The server does not see the rest of the URL and can do nothing with it. Only Javascript can act on it.
$(window).on('hashchange', function() {
var a_tags = document.getElementsByTagName('a');
for (var i = 0; i < a_tags.length; i = i + 1) {
var elem = a_tags[i];
if (/company.*#/.test(elem.href)){
elem.href = elem.href.replace('#', '/');
}
}
}
You might want to change the regexp in the if conditional to be more specific.
The same for the replace function.
However I would change the HTML server side instead if it is supposed to be permanent.