setup app complete

This commit is contained in:
2023-09-08 16:26:37 +02:00
parent 809a05c864
commit defaafdd54
12 changed files with 172 additions and 45 deletions

View File

@@ -9,13 +9,11 @@
const db = require( '../../backend/db/db.js' );
const pwdmanager = require( '../pwdmanager.js' );
const fs = require( 'fs' );
const path = require( 'path' );
const pm = require( '../../backend/plugins/manager.js' );
const spm = require( '../startPageManager.js' );
const startPageManager = new spm();
const letters = [ ',', '{' ];
class POSTHandler {
constructor ( settings ) {
@@ -154,18 +152,7 @@ class POSTHandler {
this.settings[ 'currency' ] = data.currency;
this.settings[ 'payments' ] = data.payments;
this.settings[ 'ticketTimeout' ] = data.ticketTimeout;
const settingsString = JSON.stringify( this.settings );
let settingsToSave = '';
for ( let letter in settingsString ) {
if ( letters.includes( settingsString[ letter ] ) ) {
settingsToSave += settingsString[ letter ] + '\n\t';
} else if ( settingsString[ letter ] === '}' ) {
settingsToSave += '\n' + settingsString[ letter ];
} else {
settingsToSave += settingsString[ letter ];
}
}
fs.writeFileSync( path.join( __dirname + '/../../config/settings.config.json' ), settingsToSave );
db.saveSettings( this.settings );
db.getJSONData( 'events' ).then( dat => {
let updated = dat;
for ( let event in updated ) {

View File

@@ -39,7 +39,8 @@ module.exports = ( app ) => {
if ( tickets[ event ] ) {
if ( tickets[ event ][ ticket ] ) {
if ( !tickets[ event ][ ticket ][ 'invalidated' ] ) {
// TODO: invalidate ticket!
tickets[ event ][ ticket ][ 'invalidated' ] = true;
db.writeDataSimple( 'orders', 'order_name', req.body.ticketID.slice( 0, req.body.ticketID.indexOf( '_' ) ), { 'tickets': JSON.stringify( tickets ) } );
res.send( 'ticketValid' );
} else {
res.send( 'ticketInvalid' );

View File

@@ -11,6 +11,7 @@ let createSSRApp = require( 'vue' ).createSSRApp;
let renderToString = require( 'vue/server-renderer' ).renderToString;
const fs = require( 'fs' );
const path = require( 'path' );
const db = require( '../backend/db/db.js' );
class StartPageManager {
constructor ( settings ) {
@@ -42,7 +43,7 @@ class StartPageManager {
setActiveStartPage( startPageName ) {
this.settings[ 'startPage' ] = startPageName;
fs.writeFileSync( path.join( __dirname + '/../config/settings.config.json' ), JSON.stringify( this.settings ) );
db.saveSettings( this.settings );
}
async renderStartPage( startPageName ) {

View File

@@ -15,6 +15,7 @@ const cookieParser = require( 'cookie-parser' );
const http = require( 'http' );
const fs = require( 'fs' );
const token = require( './backend/token.js' );
const db = require( './backend/db/db.js' );
console.log( `
@@ -58,7 +59,12 @@ if ( settings.setupDone ) {
} );
}
// TODO: If no init, initialize DB.
if ( !settings.init ) {
db.initDB();
let mutSettings = settings;
mutSettings[ 'init' ] = true;
db.saveSettings( mutSettings );
}
// Set up static routes for static file serving (performance wise not

View File

@@ -14,6 +14,8 @@ const settings = JSON.parse( fs.readFileSync( path.join( __dirname + '/../../con
const dbRef = { 'user': 'libreevent_users', 'admin': 'libreevent_admin', 'order': 'libreevent_orders', 'users': 'libreevent_users', 'orders': 'libreevent_orders', 'temp': 'libreevent_temp' };
const letters = [ ',', '{' ];
let dbh;
if ( settings.db === 'mysql' ) {
@@ -26,6 +28,14 @@ if ( settings.db === 'mysql' ) {
dbh.connect();
}
module.exports.initDB = () => {
( async() => {
console.log( '[ DB ] Setting up...' );
await dbh.setupDB();
console.log( '[ DB ] Setting up complete!' );
} )();
};
module.exports.getDataSimple = ( db, column, searchQuery ) => {
return new Promise( ( resolve, reject ) => {
dbh.query( { 'command': 'getFilteredData', 'property': column, 'searchQuery': searchQuery }, dbRef[ db ] ).then( data => {
@@ -185,6 +195,21 @@ module.exports.deleteJSONDataSimple = ( db, identifier ) => {
} );
};
module.exports.saveSettings = ( settings ) => {
const settingsString = JSON.stringify( settings );
let settingsToSave = '';
for ( let letter in settingsString ) {
if ( letters.includes( settingsString[ letter ] ) ) {
settingsToSave += settingsString[ letter ] + '\n\t';
} else if ( settingsString[ letter ] === '}' ) {
settingsToSave += '\n' + settingsString[ letter ];
} else {
settingsToSave += settingsString[ letter ];
}
}
fs.writeFileSync( path.join( __dirname + '/../../config/settings.config.json' ), settingsToSave );
};
const gc = () => {
// this function acts as the database garbage collector. TicketTimeout can be changed from the GUI.
this.getData( 'temp' ).then( tempData => {

View File

@@ -22,7 +22,10 @@ class JSONDB {
let data = {};
try {
JSON.parse( fs.readFileSync( path.join( __dirname + '/data/db.json' ) ) );
} catch ( err ) {}
} catch ( err ) {
console.error( '[ JSON-DB ] CRITICAL INITIALIZATION FAILURE!' + err );
throw ( 'JSONDB failed to start!' );
}
this.db = data[ 'db' ] ?? { 'libreevent_temp': {}, 'libreevent_admin': {}, 'libreevent_orders': {}, 'libreevent_users': {} };
this.dbIndex = data[ 'index' ] ?? { 'libreevent_temp': 0, 'libreevent_admin': 0, 'libreevent_orders': 0, 'libreevent_users': 0 };
this.db[ 'libreevent_temp' ] = {};

View File

@@ -1,13 +1,13 @@
{
"init":false,
"setupDone": true,
"init":true,
"setupDone":true,
"twoFA":"enforce",
"twoFAMode":"enhanced",
"db":"mysql",
"payments":"stripe",
"name":"libreevent",
"yourDomain":"http://localhost:8080",
"mailSender":"libreevent <info@libreevent.janishutz.com>",
"mailSender":"libreevent <no-reply@libreevent.janishutz.com>",
"maxTickets":10,
"currency":"CHF",
"gcInterval":300,

View File

@@ -7,7 +7,9 @@
*
*/
let db = null;
// let db = null;
let db = require( '../backend/db/db.js' );
const pwm = require( '../admin/pwdmanager.js' );
const fs = require( 'fs' );
const path = require( 'path' );
const bodyParser = require( 'body-parser' );
@@ -30,7 +32,38 @@ module.exports = ( app, settings ) => {
if ( req.session.setupKeyOk ) {
res.send( 'ok' );
} else {
res.status( 403 ).send( 'not authorized' );
res.status( 403 ).send( 'unauthorized' );
}
} );
app.post( '/setup/saveBasicSettings', bodyParser.json(), ( req, res ) => {
if ( req.session.setupKeyOk ) {
fs.writeFileSync( path.join( __dirname + '/../config/db.config.json' ), JSON.stringify( req.body.db ) );
fs.writeFileSync( path.join( __dirname + '/../config/mail.config.json' ), JSON.stringify( req.body.email ) );
if ( db === null ) {
db = require( '../backend/db/db.js' );
}
let updatedSettings = settings;
updatedSettings[ 'name' ] = req.body.websiteName;
updatedSettings[ 'mailSender' ] = req.body.mailDisplay;
db.saveSettings( updatedSettings );
res.send( 'ok' );
} else {
res.status( 403 ).send( 'unauthorized' );
}
} );
app.post( '/setup/saveRootAccount', bodyParser.json(), ( req, res ) => {
if ( req.session.setupKeyOk ) {
pwm.hashPassword( req.body.password ).then( hash => {
db.writeJSONData( 'rootAccount', { 'pass': hash, 'email': req.body.mail } );
let updatedSettings = settings;
updatedSettings[ 'setupDone' ] = true;
db.saveSettings( updatedSettings );
res.send( 'ok' );
} );
} else {
res.status( 403 ).send( 'unauthorized' );
}
} );

View File

@@ -5,7 +5,7 @@
</div>
</template>
<style>
<style scoped>
.wrapper {
width: 100%;
height: 100%;

View File

@@ -29,7 +29,7 @@
<option value="json">JSON-Database</option>
</select>
<form v-if="formData.dbType === 'mysql'">
<label for="host">Database host name</label><br>
<label for="host">Database host name (usually domain name or IP of webserver)</label><br>
<input type="url" name="host" id="host" v-model="formData.db.host"><br>
<label for="database">Database name</label><br>
<input type="text" name="database" id="database" v-model="formData.db.database"><br>
@@ -70,6 +70,7 @@
</form>
<button @click="submit()" class="button">Continue</button>
</div>
<notifications ref="notification" location="topright" size="bigger"></notifications>
</div>
</template>
@@ -82,8 +83,12 @@
<script>
import { useBackendStore } from '@/stores/backendStore.js';
import { mapStores } from 'pinia';
import notifications from '../components/notifications.vue';
export default {
components: {
notifications,
},
data () {
return {
formData: {
@@ -102,10 +107,46 @@
...mapStores( useBackendStore )
},
methods: {
submit () {
submit() {
if ( this.formData.dbType === 'mysql' ) {
if ( !this.formData.db.port || !this.formData.db.host || !this.formData.db.database || !this.formData.db.user || !this.formData.db.password ) {
this.$refs.notification.createNotification( 'Database settings are not complete!', 5, 'error', 'normal' );
return;
}
}
if( this.formData.email.port && this.formData.email.host && this.formData.email.user && this.formData.email.pass
&& this.formData.dpEmail && this.formData.display && this.formData.websiteName ) {
this.formData.mailDisplay = this.formData.display + ' <' + this.formData.dpEmail + '>';
const options = {
method: 'post',
body: JSON.stringify( this.formData ),
headers: {
'Content-Type': 'application/json',
'charset': 'utf-8'
}
};
fetch( '/setup/saveBasicSettings', options ).then( res => {
if ( res.status === 200 ) {
this.continue();
} else {
this.$refs.notification.createNotification( 'Setup key incorrect!', 5, 'error', 'normal' );
}
} );
} else {
this.$refs.notification.createNotification( 'Missing entries', 5, 'error', 'normal' );
return;
}
},
continue () {
sessionStorage.setItem( 'basics', JSON.stringify( this.formData ) );
this.backendStore.addVisitedSetupPages( 'root', true );
this.$router.push( '/setup/root' );
}
},
created () {
if ( sessionStorage.getItem( 'basics' ) ) {
this.formData = JSON.parse( sessionStorage.getItem( 'basics' ) );
}
}
};
</script>

View File

@@ -20,11 +20,13 @@
<a href="https://libreevent.janishutz.com/docs/setup/afterSetup" target="_blank">here</a></p>
<div class="list-wrapper">
<ul>
<li>Customize the start page</li>
<li>Choose a payment gateway and set it up</li>
<li>Create a event location and an event</li>
<li>Create other admin accounts with less privileges</li>
</ul>
</div>
<button class="button" @click="cleanup()">Done</button>
</div>
</div>
</template>
@@ -47,5 +49,12 @@
windowURL: location.protocol + '//' + location.host +'/admin/login',
}
},
methods: {
cleanup() {
sessionStorage.removeItem( 'basics' );
sessionStorage.removeItem( 'root' );
this.$router.push( '/admin/login' );
}
}
};
</script>

View File

@@ -154,10 +154,12 @@
}
}
} else {
if ( confirm( 'Do you really want to proceed without having your password checked?' ) ) {
if ( confirm( 'Do you really want to proceed without having your password checked? This is strongly discouraged as it essentially removes the first factor (the password) of the authentication making it much less secure.' ) ) {
if ( confirm( 'Are you really sure?' ) ) {
this.proceed();
}
}
}
} else {
this.$refs.notification.createNotification( 'Passwords do not match', 10, 'error', 'normal' );
}
@@ -169,11 +171,30 @@
}
},
proceed () {
// TODO: Perform checks
const options = {
method: 'post',
body: JSON.stringify( this.formData ),
headers: {
'Content-Type': 'application/json',
'charset': 'utf-8'
}
};
fetch( '/setup/saveRootAccount', options ).then( res => {
if ( res.status === 200 ) {
sessionStorage.setItem( 'basics', JSON.stringify( this.formData ) );
this.backendStore.addVisitedSetupPages( 'complete', true );
this.$router.push( 'complete' );
} else {
this.$refs.notification.createNotification( 'Setup key incorrect!', 5, 'error', 'normal' );
}
} );
},
},
created () {
if ( sessionStorage.getItem( 'root' ) ) {
this.formData = JSON.parse( sessionStorage.getItem( 'root' ) );
}
}
};
</script>