added suspend reason

This commit is contained in:
supertiger1234 2020-03-02 11:39:46 +00:00
parent 980d778504
commit b1c5800a8d
10 changed files with 182 additions and 42 deletions

View file

@ -61,12 +61,12 @@
<script async> <script async>
console.log("%cIMPORTANT:", "background: red; color: yellow; font-size: x-large"); console.log("%cIMPORTANT:", "background: red; color: yellow; font-size: x-large");
console.log("%cPasting code is dangerous and could cause your account to be hacked.", "color: white; font-weight: bold;"); console.log("%cPasting code is dangerous and could cause your account to be hacked.", "background: black; color: white; font-weight: bold;");
console.log("%cPasting code is dangerous and could cause your account to be hacked.", "color: white; font-weight: bold;"); console.log("%cPasting code is dangerous and could cause your account to be hacked.", "background: black; color: white; font-weight: bold;");
console.log("%cPasting code is dangerous and could cause your account to be hacked.", "color: white; font-weight: bold;"); console.log("%cPasting code is dangerous and could cause your account to be hacked.", "background: black; color: white; font-weight: bold;");
console.log("%cPasting code is dangerous and could cause your account to be hacked.", "color: white; font-weight: bold;"); console.log("%cPasting code is dangerous and could cause your account to be hacked.", "background: black; color: white; font-weight: bold;");
console.log("%cPasting code is dangerous and could cause your account to be hacked.", "color: white; font-weight: bold;"); console.log("%cPasting code is dangerous and could cause your account to be hacked.", "background: black; color: white; font-weight: bold;");
console.log("%cPasting code is dangerous and could cause your account to be hacked.", "color: white; font-weight: bold;"); console.log("%cPasting code is dangerous and could cause your account to be hacked.", "background: black; color: white; font-weight: bold;");
</script> </script>
</head> </head>

View file

@ -180,9 +180,13 @@ export default {
} }
event.target.classList.add("button-clicked"); event.target.classList.add("button-clicked");
const { ok, error, result } = await ServerService.getInviteDetail( let code;
inviteCode if (inviteCode.split("/").length >= 2) {
); code = inviteCode.split("/").pop();
} else {
code = inviteCode;
}
const { ok, error, result } = await ServerService.getInviteDetail(code);
if (!ok) { if (!ok) {
event.target.classList.remove("button-clicked"); event.target.classList.remove("button-clicked");

View file

@ -20,7 +20,8 @@
:key="invite" :key="invite"
class="invite" class="invite"
> >
{{ invite }} <span class="link">https://nertivia.tk/invites/</span>{{ invite }}
<div class="copy-button" @click="copy(invite)">Copy</div>
</div> </div>
</div> </div>
</div> </div>
@ -71,6 +72,9 @@ export default {
if (ok) { if (ok) {
this.invites.push(result.data.invite_code); this.invites.push(result.data.invite_code);
} }
},
copy(invite) {
this.$clipboard("https://nertivia.tk/invites/" + invite);
} }
}, },
computed: { computed: {
@ -154,4 +158,20 @@ export default {
margin-right: 0; margin-right: 0;
padding: 10px; padding: 10px;
} }
.link {
color: rgba(255, 255, 255, 0.5);
}
.copy-button {
display: flex;
margin: auto;
margin-right: 0;
flex-shrink: 0;
cursor: pointer;
opacity: 0.7;
transition: 0.2s;
}
.copy-button:hover {
opacity: 1;
}
</style> </style>

View file

@ -1,12 +1,16 @@
<template> <template>
<div class="dark-background admin-editor-popout" @mousedown="backgroundClick"> <div class="dark-background admin-editor-popout" @mousedown="backgroundClick">
<div class="inner"> <div class="inner">
<div>{{ popoutDetails.user.username }}</div>
<div>{{ popoutDetails.user.email }}</div>
<div>{{ popoutDetails.user.ip }}</div>
<input <input
type="password" type="password"
autocomplete="new-password" autocomplete="new-password"
v-model="password" v-model="password"
placeholder="Confirm Password" placeholder="Confirm Password"
/> />
<textarea v-model="reason" placeholder="Suspend Reason"></textarea>
<div class="button" v-if="!confirmSuspend" @click="suspendUserButton"> <div class="button" v-if="!confirmSuspend" @click="suspendUserButton">
Suspend User Suspend User
</div> </div>
@ -22,7 +26,8 @@ export default {
data() { data() {
return { return {
confirmSuspend: false, confirmSuspend: false,
password: "" password: "",
reason: ""
}; };
}, },
methods: { methods: {
@ -43,10 +48,14 @@ export default {
this.confirmSuspend = true; this.confirmSuspend = true;
return; return;
} }
await AdminService.suspendUser( const { ok } = await AdminService.suspendUser(
this.popoutDetails.uniqueID, this.popoutDetails.user.uniqueID,
this.password this.password,
this.reason
); );
if (ok) {
this.closeMenu();
}
} }
}, },
async mounted() {}, async mounted() {},

