Authored by 陈峰

Merge branch 'gray' into 'master'

Gray



See merge request !1460
Showing 45 changed files with 260 additions and 97 deletions
1 'use strict'; 1 'use strict';
2 2
  3 +const _ = require('lodash');
3 const semver = require('semver'); 4 const semver = require('semver');
4 const questionModel = require('../models/question'); 5 const questionModel = require('../models/question');
5 const headerModel = require('../../../doraemon/models/header'); // 头部model 6 const headerModel = require('../../../doraemon/models/header'); // 头部model
  7 +const geetest = require('../../passport/controllers/geetest');
6 8
7 exports.list = (req, res, next) => { 9 exports.list = (req, res, next) => {
8 let canShare = false; 10 let canShare = false;
@@ -47,6 +49,35 @@ exports.check = (req, res, next) => { @@ -47,6 +49,35 @@ exports.check = (req, res, next) => {
47 }).catch(next); 49 }).catch(next);
48 }; 50 };
49 51
  52 +exports.geetestLoad = (req, res, next) => {
  53 + req.yoho.captchaShow = false;
  54 + res.locals.useGeetest = true;
  55 +
  56 + if (_.has(res, 'locals.loadJsBefore')) {
  57 + res.locals.loadJsBefore.push({
  58 + src: global.yoho.config.geetestJs
  59 + });
  60 + } else {
  61 + res.locals.loadJsBefore = [
  62 + {
  63 + src: global.yoho.config.geetestJs
  64 + }
  65 + ];
  66 + }
  67 +
  68 + return next();
  69 +};
  70 +
  71 +exports.geetestCheck = (req, res, next) => {
  72 + let testCode = req.body.yohobuy;
  73 +
  74 + if (testCode === global.yoho.config.testCode) {
  75 + return next();
  76 + }
  77 +
  78 + return geetest.validate(req, res, next);
  79 +};
  80 +
50 exports.submit = (req, res, next) => { 81 exports.submit = (req, res, next) => {
51 let params = req.body; 82 let params = req.body;
52 83
@@ -66,11 +97,12 @@ exports.submit = (req, res, next) => { @@ -66,11 +97,12 @@ exports.submit = (req, res, next) => {
66 }).catch(next); 97 }).catch(next);
67 }; 98 };
68 99
69 -  
70 -  
71 exports.detail = (req, res, next) => { 100 exports.detail = (req, res, next) => {
72 let id = parseInt(`0${req.params.id}`, 10); 101 let id = parseInt(`0${req.params.id}`, 10);
73 102
  103 + req.yoho.captchaShow = false;
  104 + res.locals.useGeetest = true;
  105 +
74 req.ctx(questionModel).getQuestionDetail(id, req.user.uid).then(result => { 106 req.ctx(questionModel).getQuestionDetail(id, req.user.uid).then(result => {
75 if (result && result.detail && req.yoho.isApp) { 107 if (result && result.detail && req.yoho.isApp) {
76 result.detail.uid = req.user.uid; 108 result.detail.uid = req.user.uid;
@@ -64,7 +64,7 @@ const keywordsPage = (page) => { @@ -64,7 +64,7 @@ const keywordsPage = (page) => {
64 }); 64 });
65 }); 65 });
66 return pages; 66 return pages;
67 - }).timeout(200).catch(()=>{ 67 + }).catch(()=>{
68 return {}; 68 return {};
69 }); 69 });
70 }; 70 };
@@ -25,8 +25,8 @@ router.post('/check/submit', check.submit); @@ -25,8 +25,8 @@ router.post('/check/submit', check.submit);
25 25
26 router.get('/questionnaire', auth, question.list); 26 router.get('/questionnaire', auth, question.list);
27 router.post('/questionnaire/check', question.check); 27 router.post('/questionnaire/check', question.check);
28 -router.post('/questionnaire/submit', question.submit);  
29 -router.get('/questionnaire/:id', question.detail); 28 +router.post('/questionnaire/submit', question.geetestCheck, question.submit);
  29 +router.get('/questionnaire/:id', question.geetestLoad, question.detail);
