Cannot add response headers - javascript

This is the script I'm using:
const securityHeaders = [
{
key: 'X-XSS-Protection',
value: '1; mode=block'
},
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}
]
module.exports = {
async headers() {
return [
{
// Apply these headers to all routes in your application.
source: '/:path*{/}?',
headers: securityHeaders,
},
]
},
}
But when I run npm run start and check the Response Headers for localhost, none of these headers appears.
Using next version 9.5.2

You can use source: "/(.*?)", or source: '/:path*',

Related

How to distinguish between two calls of the same method based on the argumetns?

I'm using sinon to stub functions of the Google Drive in my NodeJS application. I do two different calls of the create method under the same test (I can't do restore between calls):
// Call 1:
drive.files.create({ 'requestBody': requestBody, 'media': media });
// Call 2:
drive.files.create({ 'resource': resource });
In order to stub, I could do something like:
const stub = sinon.stub(drive.files, 'create').returns({
'status': 200,
'data': {
'files': [{ 'id': id }]
}
});
This stub, actually stubs both calls but what if I want to have a successful first call and fail on the second call? How do I distinguish between the two calls (maybe) based on the arguments?
You can use stub.withArgs(arg1[, arg2, ...]); API.
It is also useful to create a stub that can act differently in response to different arguments.
E.g.
const sinon = require('sinon');
describe('72234931', () => {
it('should pass', () => {
const drive = {
files: {
create(opts) {},
},
};
const stub = sinon.stub(drive.files, 'create');
stub.withArgs({ requestBody: 'requestBody', media: 'media' }).returns({
status: 200,
data: {
files: [{ id: 1 }],
},
});
stub.withArgs({ resource: 'resource' }).returns({ status: 500 });
const r1 = drive.files.create({ requestBody: 'requestBody', media: 'media' });
sinon.assert.match(r1, { status: 200, data: { files: [{ id: 1 }] } });
const r2 = drive.files.create({ resource: 'resource' });
sinon.assert.match(r2, { status: 500 });
});
});

How can I pass an error message from the server backend to vue frontend

I am working on error handling for an application built in Vue/Vuetify. I am using external pagination for a datatable that links to an API that only allows so many hits in a period of time. Because of that, I'm trying to pass through and display an error of "Too Many Requests" on the front end for users when they hit that limit.
The issue I'm having though is passing that error from the backend server to the frontend. When it errors on the front end, it just gives a 500 error. However, the server log is giving me the actual error happening. How can I get that to pass? Below is the relevant javascript code from the server and the front end.
For note: I've been using eventbus to display errors throughout the project. But up until now, I haven't had to pass any from the back to front.
Backend Server
module.exports = {
async find(ctx) {
var page = ctx.query.page;
var key = '';
var locale = ({ location: '', location_type: '', page: page });
const sdk = require('api')('#');
try {
var response = await sdk.auth(key)['grants_funders'](locale);
}
catch (err) {
console.log(err);
}
;
// .then(res => console.log(res))
// .catch(err => console.error(err));
// console.log(response);
return response
}
};
FRONTEND
export default {
name: "Search",
components: {},
props: ["funderDirectories", "serverItemsLength"],
data() {
return {
page: 1,
usericon: usericon,
greentick: greentick,
listicon: listicon,
training: training,
keyword: null,
funderHeaders: [
{ text: "Organization", value: "funder_name" },
{ text: "City", value: "funder_city" },
{ text: "Country", value: "funder_country" },
{ text: "Count", value: "grant_count" },
],
myloadingvariable: false,
pageCount: 1,
itemsPerPage: 25,
};
},
watch: {
page() {
Vue.$funderService.find({ page: this.page }).then((res) => {
this.funderDirectories = res.data.rows;
this.serverItemsLength = res.data.total_hits;
});
},
},
methods: {},
computed: {
filteredFunderDirectories() {
if (!this.keyword) {
return this.funderDirectories;
}
return this.funderDirectories.filter(
(q) =>
q.funder_name.toLowerCase().indexOf(this.keyword.toLowerCase()) !== -1
);
},
},
};
Ultimately figured it out. added the following to the backend catch
return ctx.send({errorStatus:"Too Many Requests. Please Wait"},429)
And I was able to call

