more schemas

This commit is contained in:
Einhornimmond 2025-01-18 08:36:16 +01:00
parent 291ecce8d3
commit 5ca51a9941
8 changed files with 339 additions and 99 deletions

View File

@ -3,14 +3,8 @@
// Load Package Details for some default values
const pkg = require('../../package')
const constants = {
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v3.2024-08-06',
CURRENT: '',
},
}
const schema = require('./schema')
const joi = require('joi')
const version = {
ADMIN_MODULE_PROTOCOL: process.env.ADMIN_MODULE_PROTOCOL ?? 'http',
@ -47,11 +41,11 @@ const environment = {
// const COMMUNITY_URL =
// COMMUNITY_HOST && URL_PROTOCOL ? URL_PROTOCOL + '://' + COMMUNITY_HOST : undefined
const COMMUNITY_URL = process.env.COMMUNITY_URL ?? ADMIN_MODULE_URL
const WALLET_URL = process.env.WALLET_URL ?? COMMUNITY_URL ?? 'http://localhost'
const WALLET_URL = process.env.WALLET_URL ?? COMMUNITY_URL ?? 'http://0.0.0.0'
const endpoints = {
GRAPHQL_URI: process.env.GRAPHQL_URL ?? COMMUNITY_URL + (process.env.GRAPHQL_PATH ?? '/graphql'),
WALLET_AUTH_URL: WALLET_URL + (process.env.WALLET_AUTH_PATH ?? '/authenticate?token={token}'),
WALLET_AUTH_URL: WALLET_URL + (process.env.WALLET_AUTH_PATH ?? '/authenticate?token='),
WALLET_LOGIN_URL: WALLET_URL + (process.env.WALLET_LOGIN_PATH ?? '/login'),
}
@ -59,24 +53,15 @@ const debug = {
DEBUG_DISABLE_AUTH: process.env.DEBUG_DISABLE_AUTH === 'true' ?? false,
}
// Check config version
constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
)
) {
throw new Error(
`Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`,
)
}
const CONFIG = {
...constants,
...version,
...environment,
...endpoints,
...debug,
}
// Check config version
// TODO: use validate and construct error message including description
joi.attempt(CONFIG, schema)
module.exports = CONFIG

View File

@ -0,0 +1,71 @@
const commonSchema = require('../../../config/common.schema')
const Joi = require('joi')
module.exports = commonSchema.keys({
ADMIN_MODULE_PROTOCOL: Joi.string()
.valid('http', 'https')
.when('BROWSER_PROTOCOL', {
is: 'https',
then: Joi.string().uri({ scheme: 'https' }),
otherwise: Joi.string().uri({ scheme: 'http' }),
})
.description(
'Protocol for admin module hosting, has to be the same as for backend api url and admin to prevent mixed block errors'
)
.default('http')
.required(),
ADMIN_HOSTING: Joi.string()
.valid('nodejs')
.description('set to `nodejs` if admin is hosted by vite with a own nodejs instance')
.optional(),
ADMIN_MODULE_HOST: Joi.alternatives()
.try(
Joi.string().valid('localhost').messages({ 'any.invalid': 'Must be localhost' }),
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' }),
)
.description(
'Host (domain, IPv4, or localhost) for the admin, default is 0.0.0.0 for local hosting during develop',
)
.default('0.0.0.0')
.required(), // required only if community_url isn't set or ADMIN_HOSTING is nodejs
ADMIN_MODULE_PORT: Joi.number()
.integer()
.min(1024)
.max(49151)
.description('Port for hosting Admin with Vite as a Node.js instance, default: 8080')
.default(8080)
.required(), // required only if ADMIN_HOSTING is nodejs
WALLET_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 from wallet-frontend for forwarding from admin')
.default('http://0.0.0.0/authenticate?token=')
.required(),
WALLET_LOGIN_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 from wallet-frontend for forwarding after logout')
.default('http://0.0.0.0/login')
.required(),
DEBUG_DISABLE_AUTH: Joi.boolean()
.description('Flag for disable authorization during development')
.default(false)
.optional(), // true is only allowed in not-production setup
})

View File