30 router.get('/material', auth, materialNew.list); 30 router.get('/material', auth, materialNew.list);
31 31
32 module.exports = router; 32 module.exports = router;
@@ -51,4 +51,6 @@ @@ -51,4 +51,6 @@
51 </div> 51 </div>
52 </div> 52 </div>
53 </div> 53 </div>
  54 +
  55 + <div data-userverify="{{captchaShow}}" data-geetest="{{useGeetest}}" id="js-img-check" {{#unless useGeetest}} class="full-img-verify" {{/unless}}></div>
54 </div> 56 </div>
1 <div class="friend-invite-page yoho-page"> 1 <div class="friend-invite-page yoho-page">
2 {{# friendInviteData}} 2 {{# friendInviteData}}
3 <div class="banner"> 3 <div class="banner">
4 - <span class="title">您的好友{{nickname}}<br><b>{{#if payText}}发现了好物并推荐给您{{else}}邀请您来有货玩潮流{{/if}}</b></span> 4 + <span class="title">您的好友{{{nickname}}}<br><b>{{#if payText}}发现了好物并推荐给您{{else}}邀请您来有货玩潮流{{/if}}</b></span>
5 <span class="ico-left"></span> 5 <span class="ico-left"></span>
6 <span class="ico-right"></span> 6 <span class="ico-right"></span>
7 {{#if friendsGoods}} 7 {{#if friendsGoods}}
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 <div class="reward-related"> 22 <div class="reward-related">
23 <div class="releated-item"> 23 <div class="releated-item">
24 <span>我邀请的好友</span> 24 <span>我邀请的好友</span>
25 - <span>{{nickName}}</span> 25 + <span>{{{nickName}}}</span>
26 </div> 26 </div>
27 <div class="releated-item"> 27 <div class="releated-item">
28 <span>注册时间</span> 28 <span>注册时间</span>
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 <div class="head-pic"> 9 <div class="head-pic">
10 <img src="{{image headIco 200 200}}"> 10 <img src="{{image headIco 200 200}}">
11 </div> 11 </div>
12 - <div class="nick-name">{{nickName}}</div> 12 + <div class="nick-name">{{{nickName}}}</div>
13 </div> 13 </div>
14 <div class="calculate"> 14 <div class="calculate">
15 <div class="calculate-item"> 15 <div class="calculate-item">
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 {{# shareLog}} 42 {{# shareLog}}
43 <div class="student-item"> 43 <div class="student-item">
44 <div>{{createTime}}</div> 44 <div>{{createTime}}</div>
45 - <div>{{nickName}}</div> 45 + <div>{{{nickName}}}</div>
46 <div> 46 <div>
47 <span>+{{reward}}</span> 47 <span>+{{reward}}</span>
48 有货币 48 有货币
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 <li> 27 <li>
28 <p class="earnings-info"> 28 <p class="earnings-info">
29 <span class="num">{{#if cancel}}-{{/if}}{{#if already}}+{{/if}}{{coinNum}}</span> 29 <span class="num">{{#if cancel}}-{{/if}}{{#if already}}+{{/if}}{{coinNum}}</span>
30 - <span class="user">{{nickName}} <i {{#if cancel}}class="cancel"{{/if}}>{{statusStr}}</i></span> 30 + <span class="user">{{{nickName}}} <i {{#if cancel}}class="cancel"{{/if}}>{{statusStr}}</i></span>
31 31
32 </p> 32 </p>
33 <p class="order-info"> 33 <p class="order-info">
1 {{# rewardList}} 1 {{# rewardList}}
2 <a href="{{detailUrl}}" class="list-item"> 2 <a href="{{detailUrl}}" class="list-item">
3 - <span>{{nickName}}</span> 3 + <span>{{{nickName}}}</span>
4 <span>{{orderAmountDis}}</span> 4 <span>{{orderAmountDis}}</span>
5 <span>{{couponName}}</span> 5 <span>{{couponName}}</span>
6 <span>{{couponStatusDesc}}<i class="iconfont">&#xe614;</i></span> 6 <span>{{couponStatusDesc}}<i class="iconfont">&#xe614;</i></span>
@@ -10,6 +10,7 @@ const router = require('express').Router(); //eslint-disable-line @@ -10,6 +10,7 @@ const router = require('express').Router(); //eslint-disable-line
10 const cRoot = './controllers'; 10 const cRoot = './controllers';
11 const authMW = require('../../doraemon/middleware/auth'); 11 const authMW = require('../../doraemon/middleware/auth');
12 const disableBFCache = require('../../doraemon/middleware/disable-BFCache'); 12 const disableBFCache = require('../../doraemon/middleware/disable-BFCache');
  13 +const csrf = require('../../doraemon/middleware/csrf');
13 const seckill = require(cRoot + '/seckill'); 14 const seckill = require(cRoot + '/seckill');
14 const order = require(cRoot + '/order'); 15 const order = require(cRoot + '/order');
15 const countController = require(`${cRoot}/count`); 16 const countController = require(`${cRoot}/count`);
@@ -41,7 +42,7 @@ router.post('/index/new/orderSub', authMW, order.orderSub); // 订单提交 @@ -41,7 +42,7 @@ router.post('/index/new/orderSub', authMW, order.orderSub); // 订单提交
41 router.get('/index/new/selectCoupon', authMW, order.selectCouponsPage); // 选择优惠券 页面 New! 42 router.get('/index/new/selectCoupon', authMW, order.selectCouponsPage); // 选择优惠券 页面 New!
42 router.post('/index/new/couponList', order.couponList); // [ajax]获取优惠券列表 43 router.post('/index/new/couponList', order.couponList); // [ajax]获取优惠券列表
43 router.post('/index/new/useCouponCode', order.useCouponCode); // [ajax]购物车输入优惠券码使用优惠券 44 router.post('/index/new/useCouponCode', order.useCouponCode); // [ajax]购物车输入优惠券码使用优惠券
44 -router.get('/index/new/selectAddress', authMW, order.selectAddress); // 选择地址 45 +router.get('/index/new/selectAddress', authMW, csrf, order.selectAddress); // 选择地址
45 router.get('/index/new/invoiceInfo', authMW, order.invoiceInfo); // 发票信息 46 router.get('/index/new/invoiceInfo', authMW, order.invoiceInfo); // 发票信息
46 router.get('/index/new/jitDetail', authMW, order.jitDetail); // JIT 拆单配送信息 47 router.get('/index/new/jitDetail', authMW, order.jitDetail); // JIT 拆单配送信息
47 router.get('/index/new/selectGiftcard', authMW, order.selectGiftcard); // 选择礼品卡页面 48 router.get('/index/new/selectGiftcard', authMW, order.selectGiftcard); // 选择礼品卡页面
@@ -9,9 +9,9 @@ @@ -9,9 +9,9 @@
9 {{#if addressInfo}} 9 {{#if addressInfo}}
10 <div class="address block address-wrap {{#if @root.pageChannel.boys}} boys{{/if}}{{#if @root.pageChannel.girls}} girls{{/if}}{{#if @root.pageChannel.kids}} kids{{/if}}{{#if @root.pageChannel.lifeStyle}} life-style{{/if}}" data-id ="{{addressId}}"> 10 <div class="address block address-wrap {{#if @root.pageChannel.boys}} boys{{/if}}{{#if @root.pageChannel.girls}} girls{{/if}}{{#if @root.pageChannel.kids}} kids{{/if}}{{#if @root.pageChannel.lifeStyle}} life-style{{/if}}" data-id ="{{addressId}}">
11 <div class="info"> 11 <div class="info">
12 - <span class="info-name">{{name}}</span> 12 + <span class="info-name">{{{name}}}</span>
13 <span class="info-phone">{{phoneNum}}</span> 13 <span class="info-phone">{{phoneNum}}</span>
14 - <a href="{{selectAddressUrl}}"><span class="info-address">{{addressInfo}}</span></a> 14 + <a href="{{selectAddressUrl}}"><span class="info-address">{{{addressInfo}}}</span></a>
15 <i class="iconfont">&#xe637;</i> 15 <i class="iconfont">&#xe637;</i>
16 </div> 16 </div>
17 <a class="rest" href="{{selectAddressUrl}}">其他地址<span class="iconfont">&#xe614;</span></a> 17 <a class="rest" href="{{selectAddressUrl}}">其他地址<span class="iconfont">&#xe614;</span></a>
@@ -177,7 +177,7 @@ @@ -177,7 +177,7 @@
177 {{#if addressInfo}} 177 {{#if addressInfo}}
178 <div class="address-bottom"> 178 <div class="address-bottom">
179 <div class="back"></div> 179 <div class="back"></div>
180 - <span>送至:{{addressInfo}}</span> 180 + <span>送至:{{{addressInfo}}}</span>
181 </div> 181 </div>
182 {{/if}} 182 {{/if}}
183 <div class="bill"> 183 <div class="bill">
@@ -2,9 +2,9 @@ @@ -2,9 +2,9 @@
2 <div class="page-wrap clearfix"> 2 <div class="page-wrap clearfix">
3 {{# address}} 3 {{# address}}
4 <div class="address-item" data-address-id="{{address_id}}" data-is-support="{{is_support}}" data-href="{{../moreUrl}}"> 4 <div class="address-item" data-address-id="{{address_id}}" data-is-support="{{is_support}}" data-href="{{../moreUrl}}">
5 - <span class="name">{{consignee}}</span> 5 + <span class="name">{{{consignee}}}</span>
6 <span class="tel">{{mobile}}</span> 6 <span class="tel">{{mobile}}</span>
7 - <p class="address-info">{{area}} {{address}}</p> 7 + <p class="address-info">{{area}} {{{address}}}</p>
8 <div class="action iconfont"> 8 <div class="action iconfont">
9 <span class="edit" data-href="/home/addressAct?id={{address_id}}&refer=buynow&product_sku={{../product_sku}}&buy_number={{../buy_number}}">&#xe61e;</span> 9 <span class="edit" data-href="/home/addressAct?id={{address_id}}&refer=buynow&product_sku={{../product_sku}}&buy_number={{../buy_number}}">&#xe61e;</span>
10 <span class="del" data-id="{{address_id}}">&#xe621;</span> 10 <span class="del" data-id="{{address_id}}">&#xe621;</span>
@@ -9,9 +9,9 @@ @@ -9,9 +9,9 @@
9 {{#if addressInfo}} 9 {{#if addressInfo}}
10 <div class="address block address-wrap {{#if @root.pageChannel.boys}} boys{{/if}}{{#if @root.pageChannel.girls}} girls{{/if}}{{#if @root.pageChannel.kids}} kids{{/if}}{{#if @root.pageChannel.lifeStyle}} life-style{{/if}}" data-id ="{{addressId}}"> 10 <div class="address block address-wrap {{#if @root.pageChannel.boys}} boys{{/if}}{{#if @root.pageChannel.girls}} girls{{/if}}{{#if @root.pageChannel.kids}} kids{{/if}}{{#if @root.pageChannel.lifeStyle}} life-style{{/if}}" data-id ="{{addressId}}">
11 <div class="info"> 11 <div class="info">
12 - <span class="info-name">{{name}}</span> 12 + <span class="info-name">{{{name}}}</span>
13 <span class="info-phone">{{phoneNum}}</span> 13 <span class="info-phone">{{phoneNum}}</span>
14 - <a href="/cart/index/new/selectAddress"><span class="info-address">{{addressInfo}}</span></a> 14 + <a href="/cart/index/new/selectAddress"><span class="info-address">{{{addressInfo}}}</span></a>
15 <i class="iconfont">&#xe637;</i> 15 <i class="iconfont">&#xe637;</i>
16 </div> 16 </div>
17 <a class="rest" href="/cart/index/new/selectAddress">其他地址<span class="iconfont">&#xe614;</span></a> 17 <a class="rest" href="/cart/index/new/selectAddress">其他地址<span class="iconfont">&#xe614;</span></a>
@@ -182,7 +182,7 @@ @@ -182,7 +182,7 @@
182 {{#if addressInfo}} 182 {{#if addressInfo}}
183 <div class="address-bottom"> 183 <div class="address-bottom">
184 <div class="back"></div> 184 <div class="back"></div>
185 - <span>送至:{{addressInfo}}</span> 185 + <span>送至:{{{addressInfo}}}</span>
186 </div> 186 </div>
187 {{/if}} 187 {{/if}}
188 <div class="bill"> 188 <div class="bill">
1 <div class="my-address-page select-address-page yoho-page"> 1 <div class="my-address-page select-address-page yoho-page">
2 <div class="page-wrap clearfix"> 2 <div class="page-wrap clearfix">
3 {{# address}} 3 {{# address}}
  4 + <input type="hidden" name="_csrf" value="{{@root.csrfToken}}"/>
4 <div class="address-item" data-address-id="{{address_id}}" data-is-support="{{is_support}}" data-href="{{../moreUrl}}"> 5 <div class="address-item" data-address-id="{{address_id}}" data-is-support="{{is_support}}" data-href="{{../moreUrl}}">
5 - <span class="name">{{consignee}}</span> 6 + <span class="name">{{{consignee}}}</span>
6 <span class="tel">{{mobile}}</span> 7 <span class="tel">{{mobile}}</span>
7 - <p class="address-info">{{area}} {{address}}</p> 8 + <p class="address-info" data-address="{{area}} {{address}}">{{area}} {{{address}}}</p>
8 <div class="action iconfont"> 9 <div class="action iconfont">
9 <span class="edit" data-href="/home/addressAct?id={{address_id}}&refer=shopping">&#xe61e;</span> 10 <span class="edit" data-href="/home/addressAct?id={{address_id}}&refer=shopping">&#xe61e;</span>
10 <span class="del" data-id="{{address_id}}">&#xe621;</span> 11 <span class="del" data-id="{{address_id}}">&#xe621;</span>
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 const mRoot = '../models'; 9 const mRoot = '../models';
10 const headerModel = require('../../../doraemon/models/header'); // 头部model 10 const headerModel = require('../../../doraemon/models/header'); // 头部model
11 const addressModel = require(`${mRoot}/address`); // 地址管理 MODEL 11 const addressModel = require(`${mRoot}/address`); // 地址管理 MODEL
  12 +const cleanHtml = require('../../../utils/cleanHtml');
12 13
13 /** 14 /**
14 * 地址管理页面 15 * 地址管理页面
@@ -135,7 +136,7 @@ exports.saveAddress = (req, res, next) => { @@ -135,7 +136,7 @@ exports.saveAddress = (req, res, next) => {
135 uid: req.user.uid, 136 uid: req.user.uid,
136 address: req.body.address, 137 address: req.body.address,
137 area_code: req.body.area_code, 138 area_code: req.body.area_code,
138 - consignee: req.body.consignee, 139 + consignee: cleanHtml.htmlEncode(req.body.consignee),
139 email: req.body.email, 140 email: req.body.email,
140 id: req.body.id, 141 id: req.body.id,
141 mobile: req.body.mobile, 142 mobile: req.body.mobile,
@@ -11,6 +11,7 @@ const express = require('express'); @@ -11,6 +11,7 @@ const express = require('express');
11 const router = express.Router(); // eslint-disable-line 11 const router = express.Router(); // eslint-disable-line
12 const auth = require('../../doraemon/middleware/auth'); 12 const auth = require('../../doraemon/middleware/auth');
13 const disableBFCache = require('../../doraemon/middleware/disable-BFCache'); 13 const disableBFCache = require('../../doraemon/middleware/disable-BFCache');
  14 +const csrf = require('../../doraemon/middleware/csrf');
14 15
15 const cRoot = './controllers'; 16 const cRoot = './controllers';
16 const installment = require(cRoot + '/installment'); 17 const installment = require(cRoot + '/installment');
@@ -49,12 +50,12 @@ router.get('/QRcode/:id', personalController.QRcode); @@ -49,12 +50,12 @@ router.get('/QRcode/:id', personalController.QRcode);
49 router.get('/user/qrcode', auth, newQrcode.index); 50 router.get('/user/qrcode', auth, newQrcode.index);
50 51
51 /* 个人中心地址管理相关路由 */ 52 /* 个人中心地址管理相关路由 */
52 -router.get('/address', auth, addressController.address); // 地址管理页面  
53 -router.get('/addressAct', auth, addressController.addressAct); // 地址添加页面  
54 -router.get('/addressAct/:id', auth, addressController.addressAct); // 地址添加修改页面  
55 -router.post('/saveAddress', addressController.saveAddress); // 新增或者保存地址 53 +router.get('/address', auth, csrf, addressController.address); // 地址管理页面
  54 +router.get('/addressAct', auth, csrf, addressController.addressAct); // 地址添加页面
  55 +router.get('/addressAct/:id', auth, csrf, addressController.addressAct); // 地址添加修改页面
  56 +router.post('/saveAddress', csrf, addressController.saveAddress); // 新增或者保存地址
56 router.post('/defaultAddress', addressController.defaultAddress); // 设置默认地址 57 router.post('/defaultAddress', addressController.defaultAddress); // 设置默认地址
57 -router.post('/delAddress', addressController.delAddress); // 删除地址 58 +router.post('/delAddress', csrf, addressController.delAddress); // 删除地址
58 router.get('/locationList', auth, addressController.locationList); // 异步获取三级地址数据 59 router.get('/locationList', auth, addressController.locationList); // 异步获取三级地址数据
59 router.get('/addressModify', auth, addressController.addressModify); // 订单详情地址列表 60 router.get('/addressModify', auth, addressController.addressModify); // 订单详情地址列表
60 router.get('/chooseAddress', auth, addressController.chooseAddress); // 订单详情地址修改 61 router.get('/chooseAddress', auth, addressController.chooseAddress); // 订单详情地址修改
@@ -69,8 +70,8 @@ router.get('/delOrder', auth, orderDetailController.delOrder); // 删除订单 @@ -69,8 +70,8 @@ router.get('/delOrder', auth, orderDetailController.delOrder); // 删除订单
69 router.get('/readd', auth, orderDetailController.readdData); // 再次购买 70 router.get('/readd', auth, orderDetailController.readdData); // 再次购买
70 router.get('/cancelOrder', auth, orderDetailController.cancelOrder); // 取消订单 71 router.get('/cancelOrder', auth, orderDetailController.cancelOrder); // 取消订单
71 router.get('/refundApply', auth, orderDetailController.refundApply); // 申请退款 72 router.get('/refundApply', auth, orderDetailController.refundApply); // 申请退款
72 -router.get('/orders/addressModify', auth, orderDetailController.addressModify); // 订单详情地址修改页面  
73 -router.post('/orders/changeAddress', orderDetailController.changeAddress); // 提交新的地址数据 73 +router.get('/orders/addressModify', auth, csrf, orderDetailController.addressModify); // 订单详情地址修改页面
  74 +router.post('/orders/changeAddress', csrf, orderDetailController.changeAddress); // 提交新的地址数据
74 router.post('/orders/sure', auth, orderController.sure); // 确认收货 75 router.post('/orders/sure', auth, orderController.sure); // 确认收货
75 76
76 77
@@ -2,10 +2,11 @@ @@ -2,10 +2,11 @@
2 <div class="tip">为提高配送时效,请您尽量准确填写四级地址。</div> 2 <div class="tip">为提高配送时效,请您尽量准确填写四级地址。</div>
3 <div class="my-edit-address-page page-wrap"> 3 <div class="my-edit-address-page page-wrap">
4 <form class="edit-address"> 4 <form class="edit-address">
  5 + <input type="hidden" name="_csrf" value="{{@root.csrfToken}}" />
5 <input type="hidden" name="id" value="{{address.addressId}}"> 6 <input type="hidden" name="id" value="{{address.addressId}}">
6 <label class="username"> 7 <label class="username">
7 收 货 人 : 8 收 货 人 :
8 - <input type="text" name="consignee" maxlength="21" value="{{address.consignee}}"> 9 + <input type="text" name="consignee" maxlength="21" value="{{{address.consignee}}}">
9 </label> 10 </label>
10 <label class="mobile"> 11 <label class="mobile">
11 联系电话: 12 联系电话:
@@ -19,7 +20,7 @@ @@ -19,7 +20,7 @@
19 </label> 20 </label>
20 <label class="address"> 21 <label class="address">
21 详细地址: 22 详细地址:
22 - <textarea name="address" maxlength="255">{{address.address}}</textarea> 23 + <textarea name="address" maxlength="255">{{{address.address}}}</textarea>
23 </label> 24 </label>
24 </form> 25 </form>
25 <div class="submit"> 26 <div class="submit">
@@ -2,9 +2,9 @@ @@ -2,9 +2,9 @@
2 <div class="page-wrap clearfix modifyAdd" data-rel="{{relation}}" data-order-code="{{orderCode}}"> 2 <div class="page-wrap clearfix modifyAdd" data-rel="{{relation}}" data-order-code="{{orderCode}}">
3 {{# address}} 3 {{# address}}
4 <div class="address-item" data-address-id="{{addressId}}" > 4 <div class="address-item" data-address-id="{{addressId}}" >
5 - <span class="name">{{consignee}}</span> 5 + <span class="name">{{{consignee}}}</span>
6 <span class="tel">{{mobile}}</span> 6 <span class="tel">{{mobile}}</span>
7 - <p class="address-info">{{area}} {{address}}</p> 7 + <p class="address-info">{{area}} {{{address}}}</p>
8 </div> 8 </div>
9 {{/ address}} 9 {{/ address}}
10 10
1 <div class="my-address-page yoho-page"> 1 <div class="my-address-page yoho-page">
2 <div class="page-wrap"> 2 <div class="page-wrap">
3 {{# address}} 3 {{# address}}
  4 + <input type="hidden" name="_csrf" value="{{@root.csrfToken}}"/>
4 <div class="address-item"> 5 <div class="address-item">
5 - <span class="name">{{consignee}}</span> 6 + <span class="name">{{{consignee}}}</span>
6 <span class="tel">{{mobile}}</span> 7 <span class="tel">{{mobile}}</span>
7 - <p class="address-info">{{area}} {{address}}</p> 8 + <p class="address-info">{{area}} {{{address}}}</p>
8 <div class="action iconfont"> 9 <div class="action iconfont">
9 <a class="edit" href="/home/addressAct?id={{addressId}}">&#xe61e;</a> 10 <a class="edit" href="/home/addressAct?id={{addressId}}">&#xe61e;</a>
10 <span class="del" data-id="{{addressId}}">&#xe621;</span> 11 <span class="del" data-id="{{addressId}}">&#xe621;</span>
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 <div class="person-detail"> 8 <div class="person-detail">
9 <a href='{{userInfoLink}}' class="user-avatar" data-avatar="{{image head_ico 80 80}}"></a> 9 <a href='{{userInfoLink}}' class="user-avatar" data-avatar="{{image head_ico 80 80}}"></a>
10 <div class="basic-info"> 10 <div class="basic-info">
11 - <span class="user-name">{{nickname}}</span> 11 + <span class="user-name">{{{nickname}}}</span>
12 <span class="gender {{#isEqualOr gender 1}}boy{{/isEqualOr}}{{#isEqualOr gender 2}}girl{{/isEqualOr}}"></span> 12 <span class="gender {{#isEqualOr gender 1}}boy{{/isEqualOr}}{{#isEqualOr gender 2}}girl{{/isEqualOr}}"></span>
13 </div> 13 </div>
14 <div class="info"> 14 <div class="info">
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 <div class="list-item"> 14 <div class="list-item">
15 <div class="title">昵称</div> 15 <div class="title">昵称</div>
16 <div class="main"> 16 <div class="main">
17 - <input class="inp nick-name modify" type="text" value="{{nickName}}" /> 17 + <input class="inp nick-name modify" type="text" value="{{{nickName}}}" />
18 </div> 18 </div>
19 <div class="arr"> 19 <div class="arr">
20 <span class="iconfont">&#xe604;</span> 20 <span class="iconfont">&#xe604;</span>
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 <div class="level level-{{vip_info/cur_level}}"></div> 8 <div class="level level-{{vip_info/cur_level}}"></div>
9 </div> 9 </div>
10 <div class="right"> 10 <div class="right">
11 - <div class="name eps">{{nickname}}</div> 11 + <div class="name eps">{{{nickname}}}</div>
12 <div class="trend-code-c"> 12 <div class="trend-code-c">
13 <div class="dot">#&nbsp;</div> 13 <div class="dot">#&nbsp;</div>
14 <div class="scroll-c go-scroll"> 14 <div class="scroll-c go-scroll">
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <div class="level level-{{vip_info/cur_level}}"></div> 6 <div class="level level-{{vip_info/cur_level}}"></div>
7 </div> 7 </div>
8 <div class="user-info"> 8 <div class="user-info">
9 - <div class="name eps">{{nickname}}</div> 9 + <div class="name eps">{{{nickname}}}</div>
10 <div class="passcode"> 10 <div class="passcode">
11 {{#if trendWord}} 11 {{#if trendWord}}
12 <div class="dot">#&nbsp;</div> 12 <div class="dot">#&nbsp;</div>
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <form class="form edit-address" id="areaForm"> 6 <form class="form edit-address" id="areaForm">
7 <div class="form-group"> 7 <div class="form-group">
8 <label for="username">收货人:</label> 8 <label for="username">收货人:</label>
9 - <input name="username" type="text" maxlength="21" value="{{consignee}}"> 9 + <input name="username" type="text" maxlength="21" value="{{{consignee}}}">
10 </div> 10 </div>
11 <div class="form-group"> 11 <div class="form-group">
12 <label for="mobile">联系电话:</label> 12 <label for="mobile">联系电话:</label>
@@ -26,9 +26,10 @@ @@ -26,9 +26,10 @@
26 </div> 26 </div>
27 <div class="form-group"> 27 <div class="form-group">
28 <label for="address" class="label-address">详细地址:</label> 28 <label for="address" class="label-address">详细地址:</label>
29 - <textarea name="address" type="text" value="" maxlength="255">{{address}}</textarea> 29 + <textarea name="address" type="text" value="" maxlength="255">{{{address}}}</textarea>
30 </div> 30 </div>
31 <input type="hidden" name="orderCode" value="{{orderCode}}"> 31 <input type="hidden" name="orderCode" value="{{orderCode}}">
  32 + <input type="hidden" name="_csrf" value="{{@root.csrfToken}}">
32 </form> 33 </form>
33 <div class="tip"><span class="iconfont icon-info"></span>修改地址仅可修改一次,且会影响送货时间,请您谅解!</div> 34 <div class="tip"><span class="iconfont icon-info"></span>修改地址仅可修改一次,且会影响送货时间,请您谅解!</div>
34 <div class="btn-sure-line"> 35 <div class="btn-sure-line">
@@ -32,11 +32,11 @@ @@ -32,11 +32,11 @@
32 <span class="iconfont">&#xe637;</span> 32 <span class="iconfont">&#xe637;</span>
33 <div class="beside-icon"> 33 <div class="beside-icon">
34 <p class="name-phone"> 34 <p class="name-phone">
35 - {{deliveryInfo.userName}} 35 + {{{deliveryInfo.userName}}}
36 <span>{{deliveryInfo.mobile}}</span> 36 <span>{{deliveryInfo.mobile}}</span>
37 </p> 37 </p>
38 <p class="address"> 38 <p class="address">
39 - {{addressAll}} 39 + {{{addressAll}}}
40 </p> 40 </p>
41 </div> 41 </div>
42 </section> 42 </section>
1 <div class="personal-details yoho-page"> 1 <div class="personal-details yoho-page">
2 <ul> 2 <ul>
3 <li><span>头像</span><span><i class="head-portrait user-avatar" data-avatar="{{image head_ico 128 128}}"></i></span></li> 3 <li><span>头像</span><span><i class="head-portrait user-avatar" data-avatar="{{image head_ico 128 128}}"></i></span></li>
4 - <li><span>昵称</span><span>{{ nickname }}</span></li> 4 + <li><span>昵称</span><span>{{{ nickname }}}</span></li>
5 <li><span>性别</span><span>{{ gender }}</span></li> 5 <li><span>性别</span><span>{{ gender }}</span></li>
6 <li><span>生日</span><span>{{ birthday }}</span></li> 6 <li><span>生日</span><span>{{ birthday }}</span></li>
7 </ul> 7 </ul>
1 {{#if vip3}} 1 {{#if vip3}}
2 <p> 2 <p>
3 - <span class="user-name">{{name}}</span> 3 + <span class="user-name">{{{name}}}</span>
4 <span class="vip-icon vip-3"></span> 4 <span class="vip-icon vip-3"></span>
5 </p> 5 </p>
6 <p class="grade-desc"> 6 <p class="grade-desc">
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 20
21 {{#if vip2}} 21 {{#if vip2}}
22 <p> 22 <p>
23 - <span class="user-name">{{name}}</span> 23 + <span class="user-name">{{{name}}}</span>
24 <span class="vip-icon vip-2"></span> 24 <span class="vip-icon vip-2"></span>
25 </p> 25 </p>
26 <p class="grade-desc"> 26 <p class="grade-desc">
@@ -43,7 +43,7 @@ @@ -43,7 +43,7 @@
43 43
44 {{#if vip1}} 44 {{#if vip1}}
45 <p> 45 <p>
46 - <span class="user-name">{{name}}</span> 46 + <span class="user-name">{{{name}}}</span>
47 <span class="vip-icon vip-1"></span> 47 <span class="vip-icon vip-1"></span>
48 </p> 48 </p>
49 <p class="grade-desc"> 49 <p class="grade-desc">
@@ -66,7 +66,7 @@ @@ -66,7 +66,7 @@
66 66
67 {{#if vip0}} 67 {{#if vip0}}
68 <p> 68 <p>
69 - <span class="user-name">{{name}}</span> 69 + <span class="user-name">{{{name}}}</span>
70 <span>普通会员</span> 70 <span>普通会员</span>
71 </p> 71 </p>
72 <p class="grade-desc"> 72 <p class="grade-desc">
@@ -203,11 +203,14 @@ const shop = { @@ -203,11 +203,14 @@ const shop = {
203 _getMiniAppPath(req, brands, shopId) { 203 _getMiniAppPath(req, brands, shopId) {
204 let minis = {}; 204 let minis = {};
205 205
206 - // param:品牌ID|店铺ID, name:品牌名称, miniQrType 7:商品,2:品牌,3:店铺,miniapp_type 0:有货,1:新与力 206 + // param:品牌ID|店铺ID, name:品牌名称, miniQrType 7:商品,2:品牌,10:店铺,miniapp_type 0:有货,1:新与力
207 if (shopId) { 207 if (shopId) {
208 minis = Object.assign(minis, { 208 minis = Object.assign(minis, {
209 - param: shopId,  
210 - miniQrType: 3 209 + param: JSON.stringify({
  210 + shopId: shopId,
  211 + union_type: req.query.union_type || req.cookies.unionTypeYas || '',
  212 + }),
  213 + miniQrType: 10
211 }); 214 });
212 } else if (!brands || brands.length !== 1) { 215 } else if (!brands || brands.length !== 1) {
213 minis = Object.assign(minis, { 216 minis = Object.assign(minis, {
@@ -71,7 +71,7 @@ const newGoods = (req, res, next) => { @@ -71,7 +71,7 @@ const newGoods = (req, res, next) => {
71 }); 71 });
72 72
73 // 唤起 APP 的路径 73 // 唤起 APP 的路径
74 - res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.new","params":${JSON.stringify(appParams)}}`; 74 + res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.new","params":${encodeURIComponent(JSON.stringify(appParams))}}`;
75 75
76 let seoTitle = '【潮流新品】_引领潮流_2018时尚潮流新品-YOHO!BUY 有货'; 76 let seoTitle = '【潮流新品】_引领潮流_2018时尚潮流新品-YOHO!BUY 有货';
77 77
@@ -144,7 +144,7 @@ const _newGoods = (req, res, next) => { @@ -144,7 +144,7 @@ const _newGoods = (req, res, next) => {
144 }); 144 });
145 145
146 // 唤起 APP 的路径 146 // 唤起 APP 的路径
147 - res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.new","params":${JSON.stringify(appParams)}}`; 147 + res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.new","params":${encodeURIComponent(JSON.stringify(appParams))}}`;
148 148
149 req.ctx(newModel).indexData(uid, channel).then(result => { 149 req.ctx(newModel).indexData(uid, channel).then(result => {
150 let shopList = _.get(result, 'shop_list', []); 150 let shopList = _.get(result, 'shop_list', []);
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 {{# comments}} 3 {{# comments}}
4 <div class="comment-item clearfix"> 4 <div class="comment-item clearfix">
5 <div class="user-info clearfix"> 5 <div class="user-info clearfix">
6 - <span class="user-name">{{userName}}</span> 6 + <span class="user-name">{{{userName}}}</span>
7 <span class="goods-spec"> 7 <span class="goods-spec">
8 购买了<b>{{color}}</b> 8 购买了<b>{{color}}</b>
9 </span> 9 </span>
@@ -12,11 +12,11 @@ @@ -12,11 +12,11 @@
12 <div class="comment-content-main content-main clearfix"> 12 <div class="comment-content-main content-main clearfix">
13 {{# comments}} 13 {{# comments}}
14 <span class="user-name"> 14 <span class="user-name">
15 - {{userName}} 15 + {{{userName}}}
16 </span> 16 </span>
17 <p class="goods-spec"> 17 <p class="goods-spec">
18 购买了{{desc}} 18 购买了{{desc}}
19 - </> 19 + </p>
20 <p class="detail-content"> 20 <p class="detail-content">
21 {{content}} 21 {{content}}
22 </p> 22 </p>
  1 +'use strict';
  2 +
  3 +const csrf = require('csurf');
  4 +const csrfInit = csrf();
  5 +
  6 +module.exports = (req, res, next) => {
  7 + return csrfInit(req, res, (e) => {
  8 + res.locals.csrfToken = req.csrfToken();
  9 +
  10 + return next(e);
  11 + });
  12 +};
@@ -106,9 +106,11 @@ exports.serverError = () => { @@ -106,9 +106,11 @@ exports.serverError = () => {
106 106
107 forceNoCache(res); 107 forceNoCache(res);
108 108
109 - err.code = err.code || err.statusCode || 500; 109 + err = err || {};
110 110
111 - if (!err.type === 'entity.parse.failed') { // json 解析失败不上报错误 111 + err.code = parseInt(err.code || err.statusCode, 10) || 500;
  112 +
  113 + if (err.type !== 'entity.parse.failed') { // json 解析失败不上报错误
112 logger.error(`error at path: ${req.url}`); 114 logger.error(`error at path: ${req.url}`);
113 logger.error(err); 115 logger.error(err);
114 } 116 }
@@ -199,7 +201,7 @@ exports.serverError = () => { @@ -199,7 +201,7 @@ exports.serverError = () => {
199 } 201 }
200 202
201 if (!res.headersSent) { 203 if (!res.headersSent) {
202 - return _err500(req, res, err.code, err); 204 + return _err500(req, res, 500, err);
203 } 205 }
204 206
205 return next(err); 207 return next(err);
1 { 1 {
2 "name": "yohobuywap-node", 2 "name": "yohobuywap-node",
3 - "version": "6.6.15", 3 + "version": "6.6.17",
4 "private": true, 4 "private": true,
5 "description": "A New Yohobuy Project With Express", 5 "description": "A New Yohobuy Project With Express",
6 "repository": { 6 "repository": {
@@ -62,6 +62,7 @@ @@ -62,6 +62,7 @@
62 "connect-redis": "^3.3.3", 62 "connect-redis": "^3.3.3",
63 "cookie-parser": "^1.4.3", 63 "cookie-parser": "^1.4.3",
64 "cssnano": "^3.10.0", 64 "cssnano": "^3.10.0",
  65 + "csurf": "^1.9.0",
65 "express": "^4.16.3", 66 "express": "^4.16.3",
66 "feed": "^1.1.0", 67 "feed": "^1.1.0",
67 "geetest": "^4.1.2", 68 "geetest": "^4.1.2",
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <div class="invite-share"> 2 <div class="invite-share">
3 <span class="close-invite iconfont">&#xe72d;</span> 3 <span class="close-invite iconfont">&#xe72d;</span>
4 <img class="head-ico" src="{{image headIco 75 75}}"> 4 <img class="head-ico" src="{{image headIco 75 75}}">
5 - <span class="invite-name">"{{nickname}}"邀请你来有货玩潮流</span> 5 + <span class="invite-name">"{{{nickname}}}"邀请你来有货玩潮流</span>
6 <p class="invite-trend">{{#if trendWord}}# {{trendWord}} #{{else}}{{inviteCode}}{{/if}}</p> 6 <p class="invite-trend">{{#if trendWord}}# {{trendWord}} #{{else}}{{inviteCode}}{{/if}}</p>
7 <a href="//m.yohobuy.com/activity/friend-invite?inviteCode={{inviteCode}}" class="invite-go">现在就去</a> 7 <a href="//m.yohobuy.com/activity/friend-invite?inviteCode={{inviteCode}}" class="invite-go">现在就去</a>
8 </div> 8 </div>
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 <div class="user-info clearfix"> 13 <div class="user-info clearfix">
14 {{# comments}} 14 {{# comments}}
15 <span class="user-name"> 15 <span class="user-name">
16 - {{userName}} 16 + {{{userName}}}
17 </span> 17 </span>
18 <span class="goods-spec"> 18 <span class="goods-spec">
19 购买了<b>{{color}}</b> 19 购买了<b>{{color}}</b>
@@ -3,7 +3,15 @@ require('3party/question-detail.page.css'); @@ -3,7 +3,15 @@ require('3party/question-detail.page.css');
3 let $ = require('yoho-jquery'), 3 let $ = require('yoho-jquery'),
4 yoho = require('yoho-app'), 4 yoho = require('yoho-app'),
5 tipDg = require('plugin/tip'), 5 tipDg = require('plugin/tip'),
6 - share = require('common/share'); 6 + share = require('common/share'),
  7 + Validate = require('plugin/validata');
  8 +
  9 +let validate = new Validate('#js-img-check', {
  10 + useREM: {
  11 + rootFontSize: 40,
  12 + picWidth: 150
  13 + }
  14 +});
7 15
8 let question = { 16 let question = {
9 $base: $('#qs-wrap'), 17 $base: $('#qs-wrap'),
@@ -197,50 +205,53 @@ let question = { @@ -197,50 +205,53 @@ let question = {
197 } 205 }
198 }, 206 },
199 saveAnswers: function(info) { 207 saveAnswers: function(info) {
200 - var that = this;  
201 -  
202 - if (this.saving || !info || !info.length) { 208 + if (!info || !info.length) {
203 return; 209 return;
204 } 210 }
205 211
206 - this.saving = true;  
207 -  
208 - setTimeout(function() {  
209 - that.saving = false;  
210 - }, 5000); 212 + return validate.getResults().then(result => {
  213 + if (typeof result === 'undefined') {
  214 + return;
  215 + }
211 216
212 - $.ajax({  
213 - type: 'POST',  
214 - url: '/3party/questionnaire/submit',  
215 - data: { 217 + let params = {
216 id: this.$base.data('id'), 218 id: this.$base.data('id'),
217 uid: this.$base.data('cid'), 219 uid: this.$base.data('cid'),
218 startTime: this.startTime, 220 startTime: this.startTime,
219 endTime: Date.parse(new Date()) / 1000, 221 endTime: Date.parse(new Date()) / 1000,
220 frontAnswers: JSON.stringify(info), 222 frontAnswers: JSON.stringify(info),
221 mobile: this.$mobile.val() 223 mobile: this.$mobile.val()
222 - }  
223 - }).then(function(data) {  
224 - that.saving = false;  
225 - if (data.code === 200 || data.code === 206) {  
226 - let tip = '调查问卷已成功提交,感谢您的帮助!'; 224 + };
227 225
228 - if (data.code === 206 && data.message) {  
229 - tip = data.message;  
230 - } 226 + $.extend(params, result);
  227 +
  228 + $.ajax({
  229 + type: 'POST',
  230 + url: '/3party/questionnaire/submit',
  231 + data: params
  232 + }).then(function(data) {
  233 + validate.type === 2 && validate.refresh();
231 234
232 - tipDg.show(tip); 235 + if (data.code === 200 || data.code === 206) {
  236 + let tip = '调查问卷已成功提交,感谢您的帮助!';
233 237
234 - setTimeout(function() {  
235 - if (yoho.isApp) {  
236 - yoho.invokeMethod('go.back');  
237 - } else {  
238 - window.history.go(-1); 238 + if (data.code === 206 && data.message) {
  239 + tip = data.message;
239 } 240 }
240 - }, 2000);  
241 - } else {  
242 - tipDg.show(data.message || '网络出了点问题~');  
243 - } 241 +
  242 + tipDg.show(tip);
  243 +
  244 + setTimeout(function() {
  245 + if (yoho.isApp) {
  246 + yoho.invokeMethod('go.back');
  247 + } else {
  248 + window.history.go(-1);
  249 + }
  250 + }, 2000);
  251 + } else {
  252 + tipDg.show(data.message || '网络出了点问题~');
  253 + }
  254 + });
244 }); 255 });
245 } 256 }
246 }; 257 };
@@ -40,7 +40,8 @@ $confim.on('touchend', '.cancel', function() { @@ -40,7 +40,8 @@ $confim.on('touchend', '.cancel', function() {
40 method: 'POST', 40 method: 'POST',
41 url: '/home/delAddress', 41 url: '/home/delAddress',
42 data: { 42 data: {
43 - id: deleteId 43 + id: deleteId,
  44 + _csrf: $('input[name=_csrf]').val()
44 } 45 }
45 }).then(function(res) { 46 }).then(function(res) {
46 if ($.type(res) !== 'object') { 47 if ($.type(res) !== 'object') {
@@ -20,7 +20,7 @@ $('.address-item').on('click', function() { @@ -20,7 +20,7 @@ $('.address-item').on('click', function() {
20 address_id: addressId, 20 address_id: addressId,
21 consignee: $this.find('.name').text(), 21 consignee: $this.find('.name').text(),
22 mobile: $this.find('.tel').text(), 22 mobile: $this.find('.tel').text(),
23 - address_info: $this.find('.address-info').text(), 23 + address_info: $this.find('.address-info').data('address'),
24 is_support: $this.data('is-support') 24 is_support: $this.data('is-support')
25 }; 25 };
26 26
@@ -26,6 +26,10 @@ function cookie(name) { @@ -26,6 +26,10 @@ function cookie(name) {
26 var re = new RegExp(name + '=([^;$]*)', 'i'), 26 var re = new RegExp(name + '=([^;$]*)', 'i'),
27 matchPattern = '$1'; 27 matchPattern = '$1';
28 28
  29 + if (name === '_UID') {
  30 + return decodeURIComponent(re.test(document.cookie) ? RegExp[matchPattern] : '');
  31 + }
  32 +
29 try { 33 try {
30 return re.test(decodeURIComponent(document.cookie)) ? RegExp[matchPattern] : ''; 34 return re.test(decodeURIComponent(document.cookie)) ? RegExp[matchPattern] : '';
31 } catch (e) { 35 } catch (e) {
@@ -40,7 +40,8 @@ $confim.on('touchend', '.cancel', function() { @@ -40,7 +40,8 @@ $confim.on('touchend', '.cancel', function() {
40 method: 'POST', 40 method: 'POST',
41 url: '/home/delAddress', 41 url: '/home/delAddress',
42 data: { 42 data: {
43 - id: deleteId 43 + id: deleteId,
  44 + _csrf: $('input[name=_csrf]').val()
44 } 45 }
45 }).then(function(res) { 46 }).then(function(res) {
46 if ($.type(res) !== 'object') { 47 if ($.type(res) !== 'object') {
  1 +@import "layout/img-check";
  2 +
1 body { 3 body {
2 background: #f0f0f0; 4 background: #f0f0f0;
3 } 5 }
  1 +'use strict';
  2 +
  3 +const re = /(\r\n)|["\'<>]/g;
  4 +const htmlEntity = {
  5 + '&amp;': '\u0026',
  6 + '&quot;': '\u0022',
  7 + '&apos;': '\u0027',
  8 + '&lt;': '\u003c',
  9 + '&gt;': '\u003e'
  10 +};
  11 +
  12 +exports.htmlDecode = function(txt) {
  13 + txt = txt || '';
  14 + return txt.replace(/((&(([a-z][a-z0-9]*)|(#[0-9]+)|(#x[0-9a-f]+));)|["'<>&])/gi, function(s) {
  15 + s = s || '';
  16 + const s1 = htmlEntity[s.toLowerCase()];
  17 +
  18 + if (s1) {
  19 + s = s1;
  20 + }
  21 +
  22 + return s;
  23 + });
  24 +};
  25 +
  26 +exports.htmlEncode = function(str) {
  27 + str = str || '';
  28 + return str.replace(re, function(s) {
  29 + switch (s) {
  30 + case '"':
  31 + return '&quot;';
  32 + case '\'':
  33 + return '&apos;';
  34 + case '<':
  35 + return '&lt;';
  36 + case '>':
  37 + return '&gt;';
  38 + default:
  39 + return s;
  40 + }
  41 + });
  42 +};
@@ -2240,6 +2240,14 @@ crypto-random-string@^1.0.0: @@ -2240,6 +2240,14 @@ crypto-random-string@^1.0.0:
2240 version "1.0.0" 2240 version "1.0.0"
2241 resolved "http://npm.yohops.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" 2241 resolved "http://npm.yohops.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
2242 2242
  2243 +csrf@~3.0.3:
  2244 + version "3.0.6"
  2245 + resolved "http://npm.yohops.com/csrf/-/csrf-3.0.6.tgz#b61120ddceeafc91e76ed5313bb5c0b2667b710a"
  2246 + dependencies:
  2247 + rndm "1.2.0"
  2248 + tsscmp "1.0.5"
  2249 + uid-safe "2.1.4"
  2250 +
2243 css-color-function@~1.3.3: 2251 css-color-function@~1.3.3:
2244 version "1.3.3" 2252 version "1.3.3"
2245 resolved "http://npm.yohops.com/css-color-function/-/css-color-function-1.3.3.tgz#8ed24c2c0205073339fafa004bc8c141fccb282e" 2253 resolved "http://npm.yohops.com/css-color-function/-/css-color-function-1.3.3.tgz#8ed24c2c0205073339fafa004bc8c141fccb282e"
@@ -2402,6 +2410,15 @@ cssom@^0.3.2: @@ -2402,6 +2410,15 @@ cssom@^0.3.2:
2402 version "0.3.2" 2410 version "0.3.2"
2403 resolved "http://npm.yohops.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" 2411 resolved "http://npm.yohops.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b"
2404 2412
  2413 +csurf@^1.9.0:
  2414 + version "1.9.0"
  2415 + resolved "http://npm.yohops.com/csurf/-/csurf-1.9.0.tgz#49d2c6925ffcec7b7de559597c153fa533364133"
  2416 + dependencies:
  2417 + cookie "0.3.1"
  2418 + cookie-signature "1.0.6"
  2419 + csrf "~3.0.3"
  2420 + http-errors "~1.5.0"
  2421 +
2405 currently-unhandled@^0.4.1: 2422 currently-unhandled@^0.4.1:
2406 version "0.4.1" 2423 version "0.4.1"
2407 resolved "http://npm.yohops.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" 2424 resolved "http://npm.yohops.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
@@ -4042,6 +4059,14 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: @@ -4042,6 +4059,14 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3:
4042 setprototypeof "1.1.0" 4059 setprototypeof "1.1.0"
4043 statuses ">= 1.4.0 < 2" 4060 statuses ">= 1.4.0 < 2"
4044 4061
  4062 +http-errors@~1.5.0:
  4063 + version "1.5.1"
  4064 + resolved "http://npm.yohops.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750"
  4065 + dependencies:
  4066 + inherits "2.0.3"
  4067 + setprototypeof "1.0.2"
  4068 + statuses ">= 1.3.1 < 2"
  4069 +
4045 http-parser-js@>=0.4.0: 4070 http-parser-js@>=0.4.0:
4046 version "0.4.13" 4071 version "0.4.13"
4047 resolved "http://npm.yohops.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137" 4072 resolved "http://npm.yohops.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137"
@@ -7828,6 +7853,10 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: @@ -7828,6 +7853,10 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
7828 hash-base "^3.0.0" 7853 hash-base "^3.0.0"
7829 inherits "^2.0.1" 7854 inherits "^2.0.1"
7830 7855
  7856 +rndm@1.2.0:
  7857 + version "1.2.0"
  7858 + resolved "http://npm.yohops.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c"
  7859 +
7831 run-async@^2.0.0, run-async@^2.2.0: 7860 run-async@^2.0.0, run-async@^2.2.0:
7832 version "2.3.0" 7861 version "2.3.0"
7833 resolved "http://npm.yohops.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" 7862 resolved "http://npm.yohops.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
@@ -8008,6 +8037,10 @@ setimmediate@^1.0.4: @@ -8008,6 +8037,10 @@ setimmediate@^1.0.4:
8008 version "1.0.5" 8037 version "1.0.5"
8009 resolved "http://npm.yohops.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" 8038 resolved "http://npm.yohops.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
8010 8039
  8040 +setprototypeof@1.0.2:
  8041 + version "1.0.2"
  8042 + resolved "http://npm.yohops.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08"
  8043 +
8011 setprototypeof@1.0.3: 8044 setprototypeof@1.0.3:
8012 version "1.0.3" 8045 version "1.0.3"
8013 resolved "http://npm.yohops.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" 8046 resolved "http://npm.yohops.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
@@ -8864,6 +8897,10 @@ tslib@^1.9.0: @@ -8864,6 +8897,10 @@ tslib@^1.9.0:
8864 version "1.9.2" 8897 version "1.9.2"
8865 resolved "http://npm.yohops.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e" 8898 resolved "http://npm.yohops.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e"
8866 8899
  8900 +tsscmp@1.0.5:
  8901 + version "1.0.5"
  8902 + resolved "http://npm.yohops.com/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97"
  8903 +
8867 tty-browserify@0.0.0: 8904 tty-browserify@0.0.0:
8868 version "0.0.0" 8905 version "0.0.0"
8869 resolved "http://npm.yohops.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" 8906 resolved "http://npm.yohops.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
@@ -8928,6 +8965,12 @@ uglifyjs-webpack-plugin@^1.2.4: @@ -8928,6 +8965,12 @@ uglifyjs-webpack-plugin@^1.2.4:
8928 webpack-sources "^1.1.0" 8965 webpack-sources "^1.1.0"
8929 worker-farm "^1.5.2" 8966 worker-farm "^1.5.2"
8930 8967
  8968 +uid-safe@2.1.4:
  8969 + version "2.1.4"
  8970 + resolved "http://npm.yohops.com/uid-safe/-/uid-safe-2.1.4.tgz#3ad6f38368c6d4c8c75ec17623fb79aa1d071d81"
  8971 + dependencies:
  8972 + random-bytes "~1.0.0"
  8973 +
8931 uid-safe@~2.1.2: 8974 uid-safe@~2.1.2:
8932 version "2.1.5" 8975 version "2.1.5"
8933 resolved "http://npm.yohops.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" 8976 resolved "http://npm.yohops.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"