feat: add sections to settings object meta

This commit is contained in:
Zephyrrus 2021-01-11 12:51:45 +02:00
parent 46ef63fb9f
commit d69fcd856a
3 changed files with 98 additions and 8 deletions

View File

@ -5,65 +5,113 @@ const { env } = process;
const StatsGenerator = require('../utils/StatsGenerator');
const Sections = Object.freeze({
SERVICE: 'Service',
FILE: 'File',
USERS: 'Users',
SOCIAL_AND_SHARING: 'Social and sharing',
INSTANCE: 'Instance',
STATISTICS: 'Statistics',
SERVER: 'Server',
OTHER: 'Other'
});
// use label to name them nicely
// use meta to set custom rendering (render as radio instead of dropdown for example) and custom order
// use description to add comments which will show up as a note somewhere next to the option
const schema = Joi.object({
// Service settings
serviceName: Joi.string().default('change-me')
// .meta({ section })
.meta({
section: Sections.SERVICE
})
.label('Service name')
.description('Name of the service'),
domain: Joi.string().default(`http://localhost:${env.SERVER_PORT}`)
.meta({
section: Sections.SERVICE
})
.label('Domain')
.description('Full domain this instance is gonna be running on'),
// File related settings
chunkSize: Joi.number().integer().greater(0)
.default(90)
.meta({
section: Sections.FILE
})
.label('Chunk size')
.description('Maximum size of a chunk (files bigger than this limit will be split into multiple chunks)'),
maxSize: Joi.number().integer().min(0) // setting it to 0 disabled the limit
.default(5000)
.meta({
section: Sections.FILE
})
.label('Maximum file size')
.description('Maximum allowed upload file size in MB (0 to disable)'),
generateZips: Joi.boolean().default(true)
.meta({
section: Sections.FILE
})
.label('Generate zips')
.description('Allows users to download entire albums in ZIP format'),
generatedFileNameLength: Joi.number().integer().min(6)
.default(12)
.meta({
section: Sections.FILE
})
.label('Generated file name length')
.description('How long should the automatically generated file name be'),
generatedAlbumLength: Joi.number().integer().min(6)
.default(6)
.meta({
section: Sections.FILE
})
.label('Generated album name length')
.description('How long should the automatically generated album identifier be'),
maxLinksPerAlbum: Joi.number().integer().greater(0)
.default(5)
.meta({
section: Sections.FILE
})
.label('Maximum album links')
.description('Maximum allowed number of a distinct links for an album'),
uploadsFolder: Joi.string().default('uploads')
.meta({
section: Sections.FILE
})
.label('Uploads folder')
.description('Name of the folder where the uploads will be stored'),
blockedExtensions: Joi.array()
.items(Joi.string().pattern(/^(\.\w+)+$/, { name: 'file extension' }))
.default(['.jar', '.exe', '.msi', '.com', '.bat', '.cmd', '.scr', '.ps1', '.sh'])
.meta({
section: Sections.FILE
})
.label('Blocked extensions')
.description('List of extensions which will be rejected by the server'),
// User settings
publicMode: Joi.boolean().default(true)
.meta({
section: Sections.USERS
})
.label('Public mode')
.description('Allows people to upload files without an account'),
userAccount: Joi.boolean().default(true)
.meta({
section: Sections.USERS
})
.label('User creation')
.description('Allows people to create new accounts'),
@ -71,53 +119,76 @@ const schema = Joi.object({
metaThemeColor: Joi.string().hex().min(3)
.max(6)
.default('20222b')
.meta({
section: Sections.SOCIAL_AND_SHARING
})
.label('Meta theme color')
.description('Color that user agents should use to customize the display of the page/embeds'),
metaDescription: Joi.string().default('Blazing fast file uploader and bunker written in node! 🚀')
.meta({
section: Sections.SOCIAL_AND_SHARING
})
.label('Meta description')
.description('Short and accurate summary of the content of the page'),
metaKeyword: Joi.string().default('chibisafe,lolisafe,upload,uploader,file,vue,images,ssr,file uploader,free')
.meta({
section: Sections.SOCIAL_AND_SHARING
})
.label('Meta keywords')
.description('Words relevant to the page\'s content separated by commas'),
metaTwitterHandle: Joi.string().pattern(/^@\w{1,15}$/, { name: 'twitter handle' })
.meta({
section: Sections.SOCIAL_AND_SHARING
})
.label('Twitter handle')
.description('Your twitter handle'),
// Instance settings
backgroundImageURL: Joi.string().uri().default(p => `${p.domain}/assets/images/background.jpg`)
.meta({
section: Sections.INSTANCE
})
.label('Background image link')
.description('Background image that should be used instead of the default background'),
logoURL: Joi.string().uri().default(p => `${p.domain}/assets/images/logo.jpg`)
.meta({
section: Sections.INSTANCE
})
.label('Logo image link')
.description('Logo image that should be used instead of the default logo'),
// Statistics settings
// TODO: Pattern fails for patterns like 0 1,2-7 * * * * because of the mixing of lists and ranges
statisticsCron: Joi.string().pattern(/((((\d+,)+\d+|([\d\*]+(\/|-)\d+)|\d+|\*) ?){6})/, { name: 'cron' }).default('0 0 * * * *')
.meta({
section: Sections.STATISTICS
})
.label('Statistics schedule')
.description('Crontab like formated value which will be used to schedule generating and saving stats to the database'),
enabledStatistics: Joi.array().items(Joi.string().valid(...Object.keys(StatsGenerator.statGenerators)).optional())
.meta({ displayType: 'checkbox' })
.meta({ section: Sections.STATISTICS, displayType: 'checkbox' })
.label('Enabled statistics')
.description('Which statistics should be shown when opening the statistics page'),
savedStatistics: Joi.array().items(Joi.string().valid(...Object.keys(StatsGenerator.statGenerators)).optional())
.meta({ displayType: 'checkbox' })
.meta({ section: Sections.STATISTICS, displayType: 'checkbox' })
.label('Cached statistics')
.description('Which statistics should be saved to the database (refer to Statistics schedule for scheduling).')
.note('If a statistics is enabled but not set to be saved, it will be generated every time the statistics page is opened'),
// Server related settings
rateLimitWindow: Joi.number().integer().default(2)
.meta({ section: Sections.SERVER })
.label('API rate limit window')
.description('Timeframe for which requests are checked/remembered'),
rateLimitMax: Joi.number().integer().default(5)
.meta({ section: Sections.SERVER })
.label('API maximum limit')
.description('Max number of connections during windowMs milliseconds before sending a 429 response')
});

View File

@ -25,6 +25,7 @@
:rounded="false"
:true-value="true"
:false-value="false" />
<!-- TODO: If array and has allowed items, limit input to those items only -->
<b-taginput
v-else-if="getDisplayType(field) === 'array' || getDisplayType(field) === 'tagInput'"
v-model="settings.arr"
@ -76,7 +77,7 @@ export default {
};
},
mounted() {
// TODO: Implement merging fields with values from the db (no endpoint to fetch settings yet)
},
methods: {
getMin(field) {

View File

@ -11,7 +11,8 @@
</h2>
<hr>
<JoiObject :keys="settingsSchema.keys" :values="{}" />
<!-- TODO: IMPLEMENT SECTIONS (v-for JoiObject for each section maybe?) -->
<JoiObject :keys="sectionedSettings" :values="{}" />
</div>
</div>
</div>
@ -31,16 +32,33 @@ export default {
middleware: ['auth', 'admin', ({ store }) => {
try {
store.dispatch('admin/fetchSettings');
// TODO: Implement merging fields with values from the db (no endpoint to fetch settings yet)
store.dispatch('admin/getSettingsSchema');
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
}],
computed: mapState({
settings: state => state.admin.settings,
settingsSchema: state => state.admin.settingsSchema
}),
computed: {
...mapState({
settings: state => state.admin.settings,
settingsSchema: state => state.admin.settingsSchema
}),
sectionedSettings() {
return Object.entries(this.settings).reduce((acc, { key, field }) => {
if (!field.meta) acc['Other'] = { ...acc['Other'], [key]: field };
const { sectionName } = field.metas.find(e => e.sectionName);
if (sectionName) {
acc[sectionName] = { ...acc[sectionName], [key]: field };
} else {
acc['Other'] = { ...acc['Other'], [key]: field };
}
return acc;
}, {});
}
},
methods: {
promptRestartService() {
this.$buefy.dialog.confirm({