i have a problem with passing generated nonce into my layout.ejs in koa, helmet.
const directives = helmet.contentSecurityPolicy.getDefaultDirectives()
delete directives['form-action']
directives['script-src'] = [
"'self'",
CTFS_BASE_URI,
'https://cdn.cookielaw.org',
(req, res) => {
return `'nonce-${res.locals.cspNonce}'`
}
]
const pHelmet = promisify(
helmet({
contentSecurityPolicy: {
useDefaults: false,
directives
}
})
)
provider.use(async (ctx, next) => {
const origSecure = ctx.req.secure
ctx.req.secure = ctx.request.secure
// eslint-disable-next-line no-unused-expressions
ctx.res.locals || (ctx.res.locals = {})
ctx.res.locals.cspNonce = crypto.randomBytes(16).toString('base64')
await pHelmet(ctx.req, ctx.res)
ctx.req.secure = origSecure
return next()
})
render(provider.app, {
cache: false,
viewExt: 'ejs',
// TODO(#ct): comment layout if you don't want to use it.
layout: '_layout',
root: path.join(__dirname, 'views')
})
My configuration looks like this. provider variable is oidc-provider library.
helmet is from "helmet" and not from "koa/helmet" i tried "koa/helmet" but it doesn't work either.
I am trying to generate nonce and save it into my ctx.res.local.cspNonce. That part works as expected. Then in my _layout.ejs i want to use cspNonce in my script with
<script src="flksdjfsal" <%= locals.cspNonce%>
But it doesn't work. cspNonce variable is empty.
Configuration is from this example https://github.com/panva/node-oidc-provider/blob/main/certification/oidc/index.js
Can someone help me? Thanks
Related
In a vue cli application, scss global variables are injected by webpack chain, or simply using vue.config.js as I did in below.
let data = require('./public/content.json')
let color = data.app.skin.color
module.exports = {
css: {
loaderOptions: {
sass: {
data: `
$font: 'my font';
$host: 'example.com';
$turquaz: ${color.turquaz};
$green: ${color.green};
$green_dark: ${color.green_dark};
$green_darker: ${color.green_darker};
$yellow: ${color.yellow};
$yellow_dark: ${color.yellow_dark};
$yellow_darker: ${color.yellow_darker};
$red: ${color.red};
$red_dark: ${color.red_dark};
$red_darker: ${color.red_darker};
$white: ${color.white};
$grey: ${color.grey};
$dark: ${color.dark};
$dark_overlay: ${color.dark_overlay};
#import '#/styles/main.scss';
`
}
}
}
}
But users decided to get data by an API. So I tried to make a get request to server by axios like below:
const Axios = require('axios')
Axios.get(`api.example.com`)
.then(response => {
let color = response.data.app.skin.color
module.exports = {
css: {
loaderOptions: {
sass: {
data: `
$font: 'my font';
$host: 'example.com';
$turquaz: ${color.turquaz};
$green: ${color.green};
$green_dark: ${color.green_dark};
$green_darker: ${color.green_darker};
$yellow: ${color.yellow};
$yellow_dark: ${color.yellow_dark};
$yellow_darker: ${color.yellow_darker};
$red: ${color.red};
$red_dark: ${color.red_dark};
$red_darker: ${color.red_darker};
$white: ${color.white};
$grey: ${color.grey};
$dark: ${color.dark};
$dark_overlay: ${color.dark_overlay};
#import '#/styles/main.scss';
`
}
}
}
}
}).catch(error => console.error(error))
This way, data is present but not exported, or chained by webpack.
Is there a way to perform this action ?
Thanks in advance.
Not sure what the issue is but my Navigo router is duplicating routes.
The Router:
this.Navigo.hooks({
before: (done, params) => {
// some tomfoolery
done();
}
});
this.Navigo.on({
'/:region/travel': (params) => {
// import Travel module
// some nonsense
},
'/:region/travel/car': (params) => {
// import TravelCar module
// some nonsense
}
)};
this.Navigo.resolve();
The Problem
this.Navigo.navigate('/london/travel/car');
Navigating to /london/travel/car is also triggering the route for /london/travel and thus causing all kinds of twaddle.
Is this standard behaviour? If not, what could be wrong?
I could rewrite the routes so they don't collide e.g. /london/travel-by-car, but I really don't want to if I can avoid it.
UPDATE 1:
I tried switching the order of routes but makes no difference. I did this by declaring the longest travel routes first, /:region/travel/car, and the smallest, /:region/travel, last.
UPDATE 2:
The more I look into this, the more I'm convinced this cannot be achieved with Navigo. Navigo do not support nested routes. If somebody could confirm that my routes are in fact 'nested', I will use an alternative routing library that does support them.
My code is a little different, but works the way you expect:
var router = new Navigo("/");
var render = (content) => (document.querySelector("#app").innerHTML = content);
router
.on('/:id', ({ data }) => {
setuserId(data.id)
if (verifiedUser) {
console.log("User verified");
} else {
console.log("User NOT verified");
}
rendertemplate(userDataURL(), "#landing-template", "#app")
})
.on('/:id/q', ({ data }) => {
// Example - flaging a send with 's' from 'SMS', perhaps a diff flow?
setuserId(data.id)
rendertemplate(userDataURL(), "#landing-template", "#app")
console.log("Source was a QRcode");
})
.on('/:id/q/t', ({ data }) => {
// Example - flaging a send with 's' from 'SMS', perhaps a diff flow?
setuserId(data.id)
rendertemplate(userDataURL(), "#landing-template", "#app")
console.log("Source was a QRcode in a Train");
})
This will give me a single discreet ".. verified"/"Source was a QRcode"/"Source was a QRcode in a Train" console.log response.
B
I want to add custom template functions for Pug views.
For simplicity I've created a demo file with one custom function uppercase:
const Koa = require("koa")
const views = require("koa-views")
const app = new Koa()
app.use(
views(__dirname + "/views", {
extension: "pug",
options: {
helpers: {
uppercase: str => str.toUpperCase()
}
}
})
)
app.use(ctx => ctx.render("index", { name: "Name1" }))
app.listen(3000)
Here is a mega simple template views/index.pug:
h1= uppercase(name)
But it doesn't work, it prints such error:
TypeError: /Users/max7z/projects/test/t24__test__koa-views_pug/views/index.pug:1
> 1| h1= uppercase(name)
2|
uppercase is not a function
Not using Koa, but I solved a similar issue recently using Eleventy.js with Pug. The Pug documentation is not great on this, so it took a while to figure out.
I had to make the function a global, then use the globals property when rendering the template.
e.g.
global.uppercase = function(str){
return str.toUpperCase();
}
app.use(
views(__dirname + "/views", {
extension: "pug",
options: {
globals: ["uppercase"]
}
})
)
I have the following task that build my application:
const app = new Metalsmith(config.styleguide.path.root);
app.use(
msDefine({
production: false,
rootPath: '/'
})
);
app.use(
msIf(
gutil.env.config === 'release',
msDefine({
production: true,
rootPath: '/styleguide/'
})
)
);
app.build(...);
I need to access the rootPath from within the application, eg:
import stuff from 'stuff';
export class IconCtrl ...
...
_getIconPath(name: string, size: string): string {
switch (this.version) {
case 'current':
return `${stuff.rootPath()}/current/icn-${name}-${size}.svg`;
default:
return `${stuff.rootPath()}/legacy/${name}.svg`;
}
}
...
I haven't found a clean way to do it so far. I am not sure how to access the application configuration at build time from within the app.
you could use something like gulp-inject-scripts.
https://www.npmjs.com/package/gulp-inject-scripts
Example
var gulp = require('gulp');
var injectScripts = require('gulp-inject-scripts');
gulp.task('inject:script', function(){
return gulp.src('./demo/src/*.html')
.pipe(injectScripts({
baseDir "./demo/dist" // SET BASE DIRECTORY
}))
.pipe(gulp.dest('./demo/dist'));
});
Im new to Node.js and keep getting the Error: Route.get() requires callback functions but got a [object Undefined] error
and Ive checked out the following question and either dont understand or im still doing something wrong
Express routes: .get() requires callback functions but got a [object Object]
.get() requires callback functions but got a [object Undefined]
Error: Route.get() requires callback functions but got a [object Undefined]
Node Route.get() requires callback function but got a [object undefined]
my file structure is
server.js
routes/api/geolocations.js
routes/api/geolocations/regions.js
routes/api/geolocations/destination.js
ROOT: server.js
var geolocation = require('./routes/api/geolocation')(app);
app.get('/geolocation/', geolocation.delegate);
then I pass my data to routes/api/geolocations.js by using
geolocation.delegate(unparsedData);
from there I parse the data and send it down it's appropriate child routes.
PARENT: geolocations.js in my routes/api/geolocations.js
var destination = require('./geolocations/destination');
var region = require('./geolocations/region');
module.exports = function(app) {
return {
app.get('./geolocation/region', region.delegate);
app.get('./geolocation/destination', destination.delegate);
delegate: function(unparsedData, req, res) {
var data =[setup package for child states using unparsedData]
//HERE Id like to pass the new `data` to region or destination using the following
region.delegate(data);
//OR
destination.delegate(data);
CHILDREN: region.js / destination.js in routes/api/geolocations/regions.js or routes/api/geolocations/destination.js
module.exports = function(app) {
return {
delegate: function(data, req, res) {
...do stuff
}
}
}
UPDATE: I guess I dont know where to set up my routes, in server.js or if i can in geoloaction.js, does it matter, do need to do something like this in server.js?
var regions = require('./routes/api/geolocation/regions')([pass stuff here]);
geolocation.get('./routes/api/geolocation/regions', regions.delegate);
You should use express.js easy setup and run.
Simply download IntelliJ IDEA, find free version, then install. Then run the application and goto File->Setting->Plugin and search for NodeJS then install. Followed to this you need to Enable it. To do this goto File->Setting->Language & Frameworks->open arrow-> JavaScriptopen arrow->Libraries->Enable Node.js Core.
File Structure
routes/api/geolocations.js
routes/api/geolocations/regions.js
routes/api/geolocations/destination.js
You can have a look at the below code that might help you get started.
//------------------------------------------------------------------------
var express = require('express');
var router = express.Router();
var regions = require('../api/geolocations/regions');
var destination = require('../api/geolocations/destination');
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* geolocation.js */
router.get('/', function(req, res, next) {
var region_ext = regions.to_export;
var destin_ext = destination.to_export;
res.render('index', {
title: 'Geolocation',
region: region_ext,
destination:destin_ext
});
});
module.exports = router;
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* region.js */
var to_export = function () {
return 'this is from regions';
}
module.exports.to_export = to_export();
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* destination.js */
var to_export = function () {
return 'this is from destination';
}
module.exports.to_export = to_export();
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//In app.js, just change
var routes = require('./routes/api/geolocations');
//------------------------------------------------------------------------
jfriend00 is right, You got a little mess there. Maybe you should consider make use of next(), since if you use it the other middlewares will have a chance of manipulating the request.