| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 | <template>	<div>		<modal title="Edit User">			<div slot="body">				<p class="control has-addons">					<input						v-model="editing.username"						class="input is-expanded"						type="text"						placeholder="Username"						autofocus					/>					<a class="button is-info" v-on:click="updateUsername()"						>Update Username</a					>				</p>				<p class="control has-addons">					<input						v-model="editing.email.address"						class="input is-expanded"						type="text"						placeholder="Email Address"						autofocus					/>					<a class="button is-info" v-on:click="updateEmail()"						>Update Email Address</a					>				</p>				<p class="control has-addons">					<span class="select">						<select v-model="editing.role">							<option>default</option>							<option>admin</option>						</select>					</span>					<a class="button is-info" v-on:click="updateRole()"						>Update Role</a					>				</p>				<hr />				<p class="control has-addons">					<span class="select">						<select v-model="ban.expiresAt">							<option value="1h">1 Hour</option>							<option value="12h">12 Hours</option>							<option value="1d">1 Day</option>							<option value="1w">1 Week</option>							<option value="1m">1 Month</option>							<option value="3m">3 Months</option>							<option value="6m">6 Months</option>							<option value="1y">1 Year</option>						</select>					</span>					<input						v-model="ban.reason"						class="input is-expanded"						type="text"						placeholder="Ban reason"						autofocus					/>					<a class="button is-error" v-on:click="banUser()"						>Ban user</a					>				</p>			</div>			<div slot="footer">				<!--button class='button is-warning'>					<span> Send Verification Email</span>				</button>				<button class='button is-warning'>					<span> Send Password Reset Email</span>        </button-->				<button class="button is-warning" v-on:click="removeSessions()">					<span> Remove all sessions</span>				</button>				<button					class="button is-danger"					@click="						closeModal({							sector: 'admin',							modal: 'editUser'						})					"				>					<span> Close</span>				</button>			</div>		</modal>	</div></template><script>import { mapState, mapActions } from "vuex";import { Toast } from "vue-roaster";import io from "../../io";import Modal from "./Modal.vue";import validation from "../../validation";export default {	components: { Modal },	data() {		return {			ban: {				expiresAt: "1h"			}		};	},	computed: {		...mapState("admin/users", {			editing: state => state.editing		}),		...mapState({			userId: state => state.user.auth.userId		})	},	methods: {		updateUsername() {			const { username } = this.editing;			if (!validation.isLength(username, 2, 32))				return Toast.methods.addToast(					"Username must have between 2 and 32 characters.",					8000				);			if (!validation.regex.azAZ09_.test(username))				return Toast.methods.addToast(					"Invalid username format. Allowed characters: a-z, A-Z, 0-9 and _.",					8000				);			return this.socket.emit(				`users.updateUsername`,				this.editing._id,				username,				res => {					Toast.methods.addToast(res.message, 4000);				}			);		},		updateEmail() {			const { email } = this.editing;			if (!validation.isLength(email, 3, 254))				return Toast.methods.addToast(					"Email must have between 3 and 254 characters.",					8000				);			if (				email.indexOf("@") !== email.lastIndexOf("@") ||				!validation.regex.emailSimple.test(email)			)				return Toast.methods.addToast("Invalid email format.", 8000);			return this.socket.emit(				`users.updateEmail`,				this.editing._id,				email,				res => {					Toast.methods.addToast(res.message, 4000);				}			);		},		updateRole() {			this.socket.emit(				`users.updateRole`,				this.editing._id,				this.editing.role,				res => {					Toast.methods.addToast(res.message, 4000);					if (						res.status === "success" &&						this.editing.role === "default" &&						this.editing._id === this.userId					)						window.location.reload();				}			);		},		banUser() {			const { reason } = this.ban;			if (!validation.isLength(reason, 1, 64))				return Toast.methods.addToast(					"Reason must have between 1 and 64 characters.",					8000				);			if (!validation.regex.ascii.test(reason))				return Toast.methods.addToast(					"Invalid reason format. Only ascii characters are allowed.",					8000				);			return this.socket.emit(				`users.banUserById`,				this.editing._id,				this.ban.reason,				this.ban.expiresAt,				res => {					Toast.methods.addToast(res.message, 4000);				}			);		},		removeSessions() {			this.socket.emit(`users.removeSessions`, this.editing._id, res => {				Toast.methods.addToast(res.message, 4000);			});		},		...mapActions("modals", ["closeModal"])	},	mounted() {		io.getSocket(socket => {			this.socket = socket;			return socket;		});	}};</script><style lang="scss" scoped>@import "styles/global.scss";.save-changes {	color: #fff;}.tag:not(:last-child) {	margin-right: 5px;}.select:after {	border-color: #029ce3;}</style>
 |