MoleculerJs with Jaeger tracing: how to trace follow up action calls (new spans) in one trace

I would like to display all my traces like in the examples from the moleculer-jaeger package:
But what i get is something like this:
All spans you can see in this picture should be within the main trace (gateway).
Here is my moleculer.config:
tracing: {
enabled : true,
stackTrace: true,
actions : true,
exporter : {
type : 'Jaeger',
options: {
// HTTP Reporter endpoint. If set, HTTP Reporter will be used.
endpoint: 'http://jaeger:14268/api/traces',
// UDP Sender host option.
host : 'api.dev.host.com',
// UDP Sender port option.
port : 6832,
// Jaeger Sampler configuration.
sampler : {
// Sampler type. More info: https://www.jaegertracing.io/docs/1.14/sampling/#client-sampling-configuration
type : 'Const',
// Sampler specific options.
options: {
}
},
// Additional options for `Jaeger.Tracer`
tracerOptions: {},
// Default tags. They will be added into all span tags.
defaultTags : {
appName: 'core',
}
}
},
tags: {
action: {
// Always add the response
response: true,
},
},
},
My jaeger-service is just one of the examples:
const JaegerService = require('moleculer-jaeger')
module.exports = {
mixins : [ JaegerService ],
settings: {
host : 'jaeger-server',
port : 6832,
sampler: {
type : 'Const',
options: {
decision: 1
}
}
}
}
I tried several different configurations for sampling but nothing worked the way i would like it to have.
Here is some code where you can see the action calls i do:
// serviceX endpoint:
resolveByName: {
rest : 'GET resolve/name/:name',
params: {
name: { type: 'string' }
},
handler(ctx) {
return resolveByNameHandler(this.broker, ctx.params, 'serviceY')
}
},
// handler code
// please do not focus on the code itself. What i wanted to show is how i call the other
// services.
const { NotFoundError } = require(`${process.env.INIT_CWD}/util/error`)
module.exports = (broker, params, dataSource) => {
const { name } = params
const query = { name: name }
const rejectRequest = (name, data) => Promise.reject(new NotFoundError(name, data))
const getSourceData = result => broker.call(`${dataSource}.find`, { query: { id: result[0].ownerId } })
.then(sourceData => sourceData.length === 0
? rejectRequest(dataSource, sourceData)
: mergeResult(sourceData, result))
const mergeResult = (sourceData, result) => ({ ...sourceData[0], origin: { ...result[0], source: 'serviceX' } })
return broker.call('serviceX.find', { query: query })
.then(result => result.length === 0 ? rejectRequest('serviceX', query): result)
.then(result => result[0].ownerId ? getSourceData(result) : rejectRequest('noOwnerId', query))
}
What i also tried is to not use the moleculer-jaeger package but to use the jaeger all-in-one docker image. Same results though...
# from the docker-compose.yml
jaeger-server:
image: jaegertracing/all-in-one:latest
ports:
- 5775:5775/udp
- 6831:6831/udp
- 6832:6832/udp
- 5778:5778
- 16686:16686
- 14268:14268
- 9411:9411
networks:
- internal
What i do not want to do is to set the spans manually in every service. I have tried it already but it did not work at all, so if this would be the only solution i would be very happy to see an example.
Thanks in advance!
*edit:
The Versions i use:
{
"jaeger-client": "^3.18.1",
"moleculer": "^0.14.13",
"moleculer-db": "^0.8.12",
"moleculer-db-adapter-mongoose": "^0.8.9",
"moleculer-jaeger": "^0.2.3",
"moleculer-web": "^0.9.1",
"mongoose": "^5.12.5",
}
This version already has a built-in jager tracer, see the documentation.
In order for the events to be nested, it is necessary to transfer the context inside the actions, use ctx.call calls instead of broker.call, so they will be nested.
To quickly receive support for the moleculer, join us in discord!

