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) {
swal({ type: 'success', html: msg });
swal({ type: 'success', text: msg });
setTimeout(() => {
window.location = `${blessing.base_url}/${blessing.redirect_to || 'user'}`;
}, 1000);
} else {
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.refreshCaptcha();

View File

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

View File

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

View File

@ -2,7 +2,7 @@
<div class="box box-default">
<div class="box-header with-border">
<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>
<div class="operations">
<i

View File

@ -50,7 +50,7 @@
>
<div v-if="skinItems.length === 0" class="empty-msg">
<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 v-else>
<closet-item
@ -73,7 +73,7 @@
>
<div v-if="capeItems.length === 0" class="empty-msg">
<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 v-else>
<closet-item
@ -300,7 +300,7 @@ export default {
}
);
if (errno === 0) {
swal({ type: 'success', html: msg });
swal({ type: 'success', text: msg });
$('#modal-use-as').modal('hide');
} else {
toastr.warning(msg);

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@
<div class="box-header with-border">
<h3 class="box-title" v-t="'user.profile.avatar.title'"></h3>
</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 class="box box-warning">
@ -160,7 +160,7 @@
<h4 class="modal-title" v-t="'user.profile.delete.modal-title'"></h4>
</div>
<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 />
<input
type="password"
@ -256,7 +256,7 @@ export default {
const { nickname } = this;
if (!nickname) {
return swal({ type: 'error', html: this.$t('user.emptyNewNickName') });
return swal({ type: 'error', text: this.$t('user.emptyNewNickName') });
}
const { dismiss } = await swal({
@ -274,22 +274,22 @@ export default {
);
if (errno === 0) {
$('.nickname').each(function () {
$(this).html(nickname);
$(this).text(nickname);
});
return swal({ type: 'success', html: msg });
return swal({ type: 'success', text: msg });
} else {
return swal({ type: 'warning', html: msg });
return swal({ type: 'warning', text: msg });
}
},
async changeEmail() {
const { email } = this;
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)) {
return swal({ type: 'warning', html: this.$t('auth.invalidEmail') });
return swal({ type: 'warning', text: this.$t('auth.invalidEmail') });
}
const { dismiss } = await swal({
@ -316,7 +316,7 @@ export default {
const { deleteConfirm: password } = this;
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(
@ -326,11 +326,11 @@ export default {
if (errno === 0) {
await swal({
type: 'success',
html: msg
text: msg
});
window.location = `${blessing.base_url}/auth/login`;
} 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.directive('t', (el, { value }) => {
if (typeof value === 'string') {
el.innerHTML = trans(value);
el.textContent = trans(value);
} else if (typeof value === 'object') {
el.innerHTML = trans(value.path, value.args);
el.textContent = trans(value.path, value.args);
} else {
if (process.env.NODE_ENV !== 'production') {
console.warn('[i18n] Invalid arguments in `v-t` directive.');

View File

@ -50,7 +50,7 @@ test('login', async () => {
button.trigger('click');
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();
button.trigger('click');
@ -65,5 +65,5 @@ test('login', async () => {
);
await wrapper.vm.$nextTick();
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');
await wrapper.vm.$nextTick();
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');
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();
expect(swal).toBeCalledWith({ type: 'success', html: 'ok' });
expect(swal).toBeCalledWith({ type: 'success', text: 'ok' });
});
test('reset selected texture', () => {

View File

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