mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 05:14:23 +00:00
user account page done (- styling)
This commit is contained in:
@@ -150,7 +150,7 @@ class SQLDB {
|
|||||||
command = 'UPDATE ' + table + ' SET ';
|
command = 'UPDATE ' + table + ' SET ';
|
||||||
let updatedValues = '';
|
let updatedValues = '';
|
||||||
for ( let value in operation.newValues ) {
|
for ( let value in operation.newValues ) {
|
||||||
updatedValues += value + ' = ' + this.sqlConnection.escape( operation.newValues[ value ] ) + ', ';
|
updatedValues += value + ' = ' + this.sqlConnection.escape( String( operation.newValues[ value ] ) ) + ', ';
|
||||||
}
|
}
|
||||||
command += updatedValues.slice( 0, updatedValues.length - 2 );
|
command += updatedValues.slice( 0, updatedValues.length - 2 );
|
||||||
command += ' WHERE ' + operation.property + ' = ' + this.sqlConnection.escape( operation.searchQuery );
|
command += ' WHERE ' + operation.property + ' = ' + this.sqlConnection.escape( operation.searchQuery );
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ module.exports = ( app, settings ) => {
|
|||||||
response.status( 500 ).send( { 'data': 'There was an error reading data from the database. If this error persists, please contact the administrators', 'status': false } );
|
response.status( 500 ).send( { 'data': 'There was an error reading data from the database. If this error persists, please contact the administrators', 'status': false } );
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
console.log( 'unauthorised' );
|
|
||||||
response.status( 403 ).sendFile( path.join( __dirname + '/../ui/en/errors/403.html' ) );
|
response.status( 403 ).sendFile( path.join( __dirname + '/../ui/en/errors/403.html' ) );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
@@ -84,7 +83,7 @@ module.exports = ( app, settings ) => {
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
response.send( 'missingCredentials' );
|
response.status( 400 ).send( 'missingCredentials' );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -101,7 +100,7 @@ module.exports = ( app, settings ) => {
|
|||||||
} else if ( tokType === 'enhanced' ) {
|
} else if ( tokType === 'enhanced' ) {
|
||||||
response.sendFile( path.join( __dirname + '/../ui/en/2fa/2faEnhanced.html' ) );
|
response.sendFile( path.join( __dirname + '/../ui/en/2fa/2faEnhanced.html' ) );
|
||||||
} else {
|
} else {
|
||||||
response.sendFile( path.join( __dirname + '/../ui/en/2fa/2faInvalid.html' ) );
|
response.status( 403 ).sendFile( path.join( __dirname + '/../ui/en/2fa/2faInvalid.html' ) );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -117,7 +116,7 @@ module.exports = ( app, settings ) => {
|
|||||||
authOk[ request.body.token ] = 'ok';
|
authOk[ request.body.token ] = 'ok';
|
||||||
}
|
}
|
||||||
response.send( 'ok' );
|
response.send( 'ok' );
|
||||||
} else response.send( 'wrong' );
|
} else response.status( 403 ).send( 'wrong' );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
app.get( '/user/2fa/check', ( request, response ) => {
|
app.get( '/user/2fa/check', ( request, response ) => {
|
||||||
@@ -148,12 +147,16 @@ module.exports = ( app, settings ) => {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
app.get( '/user/resendEmail', ( req, res ) => {
|
app.get( '/user/resendEmail', ( req, res ) => {
|
||||||
|
if ( req.session.username ) {
|
||||||
( async () => {
|
( async () => {
|
||||||
let tok = generator.generateToken( 60 );
|
let tok = generator.generateToken( 60 );
|
||||||
mailTokens[ tok ] = req.session.username;
|
mailTokens[ tok ] = req.session.username;
|
||||||
mailManager.sendMail( req.session.username, await twoFA.generateSignupEmail( tok, settings.yourDomain, settings.name ), 'Confirm your email', settings.mailSender );
|
mailManager.sendMail( req.session.username, await twoFA.generateSignupEmail( tok, settings.yourDomain, settings.name ), 'Confirm your email', settings.mailSender );
|
||||||
} )();
|
} )();
|
||||||
res.send( 'sent' );
|
res.send( 'sent' );
|
||||||
|
} else {
|
||||||
|
res.status( 403 ).send( 'unauthorised' );
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
app.post( '/user/signup', bodyParser.json(), ( request, response ) => {
|
app.post( '/user/signup', bodyParser.json(), ( request, response ) => {
|
||||||
@@ -202,7 +205,7 @@ module.exports = ( app, settings ) => {
|
|||||||
response.sendFile( path.join( __dirname + '/../ui/en/signup/disallowTwoFA.html' ) );
|
response.sendFile( path.join( __dirname + '/../ui/en/signup/disallowTwoFA.html' ) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
response.sendFile( path.join( __dirname + '/../ui/en/signup/invalid.html' ) );
|
response.status( 400 ).sendFile( path.join( __dirname + '/../ui/en/signup/invalid.html' ) );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -214,7 +217,16 @@ module.exports = ( app, settings ) => {
|
|||||||
response.send( 'ok' );
|
response.send( 'ok' );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
response.send( 'unauthorised' );
|
response.status( 403 ).send( 'unauthorised' );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
app.post( '/user/settings', bodyParser.json(), ( req, res ) => {
|
||||||
|
if ( req.session.username ) {
|
||||||
|
db.writeDataSimple( 'users', 'email', req.session.username, req.body );
|
||||||
|
res.send( 'ok' );
|
||||||
|
} else {
|
||||||
|
res.status( 403 ).send( 'unauthorised' );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { defineStore } from "pinia";
|
|||||||
export const useBackendStore = defineStore ( 'backend', {
|
export const useBackendStore = defineStore ( 'backend', {
|
||||||
state: () => ( { 'guestPurchase': false, 'guestPurchaseAllowed': false } ),
|
state: () => ( { 'guestPurchase': false, 'guestPurchaseAllowed': false } ),
|
||||||
getters: {
|
getters: {
|
||||||
getVisitedSetupPages: ( state ) => state.visitedSetupPages,
|
|
||||||
getIsGuestPurchase: ( state ) => state.guestPurchase,
|
getIsGuestPurchase: ( state ) => state.guestPurchase,
|
||||||
getIsGuestPurchaseAllowed: ( state ) => state.guestPurchaseAllowed,
|
getIsGuestPurchaseAllowed: ( state ) => state.guestPurchaseAllowed,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1>Account</h1>
|
<h1>Account</h1>
|
||||||
<p>Welcome, {{ accountData.first_name }} {{ accountData.name }}!</p>
|
<p>Welcome, {{ accountData.first_name }} {{ accountData.name }}! <button @click="logout()">Log out</button></p>
|
||||||
<button @click="resendMailConfirmation()" v-if="!accountData.mail_confirmed">Resend confirmation email</button>
|
<button @click="resendMailConfirmation()" v-if="!accountData.mail_confirmed">Resend confirmation email</button>
|
||||||
|
<div class="userData-wrapper">
|
||||||
<table class="userData">
|
<table class="userData">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Email
|
Email
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
<div v-if="!isEditingAccount">
|
||||||
{{ accountData.email }}
|
{{ accountData.email }}
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<input type="email" name="email" id="email" v-model="accountData.email" @keyup="emailLiveChecker()"><br><br>
|
||||||
|
<p v-if="emailStatus" class="email-status">{{ emailStatus }}</p>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -17,7 +24,13 @@
|
|||||||
Name
|
Name
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
<div v-if="!isEditingAccount">
|
||||||
{{ accountData.first_name }} {{ accountData.name }}
|
{{ accountData.first_name }} {{ accountData.name }}
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<input type="text" name="first_name" id="first_name" v-model="accountData.first_name">
|
||||||
|
<input type="text" name="name" id="name" v-model="accountData.name">
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -25,21 +38,42 @@
|
|||||||
Email notifications
|
Email notifications
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div v-if="accountData.marketing">Enabled</div>
|
<div v-if="!isEditingAccount">
|
||||||
|
<div v-if="accountData.marketing == 'true'">Enabled</div>
|
||||||
<div v-else>Disabled</div>
|
<div v-else>Disabled</div>
|
||||||
|
</div>
|
||||||
|
<select name="emailNotification" id="emailNotification" v-model="accountData.marketing" v-else>
|
||||||
|
<option value="true">Enabled</option>
|
||||||
|
<option value="false">Disabled</option>
|
||||||
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr v-if="accountData.mail_confirmed && twoFASetting !== 'disable'">
|
||||||
<td>
|
<td>
|
||||||
Two-Factor Authentication
|
Two-Factor Authentication
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
<div v-if="!isEditingAccount">
|
||||||
<div v-if="accountData.two_fa == 'enhanced'">Enhanced</div>
|
<div v-if="accountData.two_fa == 'enhanced'">Enhanced</div>
|
||||||
<div v-else-if="accountData.two_fa == 'standard'">Standard</div>
|
<div v-else-if="accountData.two_fa == 'standard'">Standard</div>
|
||||||
<div v-else>Disabled</div>
|
<div v-else>Disabled</div>
|
||||||
|
</div>
|
||||||
|
<select name="two_fa" id="two_fa" v-model="accountData.two_fa" v-else>
|
||||||
|
<option value="enhanced">Enhanced</option>
|
||||||
|
<option value="standard">Standard</option>
|
||||||
|
<option value="disabled" v-if="twoFASetting === 'allow'">Disabled</option>
|
||||||
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<div>
|
||||||
|
<button @click="toggleEditing">
|
||||||
|
<div v-if="!isEditingAccount">Edit</div>
|
||||||
|
<div v-else>Cancel</div>
|
||||||
|
</button>
|
||||||
|
<button @click="save()" v-if="isEditingAccount">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<notifications ref="notification" location="topright" size="bigger"></notifications>
|
<notifications ref="notification" location="topright" size="bigger"></notifications>
|
||||||
<popups ref="popups" size="big" @data="data => { savePwd( data ) }"></popups>
|
<popups ref="popups" size="big" @data="data => { savePwd( data ) }"></popups>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,9 +87,23 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.userData-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
.userData {
|
.userData {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.email-status {
|
||||||
|
margin-top: -10px;
|
||||||
|
color: red;
|
||||||
|
font-style: italic;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -68,6 +116,9 @@
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
accountData: {},
|
accountData: {},
|
||||||
|
isEditingAccount: false,
|
||||||
|
emailStatus: '',
|
||||||
|
twoFASetting: 'allow',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@@ -78,6 +129,38 @@
|
|||||||
...mapStores( useUserStore )
|
...mapStores( useUserStore )
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
logout() {
|
||||||
|
fetch( '/user/logout' ).then( res => {
|
||||||
|
this.$router.push( '/login' );
|
||||||
|
this.userStore.setUserAuth( false );
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
toggleEditing () {
|
||||||
|
if ( this.isEditingAccount ) {
|
||||||
|
this.loadData();
|
||||||
|
} else {
|
||||||
|
this.emailLiveChecker();
|
||||||
|
}
|
||||||
|
this.isEditingAccount = !this.isEditingAccount;
|
||||||
|
},
|
||||||
|
save() {
|
||||||
|
let fetchOptions = {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify( this.accountData ),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'charset': 'utf-8'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetch( localStorage.getItem( 'url' ) + '/user/settings', fetchOptions ).then( res => {
|
||||||
|
if ( res.status === 200 ) {
|
||||||
|
this.$refs.notification.createNotification( 'Settings updated!', 5, 'ok', 'normal' );
|
||||||
|
this.isEditingAccount = false;
|
||||||
|
} else {
|
||||||
|
this.$refs.notification.createNotification( 'An error occurred whilst updating the settings. Please retry', 20, 'error', 'normal' );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
},
|
||||||
resendMailConfirmation() {
|
resendMailConfirmation() {
|
||||||
fetch( localStorage.getItem( 'url' ) + '/user/resendEmail' ).then( res => {
|
fetch( localStorage.getItem( 'url' ) + '/user/resendEmail' ).then( res => {
|
||||||
if ( res.status === 200 ) {
|
if ( res.status === 200 ) {
|
||||||
@@ -86,19 +169,74 @@
|
|||||||
this.$refs.notification.createNotification( 'An error occurred whilst sending the confirmation mail. Please retry', 20, 'error', 'normal' );
|
this.$refs.notification.createNotification( 'An error occurred whilst sending the confirmation mail. Please retry', 20, 'error', 'normal' );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
},
|
||||||
|
emailLiveChecker () {
|
||||||
|
setTimeout( () => {
|
||||||
|
if ( this.checkEmail() ) {
|
||||||
|
this.emailStatus = '';
|
||||||
|
} else {
|
||||||
|
this.emailStatus = 'Invalid email address';
|
||||||
|
}
|
||||||
|
}, 100 );
|
||||||
|
},
|
||||||
|
checkEmail () {
|
||||||
|
const mail = this.accountData.email ?? '';
|
||||||
|
let stat = { 'atPos': 0, 'topLevelPos': 0 };
|
||||||
|
for ( let l in mail ) {
|
||||||
|
if ( stat[ 'atPos' ] > 0 ) {
|
||||||
|
if ( mail[ l ] === '@' ) {
|
||||||
|
return false;
|
||||||
|
} else if ( mail[ l ] === '.' ) {
|
||||||
|
if ( stat[ 'topLevelPos' ] > 0 ) {
|
||||||
|
if ( l > stat[ 'topLevelPos' ] + 2 ) {
|
||||||
|
stat[ 'topLevelPos' ] = parseInt( l );
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( l > stat[ 'atPos' ] + 2 ) {
|
||||||
|
stat[ 'topLevelPos' ] = parseInt( l );
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ( !( /[a-z]/.test( mail[ l ] ) || /[A-Z]/.test( mail[ l ] ) || /[1-9]/.test( mail[ l ] ) ) ) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( mail[ l ] === '@' ) {
|
||||||
|
if ( l > 2 ) {
|
||||||
|
stat[ 'atPos' ] = parseInt( l );
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if ( !( /[a-z]/.test( mail[ l ] ) || /[A-Z]/.test( mail[ l ] ) || /[1-9]/.test( mail[ l ] ) || mail[ l ] === '.' ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( mail.length > stat[ 'topLevelPos' ] + 2 && stat[ 'topLevelPos' ] > 0 && stat[ 'atPos' ] > 0 ) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
loadData () {
|
||||||
// TODO: FUTURE Also get all orders of user (using join functions)
|
// TODO: FUTURE Also get all orders of user (using join functions)
|
||||||
|
fetch( localStorage.getItem( 'url' ) + '/settings/2fa' ).then( res => {
|
||||||
|
if ( res.status === 200 ) {
|
||||||
|
res.text().then( text => {
|
||||||
|
this.twoFASetting = text;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
} );
|
||||||
fetch( localStorage.getItem( 'url' ) + '/user/details' ).then( res => {
|
fetch( localStorage.getItem( 'url' ) + '/user/details' ).then( res => {
|
||||||
if ( res.status === 200 ) {
|
if ( res.status === 200 ) {
|
||||||
res.json().then( data => {
|
res.json().then( data => {
|
||||||
if ( data.status ) {
|
if ( data.status ) {
|
||||||
this.accountData = data.data;
|
this.accountData = data.data;
|
||||||
if ( this.accountData.marketing ) {
|
if ( !this.accountData.two_fa ) {
|
||||||
this.accountData.marketing = true;
|
this.accountData.two_fa = 'disabled';
|
||||||
} else {
|
|
||||||
this.accountData.marketing = false;
|
|
||||||
}
|
}
|
||||||
if ( !data.data.mail_confirmed ) {
|
if ( !data.data.mail_confirmed ) {
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
@@ -123,5 +261,9 @@
|
|||||||
this.userStore.setUser2fa( false );
|
this.userStore.setUser2fa( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
Reference in New Issue
Block a user