hapi-swagger disables my routes

Below is the glue manifest I use to fire up the server:
var Config = require('../config.json');
var internals = {
manifest: {
connections: [
{
host : Config.host || process.env.IP,
port : Config.apiPort || process.env.PORT,
labels : ['api']
}],
plugins: {
'./decorate': [{ 'select': ['api']}],
'hapi-auth-jwt': [{ 'select': ['api']}],
'./authentication': [{ 'select': ['api']}],
'./controllers': [{ 'select': ['api']}],
'./models': [{ 'select': ['api']}],
'./api': [{ 'select': ['api']}],
good: {
opsInterval: 5000,
reporters: [
{ 'reporter': 'good-console', 'events': { 'log': '*' } }
]
}
}
}
};
if (!process.env.PRODUCTION) {
internals.manifest.plugins['blipp'] = [{}];
internals.manifest.plugins['good'].reporters[0].events['ops'] = '*';
}
module.exports = internals.manifest;
As soon as I add 'hapi-swagger' to the list of plugins the server stops responding to the routes defined in the ./api file. None of the routes work. Is the the right way to add hapi-swagger to the glue manifest or am I doing something absurd?
EDIT: Below is the api.js
exports.register = function (plugin, options, next) {
plugin.dependency('controllers');
plugin.dependency('models');
var Controllers = plugin.plugins.controllers.handlers;
var Models = plugin.plugins.models.models;
plugin.bind({
models: Models
});
plugin.route([
{ method: 'GET', path: '/token', config: Controllers.Membership.token },
{ method: 'GET', path: '/', config: Controllers.Home.status },
{ method: 'GET', path: '/nodes', config: Controllers.Node.search },
{ method: 'GET', path: '/services', config: Controllers.Node.services },
{ method: 'GET', path: '/createnodetree', config: Controllers.Loader.createNodeTree }
]);
next();
};
exports.register.attributes = {
name: 'api',
version: require('../package.json').version
};
This happens if you try to use hapi-swagger without either including the documentation view dependencies or properly disabling documentation support. From the docs:
If you want to view the documentation from your API you will also need to install the inert and vision plugs-ins which support templates and static content serving. If you wish just to used swagger.json without the documentation for example with swagger-codegen simply set options.enableDocumentation to false.
You didn't show how you are adding the hapi-swagger plugin but you simply need to add 'enableDocumentation': false to options wherever you define that. You can find examples at the link above.

hello.js: Is it possible to set the provider's settings dynamically?

I have implemented a new module for hello.js.
I need the auth, grant and base to be dynamic.
Is there a way to set/override these values from the hello.init() call?
My module looks like this:
(function(hello) {
hello.init({
my_service_name: {
name: 'My-Service-Name',
oauth: {
version: 2,
auth: 'http://mydomain/oauth/authorize',
grant: 'http://mydomain/oauth/token'
},
scope: {
basic: ['basic_scope']
},
base: 'http://mydomain/',
xhr: function(p) {
if (p.method !== 'get' && p.data) {
// Serialize payload as JSON
p.headers = p.headers || {};
p.headers['Content-Type'] = 'application/json';
if (typeof (p.data) === 'object') {
p.data = JSON.stringify(p.data);
}
}
return true;
}
}
});
})(hello);
and my hello.init() call:
hello.init({
my_service_name: server.consumerKey
}, {
redirect_uri : server.callbackUrl,
});
The use-case is that the application I am developing will communicate with several servers, so I cannot hardcode the URLs in the module's file.
I figured out that I can override the default settings by passing the whole oauth object in the hello.init() call:
hello.init({
my_service_name: {
id: server.consumerKey,
oauth: {
version: 2,
auth: server.auth_url,
grant: server.token_url
},
base: server.baseUrl
}
}, {
redirect_uri : server.callbackUrl
});

Categories

Resources