brainlet/app/resources/js/auth.js

265 lines
8.9 KiB
JavaScript
Raw Normal View History

2020-10-05 20:36:03 +03:00
Vue.use(VueMaterial.default);
const getLoginMessageFromError = (json) => {
switch (json.message) {
case 'ERROR_REQUEST_LOGIN_INVALID': {
return 'Invalid username or password.';
}
case 'ERROR_ACCESS_DENIED': {
return 'You are not allowed to perform this action.'
}
default: {
return 'Unknown error. Something went wrong.'
}
}
}
const getSignupMessageFromError = (json) => {
switch (json.message) {
case 'ERROR_REQUEST_INVALID_DATA': {
switch (json.errors[0].param) {
case 'username': {
return 'Invalid username. Username must be between 3 and 32 characters long, and be alphanumeric.';
}
case 'password': {
return 'Invalid password. Password must be at least 8 characters long and at most 128 characters.';
}
case 'email': {
return 'Invalid email.';
}
case 'specialCode': {
return 'Invalid special code.';
}
2020-10-05 20:36:03 +03:00
default: {
return 'Invalid value sent to server. Something went wrong.';
}
}
}
case 'ERROR_ACCESS_DENIED': {
return 'You are not allowed to perform this action.'
}
case 'ERROR_REQUEST_USERNAME_EXISTS': {
return 'That username is taken.';
}
default: {
return 'Unknown error. Something went wrong.'
}
}
};
const app = new Vue({
el: '#app',
data: {
usernameInput: '',
emailInput: '',
passwordInput: '',
specialCodeInput: '',
2020-10-05 20:36:03 +03:00
mode: 'SIGNUP',
showSnackbarNotification: false,
snackbarNotification: '',
snackbarNotificationDuration: 999999,
snackbarButtonText: 'Ok',
successfulLogin: false,
loggedInUser: {},
requiresSpecialCode: null
2020-10-05 20:36:03 +03:00
},
mounted: async function() {
const res = await fetch(`${window.location.origin}/api/v1/users/current/info`, {
method: 'GET',
headers: {
'Accept': 'application/json',
},
credentials: 'include'
});
if (res.status === 200) {
const json = await res.json();
if (json.user.permissionLevel >= 1) {
this.loggedInUser = json.user;
this.mode = 'MANAGE';
} else {
this.resetSnackbarButton();
this.notification('Your account has been suspended');
this.successfulLogin = true;
}
} else {
const resInfo = await fetch(`${window.location.origin}/api/v1/users/account/create/info`, {
method: 'GET',
headers: {
'Accept': 'application/json',
}
});
if (resInfo.ok) {
const json = await resInfo.json();
this.requiresSpecialCode = json.requiresSpecialCode;
this.mode = 'SIGNUP';
} else {
this.mode = '_ERROR';
}
2020-10-05 20:36:03 +03:00
}
},
computed: {
modeName: function() {
switch (this.mode) {
case 'SIGNUP': {
return 'Sign up';
}
case 'LOGIN': {
return 'Log in';
}
case 'LOADING': {
return 'Loading...';
}
case 'MANAGE': {
return this.loggedInUser.username || 'Unknown account';
}
case 'SPECIAL_CODE': {
return 'Just one more step'
}
2020-10-05 20:36:03 +03:00
case 'NONE': {
return '';
}
default: {
return 'Something went wrong.';
}
}
}
},
methods: {
snackbarButtonAction: function() {
this.showSnackbarNotification = false;
},
snackbarButtonClick: function() {
this.snackbarButtonAction();
},
snackbarEditButton: function(buttonText="Ok", action) {
this.snackbarButtonText = buttonText;
this.snackbarButtonAction = action;
},
resetSnackbarButton: function() {
this.snackbarButtonText = 'Ok';
this.snackbarButtonAction = () => {
this.showSnackbarNotification = false;
};
},
notification: function(text) {
this.snackbarNotification = text;
this.showSnackbarNotification = true;
},
performTokenRemoval: async function() {
const res = await fetch(`${window.location.origin}/api/v1/users/browser/token/clear`, {
method: 'POST',
credentials: 'include'
});
if (res.status === 200) {
this.loggedInUser = {};
this.snackbarEditButton('Home', () => {
window.location.href = `${window.location.origin}`;
this.resetSnackbarButton();
this.showSnackbarNotification = false;
});
this.successfulLogin = true;
this.notification('Successfully logged out');
} else {
this.resetSnackbarButton();
this.notification('Could not log out');
}
},
navigateHome: function() {
window.location.href = `${window.location.origin}`;
},
performTokenCreation: async function() {
const res = await fetch(`${window.location.origin}/api/v1/users/token/create`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify({
username: this.usernameInput,
password: this.passwordInput,
alsoSetCookie: true
})
});
const json = await res.json();
if (json.error || res.status !== 200) {
this.resetSnackbarButton();
this.notification(getLoginMessageFromError(json));
return;
} else {
document.cookie = `token=${json.token}; HTTPOnly=true; max-age=10800`;
this.successfulLogin = true;
this.snackbarEditButton('Home', () => {
this.navigateHome();
this.resetSnackbarButton();
this.showSnackbarNotification = false;
});
this.notification(`Successfully logged into account "${json.user.username}"`);
this.loggedInUser = { username: json.user.username, _id: json.user._id };
return;
}
},
performAccountCreation: async function() {
let jsonData = {
username: this.usernameInput,
email: this.emailInput,
password: this.passwordInput
};
if (this.requiresSpecialCode) {
if (this.mode === 'SIGNUP') {
this.mode = 'SPECIAL_CODE';
return;
} else if (this.mode !== 'SPECIAL_CODE') {
return;
}
jsonData = {
specialCode: this.specialCodeInput,
...jsonData
}
}
2020-10-05 20:36:03 +03:00
const res = await fetch(`${window.location.origin}/api/v1/users/account/create`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(jsonData)
2020-10-05 20:36:03 +03:00
});
const json = await res.json();
console.log(json);
if (json.error || res.status !== 200) {
this.resetSnackbarButton();
this.notification(getSignupMessageFromError(json));
return;
} else {
this.snackbarEditButton('Login', () => {
this.mode = 'LOGIN';
this.resetSnackbarButton();
this.showSnackbarNotification = false;
});
this.notification(`Account "${json.user.username}" successfully created`);
return;
}
}
}
});