mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
more rules for frontend, all rules
This commit is contained in:
parent
5ca51a9941
commit
833890e0ba
@ -1,13 +1,13 @@
|
||||
const Joi = require('joi')
|
||||
|
||||
module.exports = Joi.object({
|
||||
module.exports = {
|
||||
BROWSER_PROTOCOL: Joi.string()
|
||||
.valid('http', 'https')
|
||||
.description(
|
||||
'Protocol for all URLs in the browser, must be either http or https to prevent mixed content issues.',
|
||||
)
|
||||
.default('http')
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
COMMUNITY_URL: Joi.string()
|
||||
.uri({ scheme: ['http', 'https'] })
|
||||
@ -18,7 +18,7 @@ module.exports = Joi.object({
|
||||
})
|
||||
.description('The base URL of the community, should have the same scheme like frontend, admin and backend api to prevent mixed contend issues.')
|
||||
.default('http://0.0.0.0')
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
GRAPHQL_URI: Joi.string()
|
||||
.uri({ scheme: ['http', 'https'] })
|
||||
@ -35,59 +35,61 @@ module.exports = Joi.object({
|
||||
`,
|
||||
)
|
||||
.default('http://0.0.0.0/graphql')
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
COMMUNITY_NAME: Joi.string()
|
||||
.min(3)
|
||||
.max(100)
|
||||
.description('The name of the community')
|
||||
.default('Gradido Entwicklung')
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
COMMUNITY_DESCRIPTION: Joi.string()
|
||||
.min(10)
|
||||
.max(300)
|
||||
.description('A short description of the community')
|
||||
.default('Die lokale Entwicklungsumgebung von Gradido.')
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
COMMUNITY_SUPPORT_MAIL: Joi.string()
|
||||
.email()
|
||||
.description('The support email address for the community will be used in frontend and E-Mails')
|
||||
.default('support@supportmail.com')
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
COMMUNITY_LOCATION: Joi.string()
|
||||
.pattern(/^[-+]?[0-9]{1,2}(\.[0-9]+)?,\s?[-+]?[0-9]{1,3}(\.[0-9]+)?$/)
|
||||
// TODO: ask chatgpt for the correct way
|
||||
.when('GMS_ACTIVE', {
|
||||
is: true,
|
||||
then: Joi.string().require(),
|
||||
then: Joi.string().required(),
|
||||
otherwise: Joi.string().optional()
|
||||
})
|
||||
.description('Geographical location of the community in "latitude, longitude" format')
|
||||
.default('49.280377, 9.690151')
|
||||
.require(),
|
||||
.default('49.280377, 9.690151'),
|
||||
|
||||
GRAPHIQL: Joi.boolean()
|
||||
.description('Flag for enabling graphql playground for debugging.')
|
||||
.default(false)
|
||||
.require(), // todo: only allow true in development mode
|
||||
GRAPHIQL: Joi.boolean()
|
||||
.description('Flag for enabling GraphQL playground for debugging.')
|
||||
.default(false)
|
||||
.when('NODE_ENV', {
|
||||
is: 'development',
|
||||
then: Joi.boolean().valid(true).required(), // only allow true in development mode
|
||||
otherwise: Joi.boolean().valid(false).required() // false in any other mode
|
||||
}),
|
||||
|
||||
GMS_ACTIVE: Joi.boolean()
|
||||
.description('Flag to indicate if the GMS (Geographic Member Search) service is used.')
|
||||
.default(false)
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
HUMHUB_ACTIVE: Joi.boolean()
|
||||
.description('Flag to indicate if the HumHub based Community Server is used.')
|
||||
.default(false)
|
||||
.require(),
|
||||
.required(),
|
||||
|
||||
LOG_LEVEL: Joi.string()
|
||||
.valid(['INFO', 'ERROR']) // TODO: lookup values
|
||||
.valid('all', 'mark', 'trace', 'debug', 'info', 'warn', 'error', 'fatal', 'off')
|
||||
.description('set log level')
|
||||
.default('INFO')
|
||||
.default('info')
|
||||
.required(),
|
||||
|
||||
DB_HOST: Joi.string()
|
||||
@ -96,27 +98,80 @@ module.exports = Joi.object({
|
||||
.default('localhost')
|
||||
.required(),
|
||||
|
||||
DB_PORT: Joi.number()
|
||||
.integer()
|
||||
.min(1024)
|
||||
.max(49151)
|
||||
.description('database port, default: 3306')
|
||||
.default(3306)
|
||||
.required(),
|
||||
DB_PORT: Joi.number()
|
||||
.integer()
|
||||
.min(1024)
|
||||
.max(49151)
|
||||
.description('database port, default: 3306')
|
||||
.default(3306)
|
||||
.required(),
|
||||
|
||||
// TODO: check allowed users for mariadb
|
||||
DB_USER: Joi.string()
|
||||
.description('database user name like root (default) or gradido')
|
||||
.default('root')
|
||||
.required(),
|
||||
|
||||
DB_USER: Joi.string()
|
||||
.pattern(/^[A-Za-z0-9]([A-Za-z0-9-_\.]*[A-Za-z0-9])?$/) // Validates MariaDB username rules
|
||||
.min(1) // Minimum length 1
|
||||
.max(16) // Maximum length 16
|
||||
.message(
|
||||
'Valid database username (letters, numbers, hyphens, underscores, dots allowed; no spaces, must not start or end with hyphen, dot, or underscore)'
|
||||
)
|
||||
.description('database username for mariadb')
|
||||
.default('root')
|
||||
.required(),
|
||||
|
||||
DB_PASSWORD: Joi.string()
|
||||
.description('database password')
|
||||
.default('')
|
||||
.required(),
|
||||
DB_PASSWORD: Joi.string()
|
||||
.when(Joi.ref('NODE_ENV'), {
|
||||
is: 'development',
|
||||
then: Joi.string().allow(''),
|
||||
otherwise: Joi.string()
|
||||
.min(8)
|
||||
.max(32)
|
||||
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>]).+$/)
|
||||
.message(
|
||||
'Password must be between 8 and 32 characters long, and contain at least one uppercase letter, one lowercase letter, one number, and one special character (e.g., !@#$%^&*).'
|
||||
)
|
||||
})
|
||||
.description(
|
||||
'Password for the database user. In development mode, an empty password is allowed. In other environments, a complex password is required.'
|
||||
)
|
||||
.default('')
|
||||
.required(),
|
||||
|
||||
DB_DATABASE: Joi.string()
|
||||
.description('database name like gradido_community')
|
||||
.default('gradido_community')
|
||||
.required(),
|
||||
})
|
||||
DB_DATABASE: Joi.string()
|
||||
.pattern(/^[a-zA-Z][a-zA-Z0-9_-]{1,63}$/)
|
||||
.description('Database name like gradido_community (must start with a letter, and can only contain letters, numbers, underscores, or dashes)')
|
||||
.default('gradido_community')
|
||||
.required(),
|
||||
|
||||
APP_VERSION: Joi.string()
|
||||
.pattern(/^\d+\.\d+\.\d+$/)
|
||||
.message('Version must be in the format "major.minor.patch" (e.g., "2.4.1")')
|
||||
.description('App Version from package.json, alle modules share one version')
|
||||
.required(),
|
||||
|
||||
BUILD_COMMIT: Joi.string()
|
||||
.pattern(/^[0-9a-f]{40}$/)
|
||||
.message('The commit hash must be a 40-character hexadecimal string.')
|
||||
.description('The full git commit hash.')
|
||||
.optional(),
|
||||
|
||||
BUILD_COMMIT_SHORT: Joi.string()
|
||||
.pattern(/^[0-9a-f]{7}$/)
|
||||
.message('The first 7 hexadecimal character from git commit hash.')
|
||||
.description('A short version from the git commit hash.')
|
||||
.required(),
|
||||
|
||||
NODE_ENV: Joi.string()
|
||||
.valid('production', 'development')
|
||||
.default('development')
|
||||
.description('Specifies the environment in which the application is running, "production" or "development".'),
|
||||
|
||||
DEBUG: Joi.boolean()
|
||||
.description('Indicates whether the application is in debugging mode. Set to true when NODE_ENV is not "production".')
|
||||
.default(false)
|
||||
.required(),
|
||||
|
||||
PRODUCTION: Joi.boolean()
|
||||
.default(false)
|
||||
.description('Indicates whether the application is running in production mode. Set to true when NODE_ENV is "production".')
|
||||
.required(),
|
||||
}
|
||||
@ -117,7 +117,6 @@ NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf
|
||||
NGINX_REWRITE_LEGACY_URLS=false
|
||||
|
||||
# LEGACY
|
||||
DEFAULT_PUBLISHER_ID=2896
|
||||
WEBHOOK_ELOPAGE_SECRET=secret
|
||||
|
||||
# GMS
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
# Environment
|
||||
DEFAULT_PUBLISHER_ID=2896
|
||||
|
||||
# Endpoints
|
||||
GRAPHQL_PATH=/graphql
|
||||
ADMIN_AUTH_PATH=/admin/authenticate?token={token}
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
CONFIG_VERSION=$FRONTEND_CONFIG_VERSION
|
||||
|
||||
# Environment
|
||||
DEFAULT_PUBLISHER_ID=$DEFAULT_PUBLISHER_ID
|
||||
|
||||
# Endpoints
|
||||
GRAPHQL_PATH=$GRAPHQL_PATH
|
||||
ADMIN_AUTH_PATH=$ADMIN_AUTH_PATH
|
||||
|
||||
@ -4,18 +4,19 @@
|
||||
// Load Package Details for some default values
|
||||
const pkg = require('../../package')
|
||||
const schema = require('./schema')
|
||||
const joi = require('joi')
|
||||
// const joi = require('joi')
|
||||
|
||||
const constants = {
|
||||
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
||||
}
|
||||
|
||||
const version = {
|
||||
BROWSER_PROTOCOL: process.env.BROWSER_PROTOCOL ?? 'http',
|
||||
FRONTEND_MODULE_PROTOCOL: process.env.FRONTEND_MODULE_PROTOCOL ?? 'http',
|
||||
FRONTEND_MODULE_HOST: process.env.FRONTEND_MODULE_HOST ?? '0.0.0.0',
|
||||
FRONTEND_MODULE_PORT: process.env.FRONTEND_MODULE_PORT ?? '3000',
|
||||
APP_VERSION: pkg.version,
|
||||
BUILD_COMMIT: process.env.BUILD_COMMIT ?? null,
|
||||
BUILD_COMMIT: process.env.BUILD_COMMIT ?? undefined,
|
||||
// self reference of `version.BUILD_COMMIT` is not possible at this point, hence the duplicate code
|
||||
BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT ?? '0000000').slice(0, 7),
|
||||
}
|
||||
@ -47,7 +48,6 @@ const environment = {
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
DEBUG: process.env.NODE_ENV !== 'production' ?? false,
|
||||
PRODUCTION: process.env.NODE_ENV === 'production' ?? false,
|
||||
DEFAULT_PUBLISHER_ID: process.env.DEFAULT_PUBLISHER_ID ?? 2896,
|
||||
}
|
||||
|
||||
// const COMMUNITY_HOST = process.env.COMMUNITY_HOST ?? 'localhost'
|
||||
@ -91,7 +91,6 @@ const meta = {
|
||||
}
|
||||
|
||||
const CONFIG = {
|
||||
...constants,
|
||||
...version,
|
||||
...features,
|
||||
...environment,
|
||||
@ -100,8 +99,24 @@ const CONFIG = {
|
||||
...meta,
|
||||
}
|
||||
|
||||
// Check config
|
||||
// Check config
|
||||
// TODO: use validate and construct error message including description
|
||||
joi.attempt(CONFIG, schema)
|
||||
// joi.attempt(CONFIG, schema)
|
||||
|
||||
module.exports = CONFIG
|
||||
const { error } = schema.validate(CONFIG, { stack: true, debug: true })
|
||||
const schemaJson = schema.describe()
|
||||
if (error) {
|
||||
error.details.forEach((err) => {
|
||||
const key = err.context.key
|
||||
const description = schemaJson.keys[key]
|
||||
? schema.describe().keys[key].flags.description
|
||||
: 'No description available'
|
||||
if (CONFIG[key] === undefined) {
|
||||
throw new Error(`Environment Variable '${key}' is missing. ${description}`)
|
||||
} else {
|
||||
throw new Error(`Error on Environment Variable '${key}': ${err.message}. ${description}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { ...CONFIG, ...constants }
|
||||
|
||||
@ -1,12 +1,67 @@
|
||||
const commonSchema = require('../../../config/common.schema')
|
||||
import {
|
||||
APP_VERSION,
|
||||
BROWSER_PROTOCOL,
|
||||
BUILD_COMMIT,
|
||||
BUILD_COMMIT_SHORT,
|
||||
COMMUNITY_DESCRIPTION,
|
||||
COMMUNITY_NAME,
|
||||
COMMUNITY_SUPPORT_MAIL,
|
||||
COMMUNITY_LOCATION,
|
||||
COMMUNITY_URL,
|
||||
DEBUG,
|
||||
GMS_ACTIVE,
|
||||
GRAPHQL_URI,
|
||||
HUMHUB_ACTIVE,
|
||||
NODE_ENV,
|
||||
PRODUCTION,
|
||||
} from '../../../config/common.schema'
|
||||
const Joi = require('joi')
|
||||
|
||||
module.exports = commonSchema.keys({
|
||||
// console.log(commonSchema)
|
||||
|
||||
module.exports = Joi.object({
|
||||
APP_VERSION,
|
||||
BROWSER_PROTOCOL,
|
||||
BUILD_COMMIT,
|
||||
BUILD_COMMIT_SHORT,
|
||||
COMMUNITY_DESCRIPTION,
|
||||
COMMUNITY_NAME,
|
||||
COMMUNITY_SUPPORT_MAIL,
|
||||
COMMUNITY_LOCATION,
|
||||
COMMUNITY_URL,
|
||||
DEBUG,
|
||||
GMS_ACTIVE,
|
||||
GRAPHQL_URI,
|
||||
HUMHUB_ACTIVE,
|
||||
NODE_ENV,
|
||||
PRODUCTION,
|
||||
|
||||
ADMIN_AUTH_URL: Joi.string()
|
||||
.uri({ scheme: ['http', 'https'] })
|
||||
.when('browser_protocol', {
|
||||
is: 'https',
|
||||
then: Joi.string().uri({ scheme: 'https' }),
|
||||
otherwise: Joi.string().uri({ scheme: 'http' }),
|
||||
})
|
||||
.description('Extern Url for admin-frontend')
|
||||
.default('http://0.0.0.0/admin/authenticate?token=')
|
||||
.required(),
|
||||
|
||||
COMMUNITY_REGISTER_URL: Joi.string()
|
||||
.uri({ scheme: ['http', 'https'] })
|
||||
.when('browser_protocol', {
|
||||
is: 'https',
|
||||
then: Joi.string().uri({ scheme: 'https' }),
|
||||
otherwise: Joi.string().uri({ scheme: 'http' }),
|
||||
})
|
||||
.description('URL for Register a new Account in frontend.')
|
||||
.required(),
|
||||
|
||||
FRONTEND_MODULE_PROTOCOL: Joi.string()
|
||||
.valid('http', 'https')
|
||||
.when('BROWSER_PROTOCOL', {
|
||||
is: 'https',
|
||||
then: Joi.string().uri({ scheme: 'https' }),
|
||||
then: Joi.string().uri({ scheme: 'https' }),
|
||||
otherwise: Joi.string().uri({ scheme: 'http' }),
|
||||
})
|
||||
.description(
|
||||
@ -14,7 +69,7 @@ module.exports = commonSchema.keys({
|
||||
)
|
||||
.default('http')
|
||||
.required(),
|
||||
|
||||
|
||||
FRONTEND_HOSTING: Joi.string()
|
||||
.valid('nodejs')
|
||||
.description('set to `nodejs` if frontend is hosted by vite with a own nodejs instance')
|
||||
@ -26,13 +81,22 @@ module.exports = commonSchema.keys({
|
||||
Joi.string()
|
||||
.ip({ version: ['ipv4'] })
|
||||
.messages({ 'string.ip': 'Must be a valid IPv4 address' }),
|
||||
Joi.string().domain().messages({ 'string.domain': 'Must be a valid domain' }),
|
||||
Joi.string().domain().messages({ 'string.domain': 'Must be a valid domain' })
|
||||
)
|
||||
.when('FRONTEND_HOSTING', {
|
||||
is: 'nodejs',
|
||||
then: Joi.required(),
|
||||
otherwise: Joi.optional(),
|
||||
})
|
||||
.when('COMMUNITY_URL', {
|
||||
is: null,
|
||||
then: Joi.required(),
|
||||
otherwise: Joi.optional(),
|
||||
})
|
||||
.description(
|
||||
'Host (domain, IPv4, or localhost) for the frontend, default is 0.0.0.0 for local hosting during develop',
|
||||
'Host (domain, IPv4, or localhost) for the frontend, default is 0.0.0.0 for local hosting during development.',
|
||||
)
|
||||
.default('0.0.0.0')
|
||||
.required(), // required only if community_url isn't set or FRONTEND_HOSTING is nodejs
|
||||
.default('0.0.0.0'),
|
||||
|
||||
FRONTEND_MODULE_PORT: Joi.number()
|
||||
.integer()
|
||||
@ -40,17 +104,11 @@ module.exports = commonSchema.keys({
|
||||
.max(49151)
|
||||
.description('Port for hosting Frontend with Vite as a Node.js instance, default: 3000')
|
||||
.default(3000)
|
||||
.required(), // required only if FRONTEND_HOSTING is nodejs
|
||||
|
||||
ADMIN_AUTH_URL: Joi.string()
|
||||
.uri({ scheme: ['http', 'https'] })
|
||||
.when('browser_protocol', {
|
||||
is: 'https',
|
||||
then: Joi.string().uri({ scheme: 'https' }),
|
||||
otherwise: Joi.string().uri({ scheme: 'http' }),
|
||||
})
|
||||
.description('Extern Url for admin-frontend')
|
||||
.default('http://0.0.0.0/admin/authenticate?token='),
|
||||
.when('FRONTEND_HOSTING', {
|
||||
is: 'nodejs',
|
||||
then: Joi.required(),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
|
||||
META_URL: Joi.string()
|
||||
.uri({ scheme: ['http', 'https'] })
|
||||
|
||||
@ -15,8 +15,6 @@ dotenv.config() // load env vars from .env
|
||||
|
||||
const CONFIG = require('./src/config')
|
||||
|
||||
console.log(CONFIG)
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
server: {
|
||||
@ -79,7 +77,7 @@ export default defineConfig({
|
||||
URL_PROTOCOL: null,
|
||||
COMMUNITY_URL: null,
|
||||
GRAPHQL_PATH: null,
|
||||
EXTERNAL_BACKEND_URL: CONFIG.EXTERNAL_BACKEND_URL, // null,
|
||||
GRAPHQL_URI: CONFIG.GRAPHQL_URI, // null,
|
||||
ADMIN_AUTH_PATH: CONFIG.ADMIN_AUTH_PATH ?? null, // it is the only env without exported default
|
||||
ADMIN_AUTH_URL: CONFIG.ADMIN_AUTH_URL, // null,
|
||||
COMMUNITY_NAME: null,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user