Skip to content

Commit bdfa263

Browse files
committed
feat: support custom pathToRegexpModule
1 parent 09fe2ae commit bdfa263

File tree

7 files changed

+183
-17
lines changed

7 files changed

+183
-17
lines changed

app/middleware/securities.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ module.exports = (_, app) => {
1313
}
1414

1515
// format csrf.cookieDomain
16-
const orginalCookieDomain = options.csrf.cookieDomain;
17-
if (orginalCookieDomain && typeof orginalCookieDomain !== 'function') {
18-
options.csrf.cookieDomain = () => orginalCookieDomain;
16+
const originalCookieDomain = options.csrf.cookieDomain;
17+
if (originalCookieDomain && typeof originalCookieDomain !== 'function') {
18+
options.csrf.cookieDomain = () => originalCookieDomain;
1919
}
2020

2121
defaultMiddleware.forEach(middlewareName => {
@@ -46,7 +46,10 @@ module.exports = (_, app) => {
4646
app.deprecate('[egg-security] Please use `config.security.xframe.ignore` instead, `config.security.xframe.blackUrls` will be removed very soon');
4747
opt.ignore = opt.blackUrls;
4848
}
49-
opt.matching = createMatch(opt);
49+
opt.matching = createMatch({
50+
...opt,
51+
pathToRegexpModule: app.options.pathToRegexpModule,
52+
});
5053

5154
const fn = require(path.join(__dirname, '../../lib/middlewares', middlewareName))(opt, app);
5255
middlewares.push(fn);

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"@eggjs/ip": "^2.0.2",
2222
"csrf": "^3.0.6",
2323
"delegates": "^1.0.0",
24-
"egg-path-matching": "^1.0.0",
24+
"egg-path-matching": "^1.2.0",
2525
"escape-html": "^1.0.3",
2626
"extend": "^3.0.1",
2727
"koa-compose": "^4.1.0",
@@ -43,7 +43,8 @@
4343
"eslint": "^8.40.0",
4444
"eslint-config-egg": "^12.2.1",
4545
"spy": "^1.0.0",
46-
"supertest": "^6.3.3"
46+
"supertest": "^6.3.3",
47+
"path-to-regexp-v8": "npm:path-to-regexp@8"
4748
},
4849
"scripts": {
4950
"lint": "eslint .",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module.exports = function(app) {
2+
app.get('/', controller);
3+
app.get('/foo', controller);
4+
app.get('/hello', controller);
5+
app.get('/hello/other/world', controller);
6+
app.get('/world/12', controller);
7+
8+
app.get('/options', options, controller);
9+
10+
async function controller() {
11+
this.body = 'body';
12+
}
13+
14+
async function options(ctx, next) {
15+
ctx.securityOptions.xframe = {
16+
value: 'ALLOW-FROM http://www.domain.com',
17+
};
18+
return next();
19+
}
20+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
exports.keys = 'test key';
2+
3+
exports.security = {
4+
defaultMiddleware: 'xframe',
5+
xframe: {
6+
ignore: ['/hello', '/world/:id'],
7+
},
8+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "iframe-with-pathToRegexpModule"
3+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
const { strict: assert } = require('node:assert');
2+
const mm = require('egg-mock');
3+
4+
describe('test/xframe-with-pathToRegexpModule.test.js', () => {
5+
let app;
6+
let app2;
7+
let app3;
8+
let app4;
9+
before(async () => {
10+
app = mm.app({
11+
baseDir: 'apps/iframe-with-pathToRegexpModule',
12+
plugin: 'security',
13+
pathToRegexpModule: require.resolve('path-to-regexp-v8'),
14+
});
15+
await app.ready();
16+
17+
app2 = mm.app({
18+
baseDir: 'apps/iframe-novalue',
19+
plugin: 'security',
20+
pathToRegexpModule: require.resolve('path-to-regexp-v8'),
21+
});
22+
await app2.ready();
23+
24+
app3 = mm.app({
25+
baseDir: 'apps/iframe-allowfrom',
26+
plugin: 'security',
27+
pathToRegexpModule: require.resolve('path-to-regexp-v8'),
28+
});
29+
await app3.ready();
30+
31+
app4 = mm.app({
32+
baseDir: 'apps/iframe-black-urls',
33+
plugin: 'security',
34+
pathToRegexpModule: require.resolve('path-to-regexp-v8'),
35+
});
36+
await app4.ready();
37+
});
38+
39+
afterEach(mm.restore);
40+
41+
it('should contain X-Frame-Options: SAMEORIGIN', async () => {
42+
await app.httpRequest()
43+
.get('/')
44+
.set('accept', 'text/html')
45+
.expect('x-frame-options', 'SAMEORIGIN');
46+
47+
await app.httpRequest()
48+
.get('/foo')
49+
.set('accept', 'text/html')
50+
.expect('x-frame-options', 'SAMEORIGIN');
51+
});
52+
53+
it('should contain X-Frame-Options: ALLOW-FROM http://www.domain.com by this.securityOptions', async () => {
54+
const res = await app.httpRequest()
55+
.get('/options')
56+
.set('accept', 'text/html');
57+
assert.equal(res.status, 200);
58+
assert.equal(res.headers['x-frame-options'], 'ALLOW-FROM http://www.domain.com');
59+
});
60+
61+
it('should contain X-Frame-Options: SAMEORIGIN when dont set value option', function(done) {
62+
app2.httpRequest()
63+
.get('/foo')
64+
.set('accept', 'text/html')
65+
.expect('x-frame-options', 'SAMEORIGIN', done);
66+
});
67+
68+
it('should contain X-Frame-Options: ALLOW-FROM with page when set ALLOW-FROM and page option', function(done) {
69+
app3.httpRequest()
70+
.get('/foo')
71+
.set('accept', 'text/html')
72+
.expect('x-frame-options', 'ALLOW-FROM http://www.domain.com', done);
73+
});
74+
75+
it('should not contain X-Frame-Options: SAMEORIGIN when use ignore', async () => {
76+
let res = await app.httpRequest()
77+
.get('/hello')
78+
.set('accept', 'text/html')
79+
.expect(200);
80+
assert.equal(res.headers['x-frame-options'], undefined);
81+
82+
// '/hello' won't match '/hello/other/world' on path-to-regexp@8
83+
res = await app.httpRequest()
84+
.get('/hello/other/world')
85+
.set('accept', 'text/html')
86+
.expect(200);
87+
assert.equal(res.headers['x-frame-options'], 'SAMEORIGIN');
88+
89+
res = await app4.httpRequest()
90+
.get('/hello')
91+
.set('accept', 'text/html')
92+
.expect(200);
93+
assert.equal(res.headers['x-frame-options'], undefined);
94+
95+
res = await app.httpRequest()
96+
.get('/world/12')
97+
.set('accept', 'text/html')
98+
.expect(200);
99+
assert.equal(res.headers['x-frame-options'], undefined);
100+
101+
res = await app.httpRequest()
102+
.get('/world/12?xx=xx')
103+
.set('accept', 'text/html')
104+
.expect(200);
105+
assert.equal(res.headers['x-frame-options'], undefined);
106+
107+
res = await app2.httpRequest()
108+
.get('/hello')
109+
.set('accept', 'text/html')
110+
.expect(200);
111+
assert.equal(res.headers['x-frame-options'], undefined);
112+
113+
res = await app2.httpRequest()
114+
.get('/world/12')
115+
.set('accept', 'text/html')
116+
.expect(200);
117+
assert.equal(res.headers['x-frame-options'], undefined);
118+
119+
res = await app2.httpRequest()
120+
.get('/world/12?xx=xx')
121+
.set('accept', 'text/html')
122+
.expect(200);
123+
assert.equal(res.headers['x-frame-options'], undefined);
124+
});
125+
});

test/xframe.test.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ describe('test/xframe.test.js', () => {
3838
await app.httpRequest()
3939
.get('/')
4040
.set('accept', 'text/html')
41-
.expect('X-Frame-Options', 'SAMEORIGIN');
41+
.expect('x-frame-options', 'SAMEORIGIN');
4242

4343
await app.httpRequest()
4444
.get('/foo')
4545
.set('accept', 'text/html')
46-
.expect('X-Frame-Options', 'SAMEORIGIN');
46+
.expect('x-frame-options', 'SAMEORIGIN');
4747
});
4848

4949
it('should contain X-Frame-Options: ALLOW-FROM http://www.domain.com by this.securityOptions', async () => {
@@ -58,57 +58,63 @@ describe('test/xframe.test.js', () => {
5858
app2.httpRequest()
5959
.get('/foo')
6060
.set('accept', 'text/html')
61-
.expect('X-Frame-Options', 'SAMEORIGIN', done);
61+
.expect('x-frame-options', 'SAMEORIGIN', done);
6262
});
6363

6464
it('should contain X-Frame-Options: ALLOW-FROM with page when set ALLOW-FROM and page option', function(done) {
6565
app3.httpRequest()
6666
.get('/foo')
6767
.set('accept', 'text/html')
68-
.expect('X-Frame-Options', 'ALLOW-FROM http://www.domain.com', done);
68+
.expect('x-frame-options', 'ALLOW-FROM http://www.domain.com', done);
6969
});
7070

7171
it('should not contain X-Frame-Options: SAMEORIGIN when use ignore', async () => {
7272
let res = await app.httpRequest()
7373
.get('/hello')
7474
.set('accept', 'text/html')
7575
.expect(200);
76-
assert.equal(res.headers['X-Frame-Options'], undefined);
76+
assert.equal(res.headers['x-frame-options'], undefined);
77+
78+
res = await app.httpRequest()
79+
.get('/hello/other/world')
80+
.set('accept', 'text/html')
81+
.expect(200);
82+
assert.equal(res.headers['x-frame-options'], undefined);
7783

7884
res = await app4.httpRequest()
7985
.get('/hello')
8086
.set('accept', 'text/html')
8187
.expect(200);
82-
assert.equal(res.headers['X-Frame-Options'], undefined);
88+
assert.equal(res.headers['x-frame-options'], undefined);
8389

8490
res = await app.httpRequest()
8591
.get('/world/12')
8692
.set('accept', 'text/html')
8793
.expect(200);
88-
assert.equal(res.headers['X-Frame-Options'], undefined);
94+
assert.equal(res.headers['x-frame-options'], undefined);
8995

9096
res = await app.httpRequest()
9197
.get('/world/12?xx=xx')
9298
.set('accept', 'text/html')
9399
.expect(200);
94-
assert.equal(res.headers['X-Frame-Options'], undefined);
100+
assert.equal(res.headers['x-frame-options'], undefined);
95101

96102
res = await app2.httpRequest()
97103
.get('/hello')
98104
.set('accept', 'text/html')
99105
.expect(200);
100-
assert.equal(res.headers['X-Frame-Options'], undefined);
106+
assert.equal(res.headers['x-frame-options'], undefined);
101107

102108
res = await app2.httpRequest()
103109
.get('/world/12')
104110
.set('accept', 'text/html')
105111
.expect(200);
106-
assert.equal(res.headers['X-Frame-Options'], undefined);
112+
assert.equal(res.headers['x-frame-options'], undefined);
107113

108114
res = await app2.httpRequest()
109115
.get('/world/12?xx=xx')
110116
.set('accept', 'text/html')
111117
.expect(200);
112-
assert.equal(res.headers['X-Frame-Options'], undefined);
118+
assert.equal(res.headers['x-frame-options'], undefined);
113119
});
114120
});

0 commit comments

Comments
 (0)