mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-25 19:26:31 -05:00
Extend config with various options from 1.x
Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
parent
18c6694bcb
commit
286575315e
13 changed files with 686 additions and 32 deletions
|
@ -6,47 +6,112 @@
|
|||
|
||||
import { registerAs } from '@nestjs/config';
|
||||
import * as Joi from 'joi';
|
||||
import { Loglevel } from './loglevel.enum';
|
||||
import { appConfigHsts, HstsConfig, hstsSchema } from './hsts-config';
|
||||
import { appConfigCsp, CspConfig, cspSchema } from './csp-config';
|
||||
import { appConfigMedia, MediaConfig, mediaSchema } from './media-config';
|
||||
import {
|
||||
appConfigDatabase,
|
||||
DatabaseConfig,
|
||||
databaseSchema,
|
||||
} from './database-config';
|
||||
import { appConfigAuth, AuthConfig, authSchema } from './auth-config';
|
||||
|
||||
// import { LinkifyHeaderStyle } from './linkify-header-style';
|
||||
|
||||
export interface AppConfig {
|
||||
domain: string;
|
||||
port: number;
|
||||
media: {
|
||||
backend: {
|
||||
use: string;
|
||||
filesystem: {
|
||||
uploadPath: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
loglevel: Loglevel;
|
||||
/*linkifyHeaderStyle: LinkifyHeaderStyle;
|
||||
sourceURL: string;
|
||||
urlPath: string;
|
||||
host: string;
|
||||
path: string;
|
||||
urlAddPort: boolean;
|
||||
cookiePolicy: string;
|
||||
protocolUseSSL: boolean;
|
||||
allowOrigin: string[];
|
||||
useCDN: boolean;
|
||||
enableAnonymous: boolean;
|
||||
enableAnonymousEdits: boolean;
|
||||
enableFreeURL: boolean;
|
||||
forbiddenNoteIDs: string[];
|
||||
defaultPermission: string;
|
||||
sessionSecret: string;
|
||||
sessionLife: number;
|
||||
tooBusyLag: number;
|
||||
enableGravatar: boolean;*/
|
||||
hsts: HstsConfig;
|
||||
csp: CspConfig;
|
||||
media: MediaConfig;
|
||||
database: DatabaseConfig;
|
||||
auth: AuthConfig;
|
||||
}
|
||||
|
||||
const schema = Joi.object({
|
||||
port: Joi.number(),
|
||||
media: {
|
||||
backend: {
|
||||
use: Joi.string().valid('filesystem'),
|
||||
filesystem: {
|
||||
uploadPath: Joi.when('...use', {
|
||||
is: Joi.valid('filesystem'),
|
||||
then: Joi.string(),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
domain: Joi.string(),
|
||||
port: Joi.number().default(3000).optional(),
|
||||
loglevel: Joi.string()
|
||||
.valid(...Object.values(Loglevel))
|
||||
.default(Loglevel.WARN)
|
||||
.optional(),
|
||||
/*linkifyHeaderStyle: Joi.string().valid(...Object.values(LinkifyHeaderStyle)).default(LinkifyHeaderStyle.GFM).optional(),
|
||||
sourceURL: Joi.string(),
|
||||
urlPath: Joi.string(),
|
||||
host: Joi.string().default('::').optional(),
|
||||
path: Joi.string(),
|
||||
urlAddPort: Joi.boolean().default(false).optional(),
|
||||
cookiePolicy: Joi.string(),
|
||||
protocolUseSSL: Joi.boolean().default(true).optional(),
|
||||
allowOrigin: Joi.array().items(Joi.string()),
|
||||
useCDN: Joi.boolean().default(false).optional(),
|
||||
enableAnonymous: Joi.boolean().default(true).optional(),
|
||||
enableAnonymousEdits: Joi.boolean().default(false).optional(),
|
||||
enableFreeURL: Joi.boolean().default(false).optional(),
|
||||
forbiddenNoteIDs: Joi.array().items(Joi.string()),
|
||||
defaultPermission: Joi.string(),
|
||||
sessionSecret: Joi.string(),
|
||||
sessionLife: Joi.number().default(14 * 24 * 60 * 60 * 1000).optional(),
|
||||
tooBusyLag: Joi.number().default(70).optional(),
|
||||
enableGravatar: Joi.boolean().default(true).optional(),*/
|
||||
hsts: hstsSchema,
|
||||
csp: cspSchema,
|
||||
media: mediaSchema,
|
||||
database: databaseSchema,
|
||||
auth: authSchema,
|
||||
});
|
||||
|
||||
export default registerAs('appConfig', async () => {
|
||||
const appConfig = schema.validate(
|
||||
{
|
||||
domain: process.env.HD_DOMAIN,
|
||||
port: parseInt(process.env.PORT) || undefined,
|
||||
media: {
|
||||
backend: {
|
||||
use: process.env.HD_MEDIA_BACKEND,
|
||||
filesystem: {
|
||||
uploadPath: process.env.HD_MEDIA_BACKEND_FILESYSTEM_UPLOAD_PATH,
|
||||
},
|
||||
},
|
||||
},
|
||||
loglevel: process.env.HD_LOGLEVEL, //|| Loglevel.WARN,
|
||||
/*linkifyHeaderStyle: process.env.HD_LINKIFY_HEADER_STYLE,
|
||||
sourceURL: process.env.HD_SOURCE_URL,
|
||||
urlPath: process.env.HD_URL_PATH,
|
||||
host: process.env.HD_HOST || '::',
|
||||
path: process.env.HD_PATH,
|
||||
urlAddPort: process.env.HD_URL_ADDPORT,
|
||||
cookiePolicy: process.env.HD_COOKIE_POLICY,
|
||||
protocolUseSSL: process.env.HD_PROTOCOL_USESSL || true,
|
||||
allowOrigin: toArrayConfig(process.env.HD_ALLOW_ORIGIN),
|
||||
useCDN: process.env.HD_USECDN,
|
||||
enableAnonymous: process.env.HD_ENABLE_ANONYMOUS || true,
|
||||
enableAnonymousEdits: process.env.HD_ENABLE_ANONYMOUS_EDITS,
|
||||
enableFreeURL: process.env.HD_ENABLE_FREEURL,
|
||||
forbiddenNoteIDs: toArrayConfig(process.env.HD_FORBIDDEN_NOTE_IDS),
|
||||
defaultPermission: process.env.HD_DEFAULT_PERMISSION,
|
||||
sessionSecret: process.env.HD_SESSION_SECRET,
|
||||
sessionLife: parseInt(process.env.HD_SESSION_LIFE) || 14 * 24 * 60 * 60 * 1000,
|
||||
tooBusyLag: parseInt(process.env.HD_TOOBUSY_LAG) || 70,
|
||||
enableGravatar: process.env.HD_ENABLE_GRAVATAR || true,*/
|
||||
hsts: appConfigHsts,
|
||||
csp: appConfigCsp,
|
||||
media: appConfigMedia,
|
||||
database: appConfigDatabase,
|
||||
auth: appConfigAuth,
|
||||
},
|
||||
{
|
||||
abortEarly: false,
|
||||
|
|
331
src/config/auth-config.ts
Normal file
331
src/config/auth-config.ts
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as Joi from 'joi';
|
||||
import { GitlabScope, GitlabVersion } from './gitlab.enum';
|
||||
import { toArrayConfig } from './utils';
|
||||
|
||||
export interface AuthConfig {
|
||||
email: {
|
||||
enableLogin: boolean;
|
||||
enableRegister: boolean;
|
||||
};
|
||||
facebook: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
};
|
||||
twitter: {
|
||||
consumerKey: string;
|
||||
consumerSecret: string;
|
||||
};
|
||||
github: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
};
|
||||
dropbox: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
appKey: string;
|
||||
};
|
||||
google: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
apiKey: string;
|
||||
};
|
||||
gitlab: [
|
||||
{
|
||||
providerName: string;
|
||||
baseURL: string;
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
scope: GitlabScope;
|
||||
version: GitlabVersion;
|
||||
},
|
||||
];
|
||||
// ToDo: tlsOptions exist in config.json.example. See https://nodejs.org/api/tls.html#tls_tls_connect_options_callback
|
||||
ldap: [
|
||||
{
|
||||
providerName: string;
|
||||
url: string;
|
||||
bindDn: string;
|
||||
bindCredentials: string;
|
||||
searchBase: string;
|
||||
searchFilter: string;
|
||||
searchAttributes: string[];
|
||||
usernameField: string;
|
||||
useridField: string;
|
||||
tlsCa: string[];
|
||||
},
|
||||
];
|
||||
saml: [
|
||||
{
|
||||
providerName: string;
|
||||
idpSsoUrl: string;
|
||||
idpCert: string;
|
||||
clientCert: string;
|
||||
issuer: string;
|
||||
identifierFormat: string;
|
||||
disableRequestedAuthnContext: string;
|
||||
groupAttribute: string;
|
||||
requiredGroups: string[];
|
||||
externalGroups: string;
|
||||
attribute: {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
};
|
||||
},
|
||||
];
|
||||
oauth2: [
|
||||
{
|
||||
providerName: string;
|
||||
baseURL: string;
|
||||
userProfileURL: string;
|
||||
userProfileIdAttr: string;
|
||||
userProfileUsernameAttr: string;
|
||||
userProfileDisplayNameAttr: string;
|
||||
userProfileEmailAttr: string;
|
||||
tokenURL: string;
|
||||
authorizationURL: string;
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
scope: string;
|
||||
rolesClaim: string;
|
||||
accessRole: string;
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export const authSchema = Joi.object({
|
||||
email: {
|
||||
enableLogin: Joi.boolean().default(false).optional(),
|
||||
enableRegister: Joi.boolean().default(false).optional(),
|
||||
},
|
||||
facebook: {
|
||||
clientID: Joi.string().optional(),
|
||||
clientSecret: Joi.string().optional(),
|
||||
},
|
||||
twitter: {
|
||||
consumerKey: Joi.string().optional(),
|
||||
consumerSecret: Joi.string().optional(),
|
||||
},
|
||||
github: {
|
||||
clientID: Joi.string().optional(),
|
||||
clientSecret: Joi.string().optional(),
|
||||
},
|
||||
dropbox: {
|
||||
clientID: Joi.string().optional(),
|
||||
clientSecret: Joi.string().optional(),
|
||||
appKey: Joi.string().optional(),
|
||||
},
|
||||
google: {
|
||||
clientID: Joi.string().optional(),
|
||||
clientSecret: Joi.string().optional(),
|
||||
apiKey: Joi.string().optional(),
|
||||
},
|
||||
gitlab: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
providerName: Joi.string().default('Gitlab').optional(),
|
||||
baseURL: Joi.string().optional(),
|
||||
clientID: Joi.string().optional(),
|
||||
clientSecret: Joi.string().optional(),
|
||||
scope: Joi.string()
|
||||
.valid(...Object.values(GitlabScope))
|
||||
.default(GitlabScope.READ_USER)
|
||||
.optional(),
|
||||
version: Joi.string()
|
||||
.valid(...Object.values(GitlabVersion))
|
||||
.default(GitlabVersion.V4)
|
||||
.optional(),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
// ToDo: should searchfilter have a default?
|
||||
ldap: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
providerName: Joi.string().default('LDAP').optional(),
|
||||
url: Joi.string().optional(),
|
||||
bindDn: Joi.string().optional(),
|
||||
bindCredentials: Joi.string().optional(),
|
||||
searchBase: Joi.string().optional(),
|
||||
searchFilter: Joi.string().default('(uid={{username}})').optional(),
|
||||
searchAttributes: Joi.array().items(Joi.string()),
|
||||
usernameField: Joi.string().default('userid').optional(),
|
||||
useridField: Joi.string().optional(),
|
||||
tlsCa: Joi.array().items(Joi.string()),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
saml: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
providerName: Joi.string().default('SAML').optional(),
|
||||
idpSsoUrl: Joi.string().optional(),
|
||||
idpCert: Joi.string().optional(),
|
||||
clientCert: Joi.string().optional(),
|
||||
// ToDo: (default: config.serverURL) will be build on-the-fly in the config/index.js from domain, urlAddPort and urlPath.
|
||||
issuer: Joi.string().optional(), //.default().optional(),
|
||||
identifierFormat: Joi.string()
|
||||
.default('urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress')
|
||||
.optional(),
|
||||
disableRequestedAuthnContext: Joi.boolean().default(false).optional(),
|
||||
groupAttribute: Joi.string().optional(),
|
||||
requiredGroups: Joi.array().items(Joi.string()),
|
||||
externalGroups: Joi.array().items(Joi.string()),
|
||||
attribute: {
|
||||
id: Joi.string().default('NameId').optional(),
|
||||
username: Joi.string().default('NameId').optional(),
|
||||
email: Joi.string().default('NameId').optional(),
|
||||
},
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
oauth2: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
providerName: Joi.string().default('OAuth2').optional(),
|
||||
baseURL: Joi.string().optional(),
|
||||
userProfileURL: Joi.string().optional(),
|
||||
userProfileIdAttr: Joi.string().optional(),
|
||||
userProfileUsernameAttr: Joi.string().optional(),
|
||||
userProfileDisplayNameAttr: Joi.string().optional(),
|
||||
userProfileEmailAttr: Joi.string().optional(),
|
||||
tokenURL: Joi.string().optional(),
|
||||
authorizationURL: Joi.string().optional(),
|
||||
clientID: Joi.string().optional(),
|
||||
clientSecret: Joi.string().optional(),
|
||||
scope: Joi.string().optional(),
|
||||
rolesClaim: Joi.string().optional(),
|
||||
accessRole: Joi.string().optional(),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
// ToDo: Validate these with Joi to prevent duplicate entries?
|
||||
|
||||
const gitlabNames = toArrayConfig(process.env.HD_AUTH_GITLABS, ',');
|
||||
const ldapNames = toArrayConfig(process.env.HD_AUTH_LDAPS, ',');
|
||||
const samlNames = toArrayConfig(process.env.HD_AUTH_SAMLS, ',');
|
||||
const oauth2Names = toArrayConfig(process.env.HD_AUTH_OAUTH2S, ',');
|
||||
|
||||
const gitlabs = gitlabNames.map((gitlabName) => {
|
||||
return {
|
||||
providerName: process.env[`HD_AUTH_GITLAB_${gitlabName}_PROVIDER_NAME`],
|
||||
baseURL: process.env[`HD_AUTH_GITLAB_${gitlabName}_BASE_URL`],
|
||||
clientID: process.env[`HD_AUTH_GITLAB_${gitlabName}_CLIENT_ID`],
|
||||
clientSecret: process.env[`HD_AUTH_GITLAB_${gitlabName}_CLIENT_SECRET`],
|
||||
scope: process.env[`HD_AUTH_GITLAB_${gitlabName}_GITLAB_SCOPE`],
|
||||
version: process.env[`HD_AUTH_GITLAB_${gitlabName}_GITLAB_VERSION`],
|
||||
};
|
||||
});
|
||||
|
||||
const ldaps = ldapNames.map((ldapName) => {
|
||||
return {
|
||||
providerName: process.env[`HD_AUTH_LDAP_${ldapName}_PROVIDER_NAME`],
|
||||
url: process.env[`HD_AUTH_LDAP_${ldapName}_URL`],
|
||||
bindDn: process.env[`HD_AUTH_LDAP_${ldapName}_BIND_DN`],
|
||||
bindCredentials: process.env[`HD_AUTH_LDAP_${ldapName}_BIND_CREDENTIALS`],
|
||||
searchBase: process.env[`HD_AUTH_LDAP_${ldapName}_SEARCH_BASE`],
|
||||
searchFilter: process.env[`HD_AUTH_LDAP_${ldapName}_SEARCH_FILTER`],
|
||||
searchAttributes: toArrayConfig(
|
||||
process.env[`HD_AUTH_LDAP_${ldapName}_SEARCH_ATTRIBUTES`],
|
||||
',',
|
||||
),
|
||||
usernameField: process.env[`HD_AUTH_LDAP_${ldapName}_USERNAME_FIELD`],
|
||||
useridField: process.env[`HD_AUTH_LDAP_${ldapName}_USERID_FIELD`],
|
||||
tlsCa: toArrayConfig(process.env[`HD_AUTH_LDAP_${ldapName}_TLS_CA`], ','),
|
||||
};
|
||||
});
|
||||
|
||||
const samls = samlNames.map((samlName) => {
|
||||
return {
|
||||
providerName: process.env[`HD_AUTH_SAML_${samlName}_PROVIDER_NAME`],
|
||||
idpSsoUrl: process.env[`HD_AUTH_SAML_${samlName}_IDPSSOURL`],
|
||||
idpCert: process.env[`HD_AUTH_SAML_${samlName}_IDPCERT`],
|
||||
clientCert: process.env[`HD_AUTH_SAML_${samlName}_CLIENTCERT`],
|
||||
issuer: process.env[`HD_AUTH_SAML_${samlName}_ISSUER`],
|
||||
identifierFormat: process.env[`HD_AUTH_SAML_${samlName}_IDENTIFIERFORMAT`],
|
||||
disableRequestedAuthnContext:
|
||||
process.env[`HD_AUTH_SAML_${samlName}_DISABLEREQUESTEDAUTHNCONTEXT`],
|
||||
groupAttribute: process.env[`HD_AUTH_SAML_${samlName}_GROUPATTRIBUTE`],
|
||||
requiredGroups: toArrayConfig(
|
||||
process.env[`HD_AUTH_SAML_${samlName}_REQUIREDGROUPS`],
|
||||
'|',
|
||||
),
|
||||
externalGroups: toArrayConfig(
|
||||
process.env[`HD_AUTH_SAML_${samlName}_EXTERNALGROUPS`],
|
||||
'|',
|
||||
),
|
||||
attribute: {
|
||||
id: process.env[`HD_AUTH_SAML_${samlName}_ATTRIBUTE_ID`],
|
||||
username: process.env[`HD_AUTH_SAML_${samlName}_ATTRIBUTE_USERNAME`],
|
||||
email: process.env[`HD_AUTH_SAML_${samlName}_ATTRIBUTE_USERNAME`],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const oauth2s = oauth2Names.map((oauth2Name) => {
|
||||
return {
|
||||
providerName: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_PROVIDER_NAME`],
|
||||
baseURL: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_BASEURL`],
|
||||
userProfileURL:
|
||||
process.env[`HD_AUTH_OAUTH2_${oauth2Name}_USER_PROFILE_URL`],
|
||||
userProfileIdAttr:
|
||||
process.env[`HD_AUTH_OAUTH2_${oauth2Name}_USER_PROFILE_ID_ATTR`],
|
||||
userProfileUsernameAttr:
|
||||
process.env[`HD_AUTH_OAUTH2_${oauth2Name}_USER_PROFILE_USERNAME_ATTR`],
|
||||
userProfileDisplayNameAttr:
|
||||
process.env[
|
||||
`HD_AUTH_OAUTH2_${oauth2Name}_USER_PROFILE_DISPLAY_NAME_ATTR`
|
||||
],
|
||||
userProfileEmailAttr:
|
||||
process.env[`HD_AUTH_OAUTH2_${oauth2Name}_USER_PROFILE_EMAIL_ATTR`],
|
||||
tokenURL: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_TOKEN_URL`],
|
||||
authorizationURL:
|
||||
process.env[`HD_AUTH_OAUTH2_${oauth2Name}_AUTHORIZATION_URL`],
|
||||
clientID: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_CLIENT_ID`],
|
||||
clientSecret: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_CLIENT_SECRET`],
|
||||
scope: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_SCOPE`],
|
||||
rolesClaim: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_ROLES_CLAIM`],
|
||||
accessRole: process.env[`HD_AUTH_OAUTH2_${oauth2Name}_ACCESS_ROLE`],
|
||||
};
|
||||
});
|
||||
|
||||
export const appConfigAuth = {
|
||||
email: {
|
||||
enableLogin: process.env.HD_AUTH_EMAIL_ENABLE_LOGIN,
|
||||
enableRegister: process.env.HD_AUTH_EMAIL_ENABLE_REGISTER,
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.HD_AUTH_FACEBOOK_CLIENT_ID,
|
||||
clientSecret: process.env.HD_AUTH_FACEBOOK_CLIENT_SECRET,
|
||||
},
|
||||
twitter: {
|
||||
consumerKey: process.env.HD_AUTH_TWITTER_CONSUMER_KEY,
|
||||
consumerSecret: process.env.HD_AUTH_TWITTER_CONSUMER_SECRET,
|
||||
},
|
||||
github: {
|
||||
clientID: process.env.HD_AUTH_GITHUB_CLIENT_ID,
|
||||
clientSecret: process.env.HD_AUTH_GITHUB_CLIENT_SECRET,
|
||||
},
|
||||
dropbox: {
|
||||
clientID: process.env.HD_AUTH_DROPBOX_CLIENT_ID,
|
||||
clientSecret: process.env.HD_AUTH_DROPBOX_CLIENT_SECRET,
|
||||
appKey: process.env.HD_AUTH_DROPBOX_APP_KEY,
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.HD_AUTH_GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.HD_AUTH_GOOGLE_CLIENT_SECRET,
|
||||
apiKey: process.env.HD_AUTH_GOOGLE_APP_KEY,
|
||||
},
|
||||
gitlab: gitlabs,
|
||||
ldap: ldaps,
|
||||
saml: samls,
|
||||
oauth2: oauth2s,
|
||||
};
|
24
src/config/csp-config.ts
Normal file
24
src/config/csp-config.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as Joi from 'joi';
|
||||
|
||||
export interface CspConfig {
|
||||
enable: boolean;
|
||||
maxAgeSeconds: number;
|
||||
includeSubdomains: boolean;
|
||||
preload: boolean;
|
||||
}
|
||||
|
||||
export const cspSchema = Joi.object({
|
||||
enable: Joi.boolean().default(true).optional(),
|
||||
reportURI: Joi.string().optional(),
|
||||
});
|
||||
|
||||
export const appConfigCsp = {
|
||||
enable: process.env.HD_CSP_ENABLE || true,
|
||||
reportURI: process.env.HD_CSP_REPORTURI,
|
||||
};
|
42
src/config/database-config.ts
Normal file
42
src/config/database-config.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as Joi from 'joi';
|
||||
import { DatabaseDialect } from './database-dialect.enum';
|
||||
|
||||
export interface DatabaseConfig {
|
||||
username: string;
|
||||
password: string;
|
||||
database: string;
|
||||
host: string;
|
||||
port: number;
|
||||
storage: string;
|
||||
dialect: DatabaseDialect;
|
||||
}
|
||||
|
||||
export const databaseSchema = Joi.object({
|
||||
username: Joi.string(),
|
||||
password: Joi.string(),
|
||||
database: Joi.string(),
|
||||
host: Joi.string(),
|
||||
port: Joi.number(),
|
||||
storage: Joi.when('...dialect', {
|
||||
is: Joi.valid(DatabaseDialect.SQLITE),
|
||||
then: Joi.string(),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
dialect: Joi.string().valid(...Object.values(DatabaseDialect)),
|
||||
});
|
||||
|
||||
export const appConfigDatabase = {
|
||||
username: process.env.HD_DATABASE_USER,
|
||||
password: process.env.HD_DATABASE_PASS,
|
||||
database: process.env.HD_DATABASE_NAME,
|
||||
host: process.env.HD_DATABASE_HOST,
|
||||
port: parseInt(process.env.HD_DATABASE_PORT) || undefined,
|
||||
storage: process.env.HD_DATABASE_STORAGE,
|
||||
dialect: process.env.HD_DATABASE_DIALECT,
|
||||
};
|
12
src/config/database-dialect.enum.ts
Normal file
12
src/config/database-dialect.enum.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export enum DatabaseDialect {
|
||||
POSTGRES = 'postgres',
|
||||
MYSQL = 'mysql',
|
||||
MARIADB = 'mariadb',
|
||||
SQLITE = 'sqlite',
|
||||
}
|
16
src/config/gitlab.enum.ts
Normal file
16
src/config/gitlab.enum.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export enum GitlabScope {
|
||||
READ_USER = 'read_user',
|
||||
API = 'api',
|
||||
}
|
||||
|
||||
// ToDo: Evaluate if V3 is really necessary anymore (it's deprecated since 2017)
|
||||
export enum GitlabVersion {
|
||||
V3 = 'v3',
|
||||
V4 = 'v4',
|
||||
}
|
30
src/config/hsts-config.ts
Normal file
30
src/config/hsts-config.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as Joi from 'joi';
|
||||
|
||||
export interface HstsConfig {
|
||||
enable: boolean;
|
||||
maxAgeSeconds: number;
|
||||
includeSubdomains: boolean;
|
||||
preload: boolean;
|
||||
}
|
||||
|
||||
export const hstsSchema = Joi.object({
|
||||
enable: Joi.boolean().default(true).optional(),
|
||||
maxAgeSeconds: Joi.number()
|
||||
.default(60 * 60 * 24 * 365)
|
||||
.optional(),
|
||||
includeSubdomains: Joi.boolean().default(true).optional(),
|
||||
preload: Joi.boolean().default(true).optional(),
|
||||
});
|
||||
|
||||
export const appConfigHsts = {
|
||||
enable: process.env.HD_HSTS_ENABLE,
|
||||
maxAgeSeconds: parseInt(process.env.HD_HSTS_MAX_AGE) || undefined,
|
||||
includeSubdomains: process.env.HD_HSTS_INCLUDE_SUBDOMAINS,
|
||||
preload: process.env.HD_HSTS_PRELOAD,
|
||||
};
|
11
src/config/linkify-header-style.enum.ts
Normal file
11
src/config/linkify-header-style.enum.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export enum LinkifyHeaderStyle {
|
||||
KEEP_CASE = 'keep-case',
|
||||
LOWER_CASE = 'lower-case',
|
||||
GFM = 'gfm',
|
||||
}
|
13
src/config/loglevel.enum.ts
Normal file
13
src/config/loglevel.enum.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export enum Loglevel {
|
||||
TRACE = 'trace',
|
||||
DEBUG = 'debug',
|
||||
INFO = 'info',
|
||||
WARN = 'warn',
|
||||
ERROR = 'error',
|
||||
}
|
93
src/config/media-config.ts
Normal file
93
src/config/media-config.ts
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as Joi from 'joi';
|
||||
import { BackendType } from '../media/backends/backend-type.enum';
|
||||
|
||||
export interface MediaConfig {
|
||||
backend: {
|
||||
use: BackendType;
|
||||
filesystem: {
|
||||
uploadPath: string;
|
||||
};
|
||||
s3: {
|
||||
accessKeyId: string;
|
||||
secretAccessKey: string;
|
||||
region: string;
|
||||
bucket: string;
|
||||
endPoint: string;
|
||||
};
|
||||
azure: {
|
||||
connectionString: string;
|
||||
container: string;
|
||||
};
|
||||
imgur: {
|
||||
clientID: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const mediaSchema = Joi.object({
|
||||
backend: {
|
||||
use: Joi.string().valid(...Object.values(BackendType)),
|
||||
filesystem: {
|
||||
uploadPath: Joi.when('...use', {
|
||||
is: Joi.valid(BackendType.FILESYSTEM),
|
||||
then: Joi.string(),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
},
|
||||
s3: Joi.when('...use', {
|
||||
is: Joi.valid(BackendType.S3),
|
||||
then: Joi.object({
|
||||
accessKey: Joi.string(),
|
||||
secretKey: Joi.string(),
|
||||
endPoint: Joi.string(),
|
||||
secure: Joi.boolean(),
|
||||
port: Joi.number(),
|
||||
}),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
azure: Joi.when('...use', {
|
||||
is: Joi.valid(BackendType.AZURE),
|
||||
then: Joi.object({
|
||||
connectionString: Joi.string(),
|
||||
container: Joi.string(),
|
||||
}),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
imgur: Joi.when('...use', {
|
||||
is: Joi.valid(BackendType.IMGUR),
|
||||
then: Joi.object({
|
||||
clientID: Joi.string(),
|
||||
}),
|
||||
otherwise: Joi.optional(),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export const appConfigMedia = {
|
||||
backend: {
|
||||
use: process.env.HD_MEDIA_BACKEND,
|
||||
filesystem: {
|
||||
uploadPath: process.env.HD_MEDIA_BACKEND_FILESYSTEM_UPLOAD_PATH,
|
||||
},
|
||||
s3: {
|
||||
accessKey: process.env.HD_MEDIA_BACKEND_S3_ACCESS_KEY,
|
||||
secretKey: process.env.HD_MEDIA_BACKEND_S3_ACCESS_KEY,
|
||||
endPoint: process.env.HD_MEDIA_BACKEND_S3_ENDPOINT,
|
||||
secure: process.env.HD_MEDIA_BACKEND_S3_SECURE,
|
||||
port: parseInt(process.env.HD_MEDIA_BACKEND_S3_PORT) || undefined,
|
||||
},
|
||||
azure: {
|
||||
connectionString: process.env.HD_MEDIA_BACKEND_AZURE_CONNECTION_STRING,
|
||||
container: process.env.HD_MEDIA_BACKEND_AZURE_CONTAINER,
|
||||
},
|
||||
imgur: {
|
||||
clientID: process.env.HD_MEDIA_BACKEND_IMGUR_CLIENTID,
|
||||
},
|
||||
},
|
||||
};
|
17
src/config/utils.ts
Normal file
17
src/config/utils.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export const toArrayConfig = (configValue: string, separator = ',') => {
|
||||
if (!configValue) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!configValue.includes(separator)) {
|
||||
return [configValue.trim()];
|
||||
}
|
||||
|
||||
return configValue.split(separator).map((arrayItem) => arrayItem.trim());
|
||||
};
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
export enum BackendType {
|
||||
FILEYSTEM = 'filesystem',
|
||||
FILESYSTEM = 'filesystem',
|
||||
S3 = 's3',
|
||||
IMGUR = 'imgur',
|
||||
AZURE = 'azure',
|
||||
|
|
|
@ -122,13 +122,13 @@ export class MediaService {
|
|||
private chooseBackendType(): BackendType {
|
||||
switch (this.appConfig.media.backend.use) {
|
||||
case 'filesystem':
|
||||
return BackendType.FILEYSTEM;
|
||||
return BackendType.FILESYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
private getBackendFromType(type: BackendType): MediaBackend {
|
||||
switch (type) {
|
||||
case BackendType.FILEYSTEM:
|
||||
case BackendType.FILESYSTEM:
|
||||
return this.moduleRef.get(FilesystemBackend);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue