Prevent possible XSS

This commit is contained in:
Pig Fang 2018-08-14 23:43:56 +08:00
parent 190e54578a
commit f17cc18995
15 changed files with 43 additions and 43 deletions

View File

@ -135,13 +135,13 @@ export default {
} }
); );
if (errno === 0) { if (errno === 0) {
swal({ type: 'success', html: msg }); swal({ type: 'success', text: msg });
setTimeout(() => { setTimeout(() => {
window.location = `${blessing.base_url}/${blessing.redirect_to || 'user'}`; window.location = `${blessing.base_url}/${blessing.redirect_to || 'user'}`;
}, 1000); }, 1000);
} else { } else {
if (login_fails > 3 && !this.tooManyFails) { if (login_fails > 3 && !this.tooManyFails) {
swal({ type: 'error', html: this.$t('auth.tooManyFails') }); swal({ type: 'error', text: this.$t('auth.tooManyFails') });
this.tooManyFails = true; this.tooManyFails = true;
} }
this.refreshCaptcha(); this.refreshCaptcha();

View File

@ -168,7 +168,7 @@ export default {
{ email, password, nickname, captcha } { email, password, nickname, captcha }
); );
if (errno === 0) { if (errno === 0) {
swal({ type: 'success', html: msg }); swal({ type: 'success', text: msg });
setTimeout(() => { setTimeout(() => {
window.location = `${blessing.base_url}/user`; window.location = `${blessing.base_url}/user`;
}, 1000); }, 1000);

View File

@ -82,7 +82,7 @@ export default {
{ password } { password }
); );
if (errno === 0) { if (errno === 0) {
await swal({ type: 'success', html: msg }); await swal({ type: 'success', text: msg });
window.location = `${blessing.base_url}/auth/login`; window.location = `${blessing.base_url}/auth/login`;
} else { } else {
this.infoMsg = ''; this.infoMsg = '';

View File

@ -2,7 +2,7 @@
<div class="box box-default"> <div class="box box-default">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title" style="width: 100%;"> <h3 class="box-title" style="width: 100%;">
<span v-t="title"></span> <span v-html="$t(title)"></span>
<span data-toggle="tooltip" class="badge bg-light-blue">{{ indicator }}</span> <span data-toggle="tooltip" class="badge bg-light-blue">{{ indicator }}</span>
<div class="operations"> <div class="operations">
<i <i

View File

@ -50,7 +50,7 @@
> >
<div v-if="skinItems.length === 0" class="empty-msg"> <div v-if="skinItems.length === 0" class="empty-msg">
<div v-if="query !== ''" v-t="'general.noResult'"></div> <div v-if="query !== ''" v-t="'general.noResult'"></div>
<div v-else v-t="{ path: 'user.emptyClosetMsg', args: { url: linkToSkin } }" /> <div v-else v-html="$t('user.emptyClosetMsg', { url: linkToSkin })" />
</div> </div>
<div v-else> <div v-else>
<closet-item <closet-item
@ -73,7 +73,7 @@
> >
<div v-if="capeItems.length === 0" class="empty-msg"> <div v-if="capeItems.length === 0" class="empty-msg">
<div v-if="query !== ''" v-t="'general.noResult'"></div> <div v-if="query !== ''" v-t="'general.noResult'"></div>
<div v-else v-t="{ path: 'user.emptyClosetMsg', args: { url: linkToCape } }" /> <div v-else v-html="$t('user.emptyClosetMsg', { url: linkToCape })" />
</div> </div>
<div v-else> <div v-else>
<closet-item <closet-item
@ -300,7 +300,7 @@ export default {
} }
); );
if (errno === 0) { if (errno === 0) {
swal({ type: 'success', html: msg }); swal({ type: 'success', text: msg });
$('#modal-use-as').modal('hide'); $('#modal-use-as').modal('hide');
} else { } else {
toastr.warning(msg); toastr.warning(msg);

View File

@ -108,7 +108,7 @@ export default {
if (errno === 0) { if (errno === 0) {
this.$emit('item-removed', this.tid); this.$emit('item-removed', this.tid);
swal({ type: 'success', html: msg }); swal({ type: 'success', text: msg });
} else { } else {
toastr.warning(msg); toastr.warning(msg);
} }

View File

@ -129,7 +129,7 @@ export default {
const result = await this.$http.post('/user/sign'); const result = await this.$http.post('/user/sign');
if (result.errno === 0) { if (result.errno === 0) {
swal({ type: 'success', html: result.msg }); swal({ type: 'success', text: result.msg });
this.score = result.score; this.score = result.score;
this.lastSignAt = new Date(); this.lastSignAt = new Date();

View File

@ -358,10 +358,10 @@ export default {
{ pid: player.pid, new_player_name: value } { pid: player.pid, new_player_name: value }
); );
if (errno === 0) { if (errno === 0) {
swal({ type: 'success', html: msg }); swal({ type: 'success', text: msg });
player.player_name = value; player.player_name = value;
} else { } else {
swal({ type: 'warning', html: msg }); swal({ type: 'warning', text: msg });
} }
}, },
loadICheck() { loadICheck() {
@ -410,10 +410,10 @@ export default {
{ pid: player.pid } { pid: player.pid }
); );
if (errno === 0) { if (errno === 0) {
swal({ type: 'success', html: msg }); swal({ type: 'success', text: msg });
this.players = this.players.filter(({ pid }) => pid !== player.pid); this.players = this.players.filter(({ pid }) => pid !== player.pid);
} else { } else {
swal({ type: 'warning', html: msg }); swal({ type: 'warning', text: msg });
} }
}, },
async addPlayer() { async addPlayer() {
@ -423,10 +423,10 @@ export default {
{ player_name: this.newPlayer } { player_name: this.newPlayer }
); );
if (errno === 0) { if (errno === 0) {
await swal({ type: 'success', html: msg }); await swal({ type: 'success', text: msg });
this.fetchPlayers(); this.fetchPlayers();
} else { } else {
swal({ type: 'warning', html: msg }); swal({ type: 'warning', text: msg });
} }
} }
} }

View File

@ -6,7 +6,7 @@
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title" v-t="'user.profile.avatar.title'"></h3> <h3 class="box-title" v-t="'user.profile.avatar.title'"></h3>
</div><!-- /.box-header --> </div><!-- /.box-header -->
<div class="box-body" v-t="'user.profile.avatar.notice'"></div><!-- /.box-body --> <div class="box-body" v-html="$t('user.profile.avatar.notice')"></div><!-- /.box-body -->
</div> </div>
<div class="box box-warning"> <div class="box box-warning">
@ -160,7 +160,7 @@
<h4 class="modal-title" v-t="'user.profile.delete.modal-title'"></h4> <h4 class="modal-title" v-t="'user.profile.delete.modal-title'"></h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div v-once v-html="nl2br($t('user.profile.delete.modal-notice'))"></div> <div v-once v-text="nl2br($t('user.profile.delete.modal-notice'))"></div>
<br /> <br />
<input <input
type="password" type="password"
@ -256,7 +256,7 @@ export default {
const { nickname } = this; const { nickname } = this;
if (!nickname) { if (!nickname) {
return swal({ type: 'error', html: this.$t('user.emptyNewNickName') }); return swal({ type: 'error', text: this.$t('user.emptyNewNickName') });
} }
const { dismiss } = await swal({ const { dismiss } = await swal({
@ -274,22 +274,22 @@ export default {
); );
if (errno === 0) { if (errno === 0) {
$('.nickname').each(function () { $('.nickname').each(function () {
$(this).html(nickname); $(this).text(nickname);
}); });
return swal({ type: 'success', html: msg }); return swal({ type: 'success', text: msg });
} else { } else {
return swal({ type: 'warning', html: msg }); return swal({ type: 'warning', text: msg });
} }
}, },
async changeEmail() { async changeEmail() {
const { email } = this; const { email } = this;
if (!email) { if (!email) {
return swal({ type: 'error', html: this.$t('user.emptyNewEmail') }); return swal({ type: 'error', text: this.$t('user.emptyNewEmail') });
} }
if (!/\S+@\S+\.\S+/.test(email)) { if (!/\S+@\S+\.\S+/.test(email)) {
return swal({ type: 'warning', html: this.$t('auth.invalidEmail') }); return swal({ type: 'warning', text: this.$t('auth.invalidEmail') });
} }
const { dismiss } = await swal({ const { dismiss } = await swal({
@ -316,7 +316,7 @@ export default {
const { deleteConfirm: password } = this; const { deleteConfirm: password } = this;
if (!password) { if (!password) {
return swal({ type: 'warning', html: this.$t('user.emptyDeletePassword') }); return swal({ type: 'warning', text: this.$t('user.emptyDeletePassword') });
} }
const { errno, msg } = await this.$http.post( const { errno, msg } = await this.$http.post(
@ -326,11 +326,11 @@ export default {
if (errno === 0) { if (errno === 0) {
await swal({ await swal({
type: 'success', type: 'success',
html: msg text: msg
}); });
window.location = `${blessing.base_url}/auth/login`; window.location = `${blessing.base_url}/auth/login`;
} else { } else {
return swal({ type: 'warning', html: msg }); return swal({ type: 'warning', text: msg });
} }
} }
} }

View File

@ -32,9 +32,9 @@ Vue.use(_Vue => {
_Vue.prototype.$t = trans; _Vue.prototype.$t = trans;
_Vue.directive('t', (el, { value }) => { _Vue.directive('t', (el, { value }) => {
if (typeof value === 'string') { if (typeof value === 'string') {
el.innerHTML = trans(value); el.textContent = trans(value);
} else if (typeof value === 'object') { } else if (typeof value === 'object') {
el.innerHTML = trans(value.path, value.args); el.textContent = trans(value.path, value.args);
} else { } else {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
console.warn('[i18n] Invalid arguments in `v-t` directive.'); console.warn('[i18n] Invalid arguments in `v-t` directive.');

View File

@ -50,7 +50,7 @@ test('login', async () => {
button.trigger('click'); button.trigger('click');
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(swal).toBeCalledWith({ type: 'error', html: 'auth.tooManyFails' }); expect(swal).toBeCalledWith({ type: 'error', text: 'auth.tooManyFails' });
expect(wrapper.find('img').exists()).toBeTrue(); expect(wrapper.find('img').exists()).toBeTrue();
button.trigger('click'); button.trigger('click');
@ -65,5 +65,5 @@ test('login', async () => {
); );
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
jest.runAllTimers(); jest.runAllTimers();
expect(swal).toBeCalledWith({ type: 'success', html: 'ok' }); expect(swal).toBeCalledWith({ type: 'success', text: 'ok' });
}); });

View File

@ -79,5 +79,5 @@ test('register', async () => {
button.trigger('click'); button.trigger('click');
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
jest.runAllTimers(); jest.runAllTimers();
expect(swal).toBeCalledWith({ type: 'success', html: 'ok' }); expect(swal).toBeCalledWith({ type: 'success', text: 'ok' });
}); });

View File

@ -48,5 +48,5 @@ test('reset password', async () => {
button.trigger('click'); button.trigger('click');
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(swal).toBeCalledWith({ type: 'success', html: 'ok' }); expect(swal).toBeCalledWith({ type: 'success', text: 'ok' });
}); });

View File

@ -249,7 +249,7 @@ test('submit applying texture', async () => {
} }
); );
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(swal).toBeCalledWith({ type: 'success', html: 'ok' }); expect(swal).toBeCalledWith({ type: 'success', text: 'ok' });
}); });
test('reset selected texture', () => { test('reset selected texture', () => {

View File

@ -74,14 +74,14 @@ test('change nickname', async () => {
each(fn) { each(fn) {
fn(); fn();
}, },
html() {} text() {}
})); }));
const wrapper = mount(Profile); const wrapper = mount(Profile);
const button = wrapper.find('[data-test=changeNickName]'); const button = wrapper.find('[data-test=changeNickName]');
button.trigger('click'); button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled(); expect(Vue.prototype.$http.post).not.toBeCalled();
expect(swal).toBeCalledWith({ type: 'error', html: 'user.emptyNewNickName' }); expect(swal).toBeCalledWith({ type: 'error', text: 'user.emptyNewNickName' });
wrapper.setData({ nickname: 'nickname' }); wrapper.setData({ nickname: 'nickname' });
button.trigger('click'); button.trigger('click');
@ -99,11 +99,11 @@ test('change nickname', async () => {
{ new_nickname: 'nickname' } { new_nickname: 'nickname' }
); );
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(swal).toBeCalledWith({ type: 'warning', html: 'w' }); expect(swal).toBeCalledWith({ type: 'warning', text: 'w' });
button.trigger('click'); button.trigger('click');
await flushPromises(); await flushPromises();
expect(swal).toBeCalledWith({ type: 'success', html: 'o' }); expect(swal).toBeCalledWith({ type: 'success', text: 'o' });
}); });
test('change email', async () => { test('change email', async () => {
@ -118,12 +118,12 @@ test('change email', async () => {
const button = wrapper.find('[data-test=changeEmail]'); const button = wrapper.find('[data-test=changeEmail]');
button.trigger('click'); button.trigger('click');
expect(swal).toBeCalledWith({ type: 'error', html: 'user.emptyNewEmail' }); expect(swal).toBeCalledWith({ type: 'error', text: 'user.emptyNewEmail' });
expect(Vue.prototype.$http.post).not.toBeCalled(); expect(Vue.prototype.$http.post).not.toBeCalled();
wrapper.setData({ email: 'e' }); wrapper.setData({ email: 'e' });
button.trigger('click'); button.trigger('click');
expect(swal).toBeCalledWith({ type: 'warning', html: 'auth.invalidEmail' }); expect(swal).toBeCalledWith({ type: 'warning', text: 'auth.invalidEmail' });
expect(Vue.prototype.$http.post).not.toBeCalled(); expect(Vue.prototype.$http.post).not.toBeCalled();
wrapper.setData({ email: 'a@b.c', currentPassword: 'abc' }); wrapper.setData({ email: 'a@b.c', currentPassword: 'abc' });
@ -159,7 +159,7 @@ test('delete account', async () => {
const button = wrapper.find('[data-test=deleteAccount]'); const button = wrapper.find('[data-test=deleteAccount]');
button.trigger('click'); button.trigger('click');
expect(swal).toBeCalledWith({ type: 'warning', html: 'user.emptyDeletePassword' }); expect(swal).toBeCalledWith({ type: 'warning', text: 'user.emptyDeletePassword' });
expect(Vue.prototype.$http.post).not.toBeCalled(); expect(Vue.prototype.$http.post).not.toBeCalled();
wrapper.setData({ deleteConfirm: 'abc' }); wrapper.setData({ deleteConfirm: 'abc' });
@ -169,9 +169,9 @@ test('delete account', async () => {
{ password: 'abc' } { password: 'abc' }
); );
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(swal).toBeCalledWith({ type: 'warning', html: 'w' }); expect(swal).toBeCalledWith({ type: 'warning', text: 'w' });
button.trigger('click'); button.trigger('click');
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(swal).toBeCalledWith({ type: 'success', html: 'o' }); expect(swal).toBeCalledWith({ type: 'success', text: 'o' });
}); });