@ -15,13 +15,6 @@ const constants = {
DB_VERSION: '0087-add_index_on_user_roles',
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v23.2024-04-04',
CURRENT: '',
},
}
const server = {
@ -31,6 +24,8 @@ const server = {
GRAPHIQL: process.env.GRAPHIQL === 'true' || false,
GDT_API_URL: process.env.GDT_API_URL ?? 'https://gdt.gradido.net',
PRODUCTION: process.env.NODE_ENV === 'production' || false,
// default log level on production should be info
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
}
const database = {
@ -114,18 +109,6 @@ const webhook = {
// This is needed by graphql-directive-auth
process.env.APP_SECRET = server.JWT_SECRET
// Check config version
constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
)
) {
throw new Error(
`Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`,
)
}
const federation = {
FEDERATION_BACKEND_SEND_ON_API: process.env.FEDERATION_BACKEND_SEND_ON_API ?? '1_0',
// ?? operator don't work here as expected

View File

@ -0,0 +1,30 @@
const commonSchema = require('../../../config/common.schema')
const Joi = require('joi')
module.exports = commonSchema.keys({
PORT: Joi.number()
.integer()
.min(1024)
.max(49151)
.description('Port for hosting backend, default: 4000')
.default(4000)
.required(),
// TODO: check format
JWT_SECRET: Joi.string()
.default('secret123')
.description('jwt secret for jwt tokens used for login')
.required(),
// TODO: check format
JWT_EXPIRES_IN: Joi.string()
.default('10m')
.description('time for jwt token expire, auto logout')
.required(),
GDT_API_URL: Joi.string()
.uri({ scheme: ['http', 'https'] })
.default('https://gdt.gradido.net')
.required(), // TODO: only required if gdt is active
})

View File

@ -1,26 +1,28 @@
const Joi = require('joi')
module.exports = Joi.object({
browser_protocol: Joi.string()
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'),
.default('http')
.require(),
community_url: Joi.string()
COMMUNITY_URL: Joi.string()
.uri({ scheme: ['http', 'https'] })
.when('browser_protocol', {
.when('BROWSER_PROTOCOL', {
is: 'https',
then: Joi.string().uri({ scheme: 'https' }),
otherwise: Joi.string().uri({ scheme: 'http' }),
})
.description('The base URL of the community')
.default('http://0.0.0.0'),
.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(),
external_backend_url: Joi.string()
GRAPHQL_URI: Joi.string()
.uri({ scheme: ['http', 'https'] })
.when('browser_protocol', {
.when('BROWSER_PROTOCOL', {
is: 'https',
then: Joi.string().uri({ scheme: 'https' }),
otherwise: Joi.string().uri({ scheme: 'http' }),
@ -32,39 +34,89 @@ module.exports = Joi.object({
must use the same protocol as browser_protocol.
`,
)
.default('http://0.0.0.0/graphql'),
.default('http://0.0.0.0/graphql')
.require(),
community_name: Joi.string()
COMMUNITY_NAME: Joi.string()
.min(3)
.max(100)
.description('The name of the community')
.default('Gradido Entwicklung'),
.default('Gradido Entwicklung')
.require(),
community_description: Joi.string()
COMMUNITY_DESCRIPTION: Joi.string()
.min(10)
.max(300)
.description('A short description of the community')
.default('Die lokale Entwicklungsumgebung von Gradido.'),
.default('Die lokale Entwicklungsumgebung von Gradido.')
.require(),
community_support_email: Joi.string()
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'),
.default('support@supportmail.com')
.require(),
community_location: Joi.string()
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(),
otherwise: Joi.string().optional()
})
.description('Geographical location of the community in "latitude, longitude" format')
.default('49.280377, 9.690151'),
.default('49.280377, 9.690151')
.require(),
GRAPHIQL: Joi.boolean()
.description('Flag for enabling graphql playground for debugging.')
.default(false)
.require(), // todo: only allow true in development mode
gdt_active: Joi.boolean()
.description('Flag to indicate if gdt (Gradido Transform) service is used.')
.default(false),
gms_active: Joi.boolean()
GMS_ACTIVE: Joi.boolean()
.description('Flag to indicate if the GMS (Geographic Member Search) service is used.')
.default(false),
.default(false)
.require(),
humhub_active: Joi.boolean()
HUMHUB_ACTIVE: Joi.boolean()
.description('Flag to indicate if the HumHub based Community Server is used.')
.default(false),
.default(false)
.require(),
LOG_LEVEL: Joi.string()
.valid(['INFO', 'ERROR']) // TODO: lookup values
.description('set log level')
.default('INFO')
.required(),
DB_HOST: Joi.string()
.uri({ scheme: ['http'] })
.description("database host like 'localhost' or 'mariadb' in docker setup")
.default('localhost')
.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_PASSWORD: Joi.string()
.description('database password')
.default('')
.required(),
DB_DATABASE: Joi.string()
.description('database name like gradido_community')
.default('gradido_community')
.required(),
})

View File

@ -1,13 +1,107 @@
/* eslint-disable camelcase */
// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env).
// The whole contents is exposed to the client
// Load Package Details for some default values
import schema from './schema'
import { validateAndExport } from '../../../config'
const pkg = require('../../package')
const schema = require('./schema')
const joi = require('joi')
const CONFIG = {
...validateAndExport(schema),
const constants = {
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
}
const version = {
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,
// 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),
}
let FRONTEND_MODULE_URL
// in case of hosting the frontend module with a nodejs-instance
if (process.env.FRONTEND_HOSTING === 'nodejs') {
FRONTEND_MODULE_URL =
version.FRONTEND_MODULE_PROTOCOL +
'://' +
version.FRONTEND_MODULE_HOST +
':' +
version.FRONTEND_MODULE_PORT
} else {
// in case of hosting the frontend module with a nginx
FRONTEND_MODULE_URL = version.FRONTEND_MODULE_PROTOCOL + '://' + version.FRONTEND_MODULE_HOST
}
// const FRONTEND_MODULE_URI = version.FRONTEND_MODULE_PROTOCOL + '://' + version.FRONTEND_MODULE_HOST // +
// ':' +
// version.FRONTEND_MODULE_PORT
const features = {
GMS_ACTIVE: process.env.GMS_ACTIVE ?? false,
HUMHUB_ACTIVE: process.env.HUMHUB_ACTIVE ?? false,
}
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'
// const URL_PROTOCOL = process.env.URL_PROTOCOL ?? 'http'
const COMMUNITY_URL = process.env.COMMUNITY_URL ?? FRONTEND_MODULE_URL
const endpoints = {
GRAPHQL_URI: process.env.GRAPHQL_URI ?? COMMUNITY_URL + (process.env.GRAPHQL_PATH ?? '/graphql'),
ADMIN_AUTH_URL:
process.env.ADMIN_AUTH_URL ??
COMMUNITY_URL + (process.env.ADMIN_AUTH_PATH ?? '/admin/authenticate?token='),
}
const community = {
COMMUNITY_NAME: process.env.COMMUNITY_NAME ?? 'Gradido Entwicklung',
COMMUNITY_URL: COMMUNITY_URL,
COMMUNITY_REGISTER_URL: COMMUNITY_URL + (process.env.COMMUNITY_REGISTER_PATH ?? '/register'),
COMMUNITY_DESCRIPTION:
process.env.COMMUNITY_DESCRIPTION ?? 'Die lokale Entwicklungsumgebung von Gradido.',
COMMUNITY_SUPPORT_MAIL: process.env.COMMUNITY_SUPPORT_MAIL ?? 'support@supportmail.com',
COMMUNITY_LOCATION: process.env.COMMUNITY_LOCATION ?? '49.280377, 9.690151',
}
const meta = {
META_URL: process.env.META_URL ?? 'http://localhost',
META_TITLE_DE: process.env.META_TITLE_DE ?? 'Gradido Dein Dankbarkeitskonto',
META_TITLE_EN: process.env.META_TITLE_EN ?? 'Gradido - Your gratitude account',
META_DESCRIPTION_DE:
process.env.META_DESCRIPTION_DE ??
'Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle.',
META_DESCRIPTION_EN:
process.env.META_DESCRIPTION_EN ??
'Gratitude is the currency of the new age. More and more people are unleashing their potential and shaping a good future for all.',
META_KEYWORDS_DE:
process.env.META_KEYWORDS_DE ??
'Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem',
META_KEYWORDS_EN:
process.env.META_KEYWORDS_EN ??
'Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System',
META_AUTHOR: process.env.META_AUTHOR ?? 'Bernd Hückstädt - Gradido-Akademie',
}
const CONFIG = {
...constants,
...version,
...features,
...environment,
...endpoints,
...community,
...meta,
}
// Check config
// TODO: use validate and construct error message including description
joi.attempt(CONFIG, schema)
module.exports = CONFIG

View File

@ -2,8 +2,25 @@ const commonSchema = require('../../../config/common.schema')
const Joi = require('joi')
module.exports = commonSchema.keys({
// export default Joi.object({
frontend_vite_host: Joi.alternatives()
FRONTEND_MODULE_PROTOCOL: Joi.string()
.valid('http', 'https')
.when('BROWSER_PROTOCOL', {
is: 'https',
then: Joi.string().uri({ scheme: 'https' }),
otherwise: Joi.string().uri({ scheme: 'http' }),
})
.description(
'Protocol for frontend module hosting, has to be the same as for backend api url and admin to prevent mixed block errors'
)
.default('http')
.required(),
FRONTEND_HOSTING: Joi.string()
.valid('nodejs')
.description('set to `nodejs` if frontend is hosted by vite with a own nodejs instance')
.optional(),
FRONTEND_MODULE_HOST: Joi.alternatives()
.try(
Joi.string().valid('localhost').messages({ 'any.invalid': 'Must be localhost' }),
Joi.string()
@ -12,21 +29,20 @@ module.exports = commonSchema.keys({
Joi.string().domain().messages({ 'string.domain': 'Must be a valid domain' }),
)
.description(
`
Host (domain, IPv4, or localhost) for the frontend when running Vite as a standalone Node.js instance;
internally, nginx forward requests to this address.
`,
'Host (domain, IPv4, or localhost) for the frontend, default is 0.0.0.0 for local hosting during develop',
)
.default('0.0.0.0'),
.default('0.0.0.0')
.required(), // required only if community_url isn't set or FRONTEND_HOSTING is nodejs
frontend_vite_port: Joi.number()
FRONTEND_MODULE_PORT: Joi.number()
.integer()
.min(1024)
.max(49151)
.description('Port for hosting Frontend with Vite as a Node.js instance')
.default(3000),
.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()
ADMIN_AUTH_URL: Joi.string()
.uri({ scheme: ['http', 'https'] })
.when('browser_protocol', {
is: 'https',
@ -36,44 +52,52 @@ module.exports = commonSchema.keys({
.description('Extern Url for admin-frontend')
.default('http://0.0.0.0/admin/authenticate?token='),
meta_url: Joi.string()
META_URL: Joi.string()
.uri({ scheme: ['http', 'https'] })
.description('The base URL for the meta tags.')
.default('http://localhost'),
.default('http://localhost')
.required(),
meta_title_de: Joi.string()
META_TITLE_DE: Joi.string()
.description('Meta title in German.')
.default('Gradido Dein Dankbarkeitskonto'),
.default('Gradido Dein Dankbarkeitskonto')
.required(),
meta_title_en: Joi.string()
META_TITLE_EN: Joi.string()
.description('Meta title in English.')
.default('Gradido - Your gratitude account'),
.default('Gradido - Your gratitude account')
.required(),
meta_description_de: Joi.string()
META_DESCRIPTION_DE: Joi.string()
.description('Meta description in German.')
.default(
'Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle.',
),
)
.required(),
meta_description_en: Joi.string()
META_DESCRIPTION_EN: Joi.string()
.description('Meta description in English.')
.default(
'Gratitude is the currency of the new age. More and more people are unleashing their potential and shaping a good future for all.',
),
)
.required(),
meta_keywords_de: Joi.string()
META_KEYWORDS_DE: Joi.string()
.description('Meta keywords in German.')
.default(
'Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem',
),
)
.required(),
meta_keywords_en: Joi.string()
META_KEYWORDS_EN: Joi.string()
.description('Meta keywords in English.')
.default(
'Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System',
),
)
.required(),
meta_author: Joi.string()
META_AUTHOR: Joi.string()
.description('The author for the meta tags.')
.default('Bernd Hückstädt - Gradido-Akademie'),
.default('Bernd Hückstädt - Gradido-Akademie')
.required(),
})

View File

@ -22,6 +22,7 @@ export default defineConfig({
server: {
host: CONFIG.FRONTEND_MODULE_HOST, // '0.0.0.0',
port: CONFIG.FRONTEND_MODULE_PORT, // 3000,
https: CONFIG.FRONTEND_MODULE_PROTOCOL === 'https',
},
resolve: {
alias: {