aboutsummaryrefslogtreecommitdiff
path: root/src/api/structures/Setting.js
blob: ff98339e11b3f3476b17a41ebcfa94391a244377 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
require('dotenv').config();

const Joi = require('joi');
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'),

	// Social and sharing
	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({ 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({ 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')
});

module.exports.schema = schema;
module.exports.configSchema = schema.describe();