Merge branch 'feature/hole' into 'release/3.1'
Feature/hole See merge request !28
Showing
19 changed files
with
137 additions
and
48 deletions
app/components/global/editor/editor-safe.vue
0 → 100644
1 | +<template> | ||
2 | + <editor :content="value" @change="change"></editor> | ||
3 | +</template> | ||
4 | + | ||
5 | +<script> | ||
6 | +import xss from 'util/xss'; | ||
7 | + | ||
8 | +export default { | ||
9 | + name: 'editor-safe', | ||
10 | + props: ['content'], | ||
11 | + data() { | ||
12 | + return { | ||
13 | + value: this.content | ||
14 | + }; | ||
15 | + }, | ||
16 | + methods: { | ||
17 | + change(val) { | ||
18 | + let currentVal = val; | ||
19 | + | ||
20 | + val = xss.replaceScript(val); | ||
21 | + this.$emit('change', val); | ||
22 | + if (currentVal !== val) { | ||
23 | + this.value = val; | ||
24 | + this.$Message.error('输入内容有敏感字符,已自动清除'); | ||
25 | + } | ||
26 | + } | ||
27 | + } | ||
28 | +}; | ||
29 | +</script> | ||
30 | + | ||
31 | +<style> | ||
32 | + | ||
33 | +</style> |
@@ -9,7 +9,7 @@ import LayoutTab from './layout-tab'; | @@ -9,7 +9,7 @@ import LayoutTab from './layout-tab'; | ||
9 | import LayoutFilter from './layout-filter'; | 9 | import LayoutFilter from './layout-filter'; |
10 | import LayoutPrint from './layout-print'; | 10 | import LayoutPrint from './layout-print'; |
11 | import ActionGroup from './action-group'; | 11 | import ActionGroup from './action-group'; |
12 | -import Editor from './editor'; | 12 | +import {Editor, EditorSafe} from './editor'; |
13 | import FileUpload from './file-upload'; | 13 | import FileUpload from './file-upload'; |
14 | import DragFileUpload from './drag-file-upload'; | 14 | import DragFileUpload from './drag-file-upload'; |
15 | import IFrame from './iframe'; | 15 | import IFrame from './iframe'; |
@@ -28,6 +28,7 @@ export default { | @@ -28,6 +28,7 @@ export default { | ||
28 | LayoutPrint, | 28 | LayoutPrint, |
29 | ActionGroup, | 29 | ActionGroup, |
30 | Editor, | 30 | Editor, |
31 | + EditorSafe, | ||
31 | FileUpload, | 32 | FileUpload, |
32 | DragFileUpload, | 33 | DragFileUpload, |
33 | IFrame, | 34 | IFrame, |
@@ -7,6 +7,7 @@ import Pop from './pop'; | @@ -7,6 +7,7 @@ import Pop from './pop'; | ||
7 | import Radio from './radio'; | 7 | import Radio from './radio'; |
8 | import Select from './select'; | 8 | import Select from './select'; |
9 | import Table from './table'; | 9 | import Table from './table'; |
10 | +import Input from './input'; | ||
10 | 11 | ||
11 | export default { | 12 | export default { |
12 | Cell, | 13 | Cell, |
@@ -17,5 +18,6 @@ export default { | @@ -17,5 +18,6 @@ export default { | ||
17 | Pop, | 18 | Pop, |
18 | Radio, | 19 | Radio, |
19 | Select, | 20 | Select, |
20 | - Table | 21 | + Table, |
22 | + Input | ||
21 | }; | 23 | }; |
app/components/input/index.js
0 → 100644
app/components/input/input-safe.vue
0 → 100644
1 | +<template> | ||
2 | + <Input :value="value" v-bind="$attrs" v-on="$listeners" /> | ||
3 | +</template> | ||
4 | + | ||
5 | +<script> | ||
6 | +import xss from 'util/xss'; | ||
7 | + | ||
8 | +export default { | ||
9 | + name: 'input-safe', | ||
10 | + props: ['value'], | ||
11 | + created() { | ||
12 | + this.$listeners.input = this.input; | ||
13 | + }, | ||
14 | + methods: { | ||
15 | + input(val) { | ||
16 | + if (typeof val === 'string') { | ||
17 | + this.value = xss.replaceIllegal(val); | ||
18 | + } else { | ||
19 | + this.value = val; | ||
20 | + } | ||
21 | + this.$emit('input', this.value); | ||
22 | + if (this.value !== val) { | ||
23 | + this.$Message.error('输入内容有敏感字符,已自动清除'); | ||
24 | + } | ||
25 | + } | ||
26 | + } | ||
27 | +}; | ||
28 | +</script> |
@@ -52,7 +52,7 @@ export default { | @@ -52,7 +52,7 @@ export default { | ||
52 | return <span>颜色展示名称</span>; | 52 | return <span>颜色展示名称</span>; |
53 | } | 53 | } |
54 | if (this.isExist(params.index)) { | 54 | if (this.isExist(params.index)) { |
55 | - return h('Input', { | 55 | + return h('input-safe', { |
56 | props: { | 56 | props: { |
57 | value: params.row.factoryGoodsName | 57 | value: params.row.factoryGoodsName |
58 | }, | 58 | }, |
@@ -109,11 +109,11 @@ export default { | @@ -109,11 +109,11 @@ export default { | ||
109 | 109 | ||
110 | if (this.isExist(params.index)) { | 110 | if (this.isExist(params.index)) { |
111 | return ( | 111 | return ( |
112 | - <i-input | 112 | + <input-safe |
113 | value={params.row.factoryCode} | 113 | value={params.row.factoryCode} |
114 | placeholder='请输入...' | 114 | placeholder='请输入...' |
115 | onInput={val => (params.row.factoryCode = val)} | 115 | onInput={val => (params.row.factoryCode = val)} |
116 | - style={{width: '100%'}}></i-input> | 116 | + style={{width: '100%'}}></input-safe> |
117 | ); | 117 | ); |
118 | } | 118 | } |
119 | return null; | 119 | return null; |
@@ -149,7 +149,7 @@ export default { | @@ -149,7 +149,7 @@ export default { | ||
149 | <div class={{'row-span': true}}> | 149 | <div class={{'row-span': true}}> |
150 | <div style={{position: 'relative'}}> | 150 | <div style={{position: 'relative'}}> |
151 | <div class={{'size-code-error': size.validate && !size.name}}> | 151 | <div class={{'size-code-error': size.validate && !size.name}}> |
152 | - <i-input | 152 | + <input-safe |
153 | value={size.name} | 153 | value={size.name} |
154 | onInput={val => (size.name = val)} | 154 | onInput={val => (size.name = val)} |
155 | disabled={!params.row.operator[i].value} | 155 | disabled={!params.row.operator[i].value} |
@@ -58,7 +58,9 @@ export default { | @@ -58,7 +58,9 @@ export default { | ||
58 | }; | 58 | }; |
59 | }, | 59 | }, |
60 | created() { | 60 | created() { |
61 | - this.isCaptcha = this.$cookie.get('_captcha'); | 61 | + this.isCaptcha = true; |
62 | + | ||
63 | + // this.isCaptcha = this.$cookie.get('_captcha'); | ||
62 | }, | 64 | }, |
63 | methods: { | 65 | methods: { |
64 | handleSubmit(name) { | 66 | handleSubmit(name) { |
@@ -16,15 +16,15 @@ | @@ -16,15 +16,15 @@ | ||
16 | <Form-item label="类目"> <span>{{sortName}}</span> </Form-item> | 16 | <Form-item label="类目"> <span>{{sortName}}</span> </Form-item> |
17 | 17 | ||
18 | <Form-item label="商品名称" prop="productName"> | 18 | <Form-item label="商品名称" prop="productName"> |
19 | - <Input v-model="product.productName" placeholder="请输入..." style="width: 400px;"/> | 19 | + <input-safe v-model="product.productName" placeholder="请输入..." style="width: 400px;"/> |
20 | </Form-item> | 20 | </Form-item> |
21 | 21 | ||
22 | <Form-item label="商品卖点"> | 22 | <Form-item label="商品卖点"> |
23 | - <Input v-model="product.phrase" :maxlength="12" placeholder="最多12个字符" style="width: 400px;"/> | 23 | + <input-safe v-model="product.phrase" :maxlength="12" placeholder="最多12个字符" style="width: 400px;"/> |
24 | </Form-item> | 24 | </Form-item> |
25 | 25 | ||
26 | <Form-item label="商家商品编码" prop="factoryCode"> | 26 | <Form-item label="商家商品编码" prop="factoryCode"> |
27 | - <Input v-model="product.factoryCode" placeholder="请输入..." style="width: 400px;"/> | 27 | + <input-safe v-model="product.factoryCode" placeholder="请输入..." style="width: 400px;"/> |
28 | </Form-item> | 28 | </Form-item> |
29 | 29 | ||
30 | <Form-item label="货品年" prop="goodsYears"> | 30 | <Form-item label="货品年" prop="goodsYears"> |
@@ -73,11 +73,11 @@ | @@ -73,11 +73,11 @@ | ||
73 | <Row> <div class="create-item-title">商品价格</div> </Row> | 73 | <Row> <div class="create-item-title">商品价格</div> </Row> |
74 | 74 | ||
75 | <Form-item label="吊牌价" prop="retailPrice"> | 75 | <Form-item label="吊牌价" prop="retailPrice"> |
76 | - <Input v-model="product.retailPrice" :number="true" placeholder="请输入..." style="width: 400px;"/> | 76 | + <input-safe v-model="product.retailPrice" :number="true" placeholder="请输入..." style="width: 400px;"/> |
77 | </Form-item> | 77 | </Form-item> |
78 | 78 | ||
79 | <Form-item label="销售价" prop="salesPrice"> | 79 | <Form-item label="销售价" prop="salesPrice"> |
80 | - <Input v-model="product.salesPrice" :number="true" placeholder="请输入..." style="width: 400px;"/> | 80 | + <input-safe v-model="product.salesPrice" :number="true" placeholder="请输入..." style="width: 400px;"/> |
81 | </Form-item> | 81 | </Form-item> |
82 | </Form> | 82 | </Form> |
83 | 83 |
@@ -118,7 +118,7 @@ | @@ -118,7 +118,7 @@ | ||
118 | 118 | ||
119 | <Row> | 119 | <Row> |
120 | <Col> | 120 | <Col> |
121 | - <editor :content="desc" :z-index="2" @change="updateProductDesc"></editor> | 121 | + <editor-safe :content="desc" :z-index="2" @change="updateProductDesc"></editor-safe> |
122 | </Col> | 122 | </Col> |
123 | </Row> | 123 | </Row> |
124 | 124 |
@@ -14,13 +14,13 @@ | @@ -14,13 +14,13 @@ | ||
14 | <span>{{product.smallSortName}}</span> | 14 | <span>{{product.smallSortName}}</span> |
15 | </Form-item> | 15 | </Form-item> |
16 | <Form-item label="商品名称" prop="productName"> | 16 | <Form-item label="商品名称" prop="productName"> |
17 | - <Input v-model="product.productName" placeholder="请输入..." /> | 17 | + <input-safe v-model="product.productName" placeholder="请输入..." /> |
18 | </Form-item> | 18 | </Form-item> |
19 | <Form-item label="商品卖点"> | 19 | <Form-item label="商品卖点"> |
20 | - <Input v-model="product.phrase" :maxlength="12" placeholder="最多12个字符"/> | 20 | + <input-safe v-model="product.phrase" :maxlength="12" placeholder="最多12个字符"/> |
21 | </Form-item> | 21 | </Form-item> |
22 | <Form-item label="商家商品编码" prop="factoryCode"> | 22 | <Form-item label="商家商品编码" prop="factoryCode"> |
23 | - <Input v-model="product.factoryCode" placeholder="请输入..." /> | 23 | + <input-safe v-model="product.factoryCode" placeholder="请输入..." /> |
24 | </Form-item> | 24 | </Form-item> |
25 | <Form-item label="货品年"> | 25 | <Form-item label="货品年"> |
26 | <Date-picker :value="product.goodsYears.toString()" type="year" placeholder="选择年" disabled> | 26 | <Date-picker :value="product.goodsYears.toString()" type="year" placeholder="选择年" disabled> |
@@ -62,10 +62,10 @@ | @@ -62,10 +62,10 @@ | ||
62 | </Form-item> | 62 | </Form-item> |
63 | <div class="create-item-title">商品价格</div> | 63 | <div class="create-item-title">商品价格</div> |
64 | <Form-item label="吊牌价"> | 64 | <Form-item label="吊牌价"> |
65 | - <Input v-model="product.retailPrice" disabled placeholder="请输入..." /> | 65 | + <input-safe v-model="product.retailPrice" disabled placeholder="请输入..." /> |
66 | </Form-item> | 66 | </Form-item> |
67 | <Form-item label="销售价"> | 67 | <Form-item label="销售价"> |
68 | - <Input v-model="product.salesPrice" disabled placeholder="请输入..." /> | 68 | + <input-safe v-model="product.salesPrice" disabled placeholder="请输入..." /> |
69 | </Form-item> | 69 | </Form-item> |
70 | <div class="create-group"> | 70 | <div class="create-group"> |
71 | <span class="create-group-indicator"></span> | 71 | <span class="create-group-indicator"></span> |
@@ -81,9 +81,9 @@ | @@ -81,9 +81,9 @@ | ||
81 | <div class="create-item-title">商品描述 | 81 | <div class="create-item-title">商品描述 |
82 | <span class="create-group-sub-title">(详情页内容)</span> | 82 | <span class="create-group-sub-title">(详情页内容)</span> |
83 | </div> | 83 | </div> |
84 | - <editor :content="product.productIntro" | 84 | + <editor-safe :content="product.productIntro" |
85 | @change="updateProductDesc" | 85 | @change="updateProductDesc" |
86 | - :z-index="2"></editor> | 86 | + :z-index="2"></editor-safe> |
87 | <div class="create-item-title">商品属性 | 87 | <div class="create-item-title">商品属性 |
88 | <span class="create-group-sub-title">(请认真选择所列的属性项,所填内容会对商品搜索、智能推荐等功能产生影响,从而影响商品曝光展示)</span> | 88 | <span class="create-group-sub-title">(请认真选择所列的属性项,所填内容会对商品搜索、智能推荐等功能产生影响,从而影响商品曝光展示)</span> |
89 | </div> | 89 | </div> |
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | 8 | ||
9 | <div style="text-align: center"> | 9 | <div style="text-align: center"> |
10 | <filter-item :label="'分类名称'"> | 10 | <filter-item :label="'分类名称'"> |
11 | - <Input v-model="name" @on-enter="submit"/> | 11 | + <input-safe v-model="name" @on-enter="submit"/> |
12 | </filter-item> | 12 | </filter-item> |
13 | </div> | 13 | </div> |
14 | 14 |
@@ -12,8 +12,12 @@ export default function() { | @@ -12,8 +12,12 @@ export default function() { | ||
12 | }, | 12 | }, |
13 | { | 13 | { |
14 | title: '分类名称', | 14 | title: '分类名称', |
15 | - key: 'categoryName', | ||
16 | align: 'center', | 15 | align: 'center', |
16 | + render(h, params) { | ||
17 | + return ( | ||
18 | + <span>{params.row.categoryName}</span> | ||
19 | + ); | ||
20 | + } | ||
17 | }, | 21 | }, |
18 | { | 22 | { |
19 | title: '创建时间', | 23 | title: '创建时间', |
@@ -24,8 +24,8 @@ | @@ -24,8 +24,8 @@ | ||
24 | <em class="upload-img-tip">尺寸要求150px*150px 不大于500KB</em> | 24 | <em class="upload-img-tip">尺寸要求150px*150px 不大于500KB</em> |
25 | </Form-item> | 25 | </Form-item> |
26 | <Form-item label="店铺简介:"> | 26 | <Form-item label="店铺简介:"> |
27 | - <editor :content="shopData.shopIntro" @change="updateData" :z-index="2"> | ||
28 | - </editor> | 27 | + <editor-safe :content="shopData.shopIntro" @change="updateData" :z-index="2"> |
28 | + </editor-safe> | ||
29 | </Form-item> | 29 | </Form-item> |
30 | <Form-item label="品牌-供应商:"> | 30 | <Form-item label="品牌-供应商:"> |
31 | <Table :columns="tableCols" width="700" :data="tableData"></Table> | 31 | <Table :columns="tableCols" width="700" :data="tableData"></Table> |
app/util/xss.js
0 → 100644
@@ -22,8 +22,8 @@ | @@ -22,8 +22,8 @@ | ||
22 | </div> | 22 | </div> |
23 | </Form-item> | 23 | </Form-item> |
24 | <Form-item label="简介:" prop="intro"> | 24 | <Form-item label="简介:" prop="intro"> |
25 | - <editor :content="modelData.intro" @change="editorChange" :z-index="2"> | ||
26 | - </editor> | 25 | + <editor-safe :content="modelData.intro" @change="editorChange" :z-index="2"> |
26 | + </editor-safe> | ||
27 | </Form-item> | 27 | </Form-item> |
28 | <Form-item> | 28 | <Form-item> |
29 | <Button type="primary" @click="submit">保存</Button> | 29 | <Button type="primary" @click="submit">保存</Button> |
@@ -27,28 +27,29 @@ class CaptchaController extends Context { | @@ -27,28 +27,29 @@ class CaptchaController extends Context { | ||
27 | return request(`${captcha.verifiedGraphicCode}?imageView2/0/format/jpg/q/70|watermark/2/text/${uuid.v4()}/fontsize/120/dissolve/10`).pipe(res); // eslint-disable-line | 27 | return request(`${captcha.verifiedGraphicCode}?imageView2/0/format/jpg/q/70|watermark/2/text/${uuid.v4()}/fontsize/120/dissolve/10`).pipe(res); // eslint-disable-line |
28 | } | 28 | } |
29 | check(req, res, next) { | 29 | check(req, res, next) { |
30 | - let isCaptcha = req.session.isCaptcha; | 30 | + // let isCaptcha = req.session.isCaptcha; |
31 | 31 | ||
32 | - if (isCaptcha) { | ||
33 | - if (req.body.captcha === req.session.captcha) { | ||
34 | - if (new Date().getTime() > req.session.captchaTimeout) { | ||
35 | - return res.json({ | ||
36 | - code: 400, | ||
37 | - captcha: true, | ||
38 | - expired: true, | ||
39 | - message: '验证码过期' | ||
40 | - }); | ||
41 | - } | ||
42 | - return next(); | ||
43 | - } else { | 32 | + // if (isCaptcha) { |
33 | + if (req.body.captcha === req.session.captcha) { | ||
34 | + if (new Date().getTime() > req.session.captchaTimeout) { | ||
44 | return res.json({ | 35 | return res.json({ |
45 | code: 400, | 36 | code: 400, |
46 | captcha: true, | 37 | captcha: true, |
47 | - message: '验证码错误' | 38 | + expired: true, |
39 | + message: '验证码过期' | ||
48 | }); | 40 | }); |
49 | } | 41 | } |
42 | + return next(); | ||
43 | + } else { | ||
44 | + return res.json({ | ||
45 | + code: 400, | ||
46 | + captcha: true, | ||
47 | + message: '验证码错误' | ||
48 | + }); | ||
50 | } | 49 | } |
51 | - return next(); | 50 | + |
51 | + // } | ||
52 | + // return next(); | ||
52 | } | 53 | } |
53 | } | 54 | } |
54 | 55 |
@@ -46,21 +46,21 @@ module.exports = (req, res, next) => { | @@ -46,21 +46,21 @@ module.exports = (req, res, next) => { | ||
46 | 46 | ||
47 | if (currentShop) { | 47 | if (currentShop) { |
48 | let baseParams = { | 48 | let baseParams = { |
49 | - pid: req.session.LOGIN_UID, | ||
50 | - founder: req.session.LOGIN_UID, | 49 | + pid: req.user.uid, |
50 | + founder: req.user.uid, | ||
51 | shopsId: currentShop.shopsId, | 51 | shopsId: currentShop.shopsId, |
52 | shopId: currentShop.shopsId, | 52 | shopId: currentShop.shopsId, |
53 | shop: currentShop.shopsId, | 53 | shop: currentShop.shopsId, |
54 | supplierId: currentShop.shopsBrands.length ? _.first(currentShop.shopsBrands).supplierId : 0, | 54 | supplierId: currentShop.shopsBrands.length ? _.first(currentShop.shopsBrands).supplierId : 0, |
55 | platform_id: config.platform, | 55 | platform_id: config.platform, |
56 | - userId: req.session.LOGIN_UID | 56 | + userId: req.user.uid |
57 | }; | 57 | }; |
58 | let reqParams = Object.assign({ | 58 | let reqParams = Object.assign({ |
59 | url: apiUrl, | 59 | url: apiUrl, |
60 | method: req.method.toLowerCase(), | 60 | method: req.method.toLowerCase(), |
61 | headers: { | 61 | headers: { |
62 | 'x-shop-id': currentShop.shopsId, | 62 | 'x-shop-id': currentShop.shopsId, |
63 | - 'x-user-id': req.session.LOGIN_UID, | 63 | + 'x-user-id': req.user.uid, |
64 | 'Content-Type': 'application/json' | 64 | 'Content-Type': 'application/json' |
65 | } | 65 | } |
66 | }); | 66 | }); |
@@ -71,7 +71,7 @@ module.exports = (req, res, next) => { | @@ -71,7 +71,7 @@ module.exports = (req, res, next) => { | ||
71 | } | 71 | } |
72 | 72 | ||
73 | if (req.method.toLowerCase() === 'get') { | 73 | if (req.method.toLowerCase() === 'get') { |
74 | - reqParams.qs = Object.assign(baseParams, req.query, req.body); | 74 | + reqParams.qs = Object.assign({}, req.query, req.body, baseParams); |
75 | } else if (files.length) { | 75 | } else if (files.length) { |
76 | let reqFiles = {}; | 76 | let reqFiles = {}; |
77 | 77 |
-
Please register or login to post a comment