View file

@ -97,7 +97,11 @@
<div <div
class="about-item" class="about-item"
v-if="aboutMe" v-if="aboutMe"
:class="{ infoAboutMe: aboutItem.key === 'About me' }" :class="{
infoAboutMe:
aboutItem.key === 'About me' ||
aboutItem.key === 'Suspend Reason'
}"
> >
<div class="key">{{ aboutItem.key }}:</div> <div class="key">{{ aboutItem.key }}:</div>
<div <div

View file

@ -11,7 +11,9 @@
</div> </div>
<div class="date" v-if="!presence">{{ date }}</div> <div class="date" v-if="!presence">{{ date }}</div>
<div class="presence" v-if="presence">{{ presence }}</div> <div class="presence" v-if="presence">{{ presence }}</div>
<div class="suspended" v-if="user.banned">Suspended</div>
</div> </div>
</div> </div>
</template> </template>
@ -41,7 +43,7 @@ export default {
this.$store.dispatch("setAllPopout", { this.$store.dispatch("setAllPopout", {
show: true, show: true,
type: "ADMIN_MANAGE_USER", type: "ADMIN_MANAGE_USER",
uniqueID: this.user.uniqueID user: this.user
}); });
} }
} }
@ -61,6 +63,12 @@ export default {
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
} }
} }
.suspended {
background: rgb(255, 45, 45);
border-radius: 4px;
padding: 3px;
display: flex;
}
.profile-picture { .profile-picture {
width: 40px; width: 40px;
height: 40px; height: 40px;
@ -72,6 +80,11 @@ export default {
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
.details {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.date { .date {
font-size: 14px; font-size: 14px;
opacity: 0.6; opacity: 0.6;

View file

@ -1,21 +1,26 @@
import { instance, wrapper } from "./Api"; import { instance, wrapper } from "./Api";
const config = require('../config.js'); const config = require("../config.js");
let domain = ""; let domain = "";
if (config.serverURL) domain = config.serverURL+"/" if (config.serverURL) domain = config.serverURL + "/";
export default { export default {
register(credentials) { register(credentials) {
return wrapper(instance().post(domain+"user/register", credentials)); return wrapper(instance().post(domain + "user/register", credentials));
},
confirmEmail(email, code) {
return wrapper(
instance().post(domain + "user/register/confirm", { email, code })
);
}, },
login(credentials) { login(credentials) {
return wrapper(instance().post(domain+"user/login", credentials)); return wrapper(instance().post(domain + "user/login", credentials));
}, },
logout() { logout() {
return wrapper(instance().delete(domain+"user/logout")); return wrapper(instance().delete(domain + "user/logout"));
}, },
user() { user() {
return wrapper(instance().get(domain+"user")); return wrapper(instance().get(domain + "user"));
} }
}; };

View file

@ -19,9 +19,11 @@ export default {
approveTheme(id) { approveTheme(id) {
return wrapper(instance().patch(`admin/themes/${id}/approve`)); return wrapper(instance().patch(`admin/themes/${id}/approve`));
}, },
suspendUser(uniqueID, password) { suspendUser(uniqueID, password, reason) {
return wrapper( return wrapper(
instance().delete(`admin/users/${uniqueID}`, { data: { password } }) instance().delete(`admin/users/${uniqueID}`, {
data: { password, reason }
})
); );
} }
}; };

View file

@ -12,7 +12,7 @@
</div> </div>
<div class="info">Login to access Nertivia</div> <div class="info">Login to access Nertivia</div>
<form <form
v-if="!showCaptcha" v-if="currentPage === 0"
action="#" action="#"
@submit.prevent="submitForm" @submit.prevent="submitForm"
@keydown="keyDownEvent" @keydown="keyDownEvent"
@ -62,7 +62,7 @@
</button> </button>
</div> </div>
</form> </form>
<div v-if="showCaptcha" class="captcha-box"> <div v-if="currentPage === 1" class="captcha-box">
<div class="input captcha-input"> <div class="input captcha-input">
<div class="input-text"> <div class="input-text">
Beep Boop Beep Boop
@ -75,6 +75,23 @@
</div> </div>
</div> </div>
</div> </div>
<div v-if="currentPage === 2" class="form">
<div class="input">
<div class="input-text">
Check your email:
<span v-if="confirm_code.alert" class="error"
>- {{ confirm_code.alert }}</span
>
</div>
<input
@input="confirmCodeInput"
v-model="confirm_code.value"
type="text"
placeholder="Code"
autocomplete="off"
/>
</div>
</div>
</div> </div>
</transition> </transition>
</div> </div>
@ -96,10 +113,11 @@ export default {
return { return {
isElectron: window && window.process && window.process.type, isElectron: window && window.process && window.process.type,
showCaptcha: false, currentPage: 0,
visible: true, visible: true,
email: { value: "", alert: "" }, email: { value: "", alert: "" },
password: { value: "", alert: "" }, password: { value: "", alert: "" },
confirm_code: { value: "", alert: "" },
reCaptcha: { alert: "" }, reCaptcha: { alert: "" },
otherError: "", otherError: "",
@ -121,7 +139,7 @@ export default {
this.login(); this.login();
}, },
submitForm() { submitForm() {
this.showCaptcha = true; this.currentPage = 1;
}, },
keyDownEvent(event) { keyDownEvent(event) {
if (event.keyCode === 13) { if (event.keyCode === 13) {
@ -155,7 +173,7 @@ export default {
window.location.href = "/app"; window.location.href = "/app";
}, 1000); }, 1000);
} else { } else {
this.showCaptcha = false; this.currentPage = 0;
this.deactive = false; this.deactive = false;
this.captchaToken = null; this.captchaToken = null;
this.$refs.recaptcha.resetRecaptcha(); this.$refs.recaptcha.resetRecaptcha();
@ -163,6 +181,10 @@ export default {
this.otherError = "Can't connect to server."; this.otherError = "Can't connect to server.";
return; return;
} }
if (error.response.data.code === "CONFIRM_EMAIL") {
this.currentPage = 2;
return;
}
const errors = error.response.data.errors; const errors = error.response.data.errors;
for (let index in errors) { for (let index in errors) {
const message = errors[index].msg; const message = errors[index].msg;
@ -177,6 +199,29 @@ export default {
}, },
registerButton() { registerButton() {
this.$router.push("/register"); this.$router.push("/register");
},
async confirmCodeInput(event) {
const value = event.target.value;
if (value.length === 10) {
const { ok, result, error } = await AuthenticationService.confirmEmail(
this.email.value,
value
);
if (!ok) {
if (error.response === undefined) {
this.otherError = "Can't connect to server.";
return;
}
this.confirm_code.alert =
error.response.data.error || "Something went wrong.";
} else {
this.visible = false;
this.$store.dispatch("token", result.data.token);
setTimeout(() => {
window.location.href = "/app";
}, 1000);
}
}
} }
} }
}; };
@ -268,7 +313,8 @@ body {
text-align: center; text-align: center;
margin-bottom: 10px; margin-bottom: 10px;
} }
form { form,
.form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;

View file

@ -14,7 +14,7 @@
Welcome, new user! I Hope you enjoy Nertivia! Welcome, new user! I Hope you enjoy Nertivia!
</div> </div>
<form <form
v-if="!showCaptcha" v-if="currentPage === 0"
action="#" action="#"
@submit.prevent="formSubmit" @submit.prevent="formSubmit"
@keydown="keyDownEvent" @keydown="keyDownEvent"
@ -84,7 +84,7 @@
</button> </button>
</div> </div>
</form> </form>
<div v-if="showCaptcha" class="captcha-box"> <div v-if="currentPage === 1" class="captcha-box">
<div class="input captcha-input"> <div class="input captcha-input">
<div class="input-text">Beep Boop</div> <div class="input-text">Beep Boop</div>
<div class="captcha"> <div class="captcha">
@ -92,6 +92,23 @@
</div> </div>
</div> </div>
</div> </div>
<div v-if="currentPage === 2" class="form">
<div class="input">
<div class="input-text">
Check your email:
<span v-if="confirm_code.alert" class="error"
>- {{ confirm_code.alert }}</span
>
</div>
<input
@input="confirmCodeInput"
v-model="confirm_code.value"
type="text"
placeholder="Code"
autocomplete="off"
/>
</div>
</div>
</div> </div>
</transition> </transition>
</div> </div>
@ -113,8 +130,9 @@ export default {
return { return {
isElectron: window && window.process && window.process.type, isElectron: window && window.process && window.process.type,
showCaptcha: false, currentPage: 0,
visible: true, visible: true,
confirm_code: { value: "", alert: "" },
email: { value: "", alert: "" }, email: { value: "", alert: "" },
username: { value: "", alert: "" }, username: { value: "", alert: "" },
password: { value: "", alert: "" }, password: { value: "", alert: "" },
@ -137,7 +155,7 @@ export default {
this.register(); this.register();
}, },
formSubmit() { formSubmit() {
this.showCaptcha = true; this.currentPage = 1;
}, },
keyDownEvent(event) { keyDownEvent(event) {
if (event.keyCode === 13) { if (event.keyCode === 13) {
@ -151,20 +169,16 @@ export default {
const username = this.username.value.trim(); const username = this.username.value.trim();
const password = this.password.value.trim(); const password = this.password.value.trim();
const { ok, error, result } = await AuthenticationService.register({ const { ok, error } = await AuthenticationService.register({
email, email,
username, username,
password, password,
token: this.captchaToken token: this.captchaToken
}); });
if (ok) { if (ok) {
this.visible = false; this.currentPage = 2;
this.$store.dispatch("token", result.data.token);
setTimeout(() => {
window.location.href = "/app";
}, 1000);
} else { } else {
this.showCaptcha = false; this.currentPage = 0;
this.deactive = false; this.deactive = false;
this.captchaToken = null; this.captchaToken = null;
this.$refs.recaptcha.resetRecaptcha(); this.$refs.recaptcha.resetRecaptcha();
@ -186,6 +200,29 @@ export default {
}, },
loginButton() { loginButton() {
this.$router.push("/login"); this.$router.push("/login");
},
async confirmCodeInput(event) {
const value = event.target.value;
if (value.length === 10) {
const { ok, result, error } = await AuthenticationService.confirmEmail(
this.email.value,
value
);
if (!ok) {
if (error.response === undefined) {
this.otherError = "Can't connect to server.";
return;
}
this.confirm_code.alert =
error.response.data.error || "Something went wrong.";
} else {
this.visible = false;
this.$store.dispatch("token", result.data.token);
setTimeout(() => {
window.location.href = "/app";
}, 1000);
}
}
} }
} }
}; };
@ -276,7 +313,7 @@ body {
text-align: center; text-align: center;
margin-bottom: 10px; margin-bottom: 10px;
} }
form { form, .form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;