mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-18 17:25:16 -04:00
Move old backend code to old_src folder
Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
parent
c42d2223e8
commit
7b9f9a487b
97 changed files with 7 additions and 7 deletions
122
old_src/lib/config/default.ts
Normal file
122
old_src/lib/config/default.ts
Normal file
|
@ -0,0 +1,122 @@
|
|||
import os from 'os'
|
||||
import { Config } from './interfaces'
|
||||
import { Permission } from './enum'
|
||||
|
||||
export const defaultConfig: Config = {
|
||||
permission: Permission,
|
||||
domain: '',
|
||||
urlPath: '',
|
||||
host: '0.0.0.0',
|
||||
port: 3000,
|
||||
socket: {
|
||||
group: undefined,
|
||||
owner: undefined,
|
||||
mode: undefined
|
||||
},
|
||||
loglevel: 'info',
|
||||
urlAddPort: false,
|
||||
allowOrigin: ['localhost'],
|
||||
useSSL: false,
|
||||
hsts: {
|
||||
enable: true,
|
||||
maxAgeSeconds: 60 * 60 * 24 * 365,
|
||||
includeSubdomains: true,
|
||||
preload: true
|
||||
},
|
||||
csp: {
|
||||
enable: true,
|
||||
directives: {},
|
||||
addDefaults: true,
|
||||
addDisqus: true,
|
||||
addGoogleAnalytics: true,
|
||||
upgradeInsecureRequests: 'auto',
|
||||
reportURI: undefined
|
||||
},
|
||||
protocolUseSSL: false,
|
||||
useCDN: false,
|
||||
allowAnonymous: true,
|
||||
allowAnonymousEdits: false,
|
||||
allowFreeURL: false,
|
||||
forbiddenNoteIDs: ['robots.txt', 'favicon.ico', 'api', 'build', 'css', 'docs', 'fonts', 'js', 'uploads', 'vendor', 'views'],
|
||||
defaultPermission: 'editable',
|
||||
dbURL: '',
|
||||
db: {},
|
||||
// ssl path
|
||||
sslKeyPath: '',
|
||||
sslCertPath: '',
|
||||
sslCAPath: [],
|
||||
dhParamPath: '',
|
||||
// other path
|
||||
publicPath: './public',
|
||||
viewPath: './public/views',
|
||||
tmpPath: os.tmpdir(),
|
||||
defaultNotePath: './public/default.md',
|
||||
docsPath: './public/docs',
|
||||
uploadsPath: './public/uploads',
|
||||
localesPath: './locales',
|
||||
// session
|
||||
sessionName: 'connect.sid',
|
||||
sessionSecret: 'secret',
|
||||
sessionSecretLen: 128,
|
||||
sessionLife: 14 * 24 * 60 * 60 * 1000, // 14 days
|
||||
staticCacheTime: 1 * 24 * 60 * 60 * 1000, // 1 day
|
||||
// socket.io
|
||||
heartbeatInterval: 5000,
|
||||
heartbeatTimeout: 10000,
|
||||
// too busy timeout
|
||||
tooBusyLag: 70,
|
||||
// document
|
||||
documentMaxLength: 100000,
|
||||
// image upload setting, available options are imgur/s3/filesystem/azure/lutim
|
||||
imageUploadType: 'filesystem',
|
||||
lutim: {
|
||||
url: 'https://framapic.org/'
|
||||
},
|
||||
minio: {
|
||||
accessKey: undefined,
|
||||
secretKey: undefined,
|
||||
endPoint: undefined,
|
||||
secure: true,
|
||||
port: 9000
|
||||
},
|
||||
gitlab: {
|
||||
baseURL: undefined,
|
||||
clientID: undefined,
|
||||
clientSecret: undefined,
|
||||
scope: undefined,
|
||||
version: 'v4'
|
||||
},
|
||||
saml: {
|
||||
idpSsoUrl: undefined,
|
||||
idpCert: undefined,
|
||||
issuer: undefined,
|
||||
identifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
|
||||
disableRequestedAuthnContext: false,
|
||||
groupAttribute: undefined,
|
||||
externalGroups: [],
|
||||
requiredGroups: [],
|
||||
attribute: {
|
||||
id: undefined,
|
||||
username: undefined,
|
||||
email: undefined
|
||||
}
|
||||
},
|
||||
email: true,
|
||||
allowEmailRegister: true,
|
||||
allowGravatar: true,
|
||||
openID: false,
|
||||
// linkifyHeaderStyle - How is a header text converted into a link id.
|
||||
// Header Example: "3.1. Good Morning my Friend! - Do you have 5$?"
|
||||
// * 'keep-case' is the legacy CodiMD value.
|
||||
// Generated id: "31-Good-Morning-my-Friend---Do-you-have-5"
|
||||
// * 'lower-case' is the same like legacy (see above), but converted to lower-case.
|
||||
// Generated id: "#31-good-morning-my-friend---do-you-have-5"
|
||||
// * 'gfm' _GitHub-Flavored Markdown_ style as described here:
|
||||
// https://gist.github.com/asabaylus/3071099#gistcomment-1593627
|
||||
// It works like 'lower-case', but making sure the ID is unique.
|
||||
// This is What GitHub, GitLab and (hopefully) most other tools use.
|
||||
// Generated id: "31-good-morning-my-friend---do-you-have-5"
|
||||
// 2nd appearance: "31-good-morning-my-friend---do-you-have-5-1"
|
||||
// 3rd appearance: "31-good-morning-my-friend---do-you-have-5-2"
|
||||
linkifyHeaderStyle: 'keep-case'
|
||||
}
|
15
old_src/lib/config/defaultSSL.ts
Normal file
15
old_src/lib/config/defaultSSL.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import fs from 'fs'
|
||||
|
||||
function getFile (path): string {
|
||||
if (fs.existsSync(path)) {
|
||||
return path
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export const defaultSSL = {
|
||||
sslKeyPath: getFile('/run/secrets/key.pem'),
|
||||
sslCertPath: getFile('/run/secrets/cert.pem'),
|
||||
sslCAPath: getFile('/run/secrets/ca.pem') !== undefined ? [getFile('/run/secrets/ca.pem')] : [],
|
||||
dhParamPath: getFile('/run/secrets/dhparam.pem')
|
||||
}
|
57
old_src/lib/config/dockerSecret.ts
Normal file
57
old_src/lib/config/dockerSecret.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
const basePath = path.resolve('/run/secrets/')
|
||||
|
||||
function getSecret (secret): string | undefined {
|
||||
const filePath = path.join(basePath, secret)
|
||||
if (fs.existsSync(filePath)) return fs.readFileSync(filePath, 'utf-8')
|
||||
return undefined
|
||||
}
|
||||
|
||||
export let dockerSecret: { s3: { accessKeyId: string | undefined; secretAccessKey: string | undefined }; github: { clientID: string | undefined; clientSecret: string | undefined }; facebook: { clientID: string | undefined; clientSecret: string | undefined }; google: { clientID: string | undefined; hostedDomain: string | undefined; clientSecret: string | undefined }; sessionSecret: string | undefined; sslKeyPath: string | undefined; twitter: { consumerSecret: string | undefined; consumerKey: string | undefined }; dropbox: { clientID: string | undefined; clientSecret: string | undefined; appKey: string | undefined }; gitlab: { clientID: string | undefined; clientSecret: string | undefined }; imgur: string | undefined; sslCertPath: string | undefined; sslCAPath: (string | undefined)[]; dhParamPath: string | undefined; dbURL: string | undefined; azure: { connectionString: string | undefined } }
|
||||
|
||||
if (fs.existsSync(basePath)) {
|
||||
dockerSecret = {
|
||||
dbURL: getSecret('dbURL'),
|
||||
sessionSecret: getSecret('sessionsecret'),
|
||||
sslKeyPath: getSecret('sslkeypath'),
|
||||
sslCertPath: getSecret('sslcertpath'),
|
||||
sslCAPath: [getSecret('sslcapath')],
|
||||
dhParamPath: getSecret('dhparampath'),
|
||||
s3: {
|
||||
accessKeyId: getSecret('s3_acccessKeyId'),
|
||||
secretAccessKey: getSecret('s3_secretAccessKey')
|
||||
},
|
||||
azure: {
|
||||
connectionString: getSecret('azure_connectionString')
|
||||
},
|
||||
facebook: {
|
||||
clientID: getSecret('facebook_clientID'),
|
||||
clientSecret: getSecret('facebook_clientSecret')
|
||||
},
|
||||
twitter: {
|
||||
consumerKey: getSecret('twitter_consumerKey'),
|
||||
consumerSecret: getSecret('twitter_consumerSecret')
|
||||
},
|
||||
github: {
|
||||
clientID: getSecret('github_clientID'),
|
||||
clientSecret: getSecret('github_clientSecret')
|
||||
},
|
||||
gitlab: {
|
||||
clientID: getSecret('gitlab_clientID'),
|
||||
clientSecret: getSecret('gitlab_clientSecret')
|
||||
},
|
||||
dropbox: {
|
||||
clientID: getSecret('dropbox_clientID'),
|
||||
clientSecret: getSecret('dropbox_clientSecret'),
|
||||
appKey: getSecret('dropbox_appKey')
|
||||
},
|
||||
google: {
|
||||
clientID: getSecret('google_clientID'),
|
||||
clientSecret: getSecret('google_clientSecret'),
|
||||
hostedDomain: getSecret('google_hostedDomain')
|
||||
},
|
||||
imgur: getSecret('imgur_clientid')
|
||||
}
|
||||
}
|
29
old_src/lib/config/enum.ts
Normal file
29
old_src/lib/config/enum.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
export interface Environment {
|
||||
development: string;
|
||||
production: string;
|
||||
test: string;
|
||||
}
|
||||
|
||||
export const Environment: Environment = {
|
||||
development: 'development',
|
||||
production: 'production',
|
||||
test: 'test'
|
||||
}
|
||||
|
||||
export interface Permission {
|
||||
freely: string;
|
||||
editable: string;
|
||||
limited: string;
|
||||
locked: string;
|
||||
protected: string;
|
||||
private: string;
|
||||
}
|
||||
|
||||
export const Permission: Permission = {
|
||||
freely: 'freely',
|
||||
editable: 'editable',
|
||||
limited: 'limited',
|
||||
locked: 'locked',
|
||||
protected: 'protected',
|
||||
private: 'private'
|
||||
}
|
138
old_src/lib/config/environment.ts
Normal file
138
old_src/lib/config/environment.ts
Normal file
|
@ -0,0 +1,138 @@
|
|||
import { toArrayConfig, toBooleanConfig, toIntegerConfig } from './utils'
|
||||
|
||||
export const environment = {
|
||||
sourceURL: process.env.CMD_SOURCE_URL,
|
||||
domain: process.env.CMD_DOMAIN,
|
||||
urlPath: process.env.CMD_URL_PATH,
|
||||
host: process.env.CMD_HOST,
|
||||
port: toIntegerConfig(process.env.CMD_PORT),
|
||||
path: process.env.CMD_PATH,
|
||||
socket: {
|
||||
group: process.env.CMD_SOCKET_GROUP,
|
||||
owner: process.env.CMD_SOCKET_OWNER,
|
||||
mode: process.env.CMD_SOCKET_MODE
|
||||
},
|
||||
loglevel: process.env.CMD_LOGLEVEL,
|
||||
urlAddPort: toBooleanConfig(process.env.CMD_URL_ADDPORT),
|
||||
useSSL: toBooleanConfig(process.env.CMD_USESSL),
|
||||
hsts: {
|
||||
enable: toBooleanConfig(process.env.CMD_HSTS_ENABLE),
|
||||
maxAgeSeconds: toIntegerConfig(process.env.CMD_HSTS_MAX_AGE),
|
||||
includeSubdomains: toBooleanConfig(process.env.CMD_HSTS_INCLUDE_SUBDOMAINS),
|
||||
preload: toBooleanConfig(process.env.CMD_HSTS_PRELOAD)
|
||||
},
|
||||
csp: {
|
||||
enable: toBooleanConfig(process.env.CMD_CSP_ENABLE),
|
||||
reportURI: process.env.CMD_CSP_REPORTURI
|
||||
},
|
||||
protocolUseSSL: toBooleanConfig(process.env.CMD_PROTOCOL_USESSL),
|
||||
allowOrigin: toArrayConfig(process.env.CMD_ALLOW_ORIGIN),
|
||||
useCDN: toBooleanConfig(process.env.CMD_USECDN),
|
||||
allowAnonymous: toBooleanConfig(process.env.CMD_ALLOW_ANONYMOUS),
|
||||
allowAnonymousEdits: toBooleanConfig(process.env.CMD_ALLOW_ANONYMOUS_EDITS),
|
||||
allowFreeURL: toBooleanConfig(process.env.CMD_ALLOW_FREEURL),
|
||||
forbiddenNoteIDs: toArrayConfig(process.env.CMD_FORBIDDEN_NOTE_IDS),
|
||||
defaultPermission: process.env.CMD_DEFAULT_PERMISSION,
|
||||
dbURL: process.env.CMD_DB_URL,
|
||||
sessionSecret: process.env.CMD_SESSION_SECRET,
|
||||
sessionLife: toIntegerConfig(process.env.CMD_SESSION_LIFE),
|
||||
tooBusyLag: toIntegerConfig(process.env.CMD_TOOBUSY_LAG),
|
||||
imageUploadType: process.env.CMD_IMAGE_UPLOAD_TYPE,
|
||||
imgur: {
|
||||
clientID: process.env.CMD_IMGUR_CLIENTID
|
||||
},
|
||||
s3: {
|
||||
accessKeyId: process.env.CMD_S3_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.CMD_S3_SECRET_ACCESS_KEY,
|
||||
region: process.env.CMD_S3_REGION,
|
||||
endpoint: process.env.CMD_S3_ENDPOINT
|
||||
},
|
||||
minio: {
|
||||
accessKey: process.env.CMD_MINIO_ACCESS_KEY,
|
||||
secretKey: process.env.CMD_MINIO_SECRET_KEY,
|
||||
endPoint: process.env.CMD_MINIO_ENDPOINT,
|
||||
secure: toBooleanConfig(process.env.CMD_MINIO_SECURE),
|
||||
port: toIntegerConfig(process.env.CMD_MINIO_PORT)
|
||||
},
|
||||
lutim: {
|
||||
url: process.env.CMD_LUTIM_URL
|
||||
},
|
||||
s3bucket: process.env.CMD_S3_BUCKET,
|
||||
azure: {
|
||||
connectionString: process.env.CMD_AZURE_CONNECTION_STRING,
|
||||
container: process.env.CMD_AZURE_CONTAINER
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.CMD_FACEBOOK_CLIENTID,
|
||||
clientSecret: process.env.CMD_FACEBOOK_CLIENTSECRET
|
||||
},
|
||||
twitter: {
|
||||
consumerKey: process.env.CMD_TWITTER_CONSUMERKEY,
|
||||
consumerSecret: process.env.CMD_TWITTER_CONSUMERSECRET
|
||||
},
|
||||
github: {
|
||||
clientID: process.env.CMD_GITHUB_CLIENTID,
|
||||
clientSecret: process.env.CMD_GITHUB_CLIENTSECRET
|
||||
},
|
||||
gitlab: {
|
||||
baseURL: process.env.CMD_GITLAB_BASEURL,
|
||||
clientID: process.env.CMD_GITLAB_CLIENTID,
|
||||
clientSecret: process.env.CMD_GITLAB_CLIENTSECRET,
|
||||
scope: process.env.CMD_GITLAB_SCOPE
|
||||
},
|
||||
oauth2: {
|
||||
providerName: process.env.CMD_OAUTH2_PROVIDERNAME,
|
||||
baseURL: process.env.CMD_OAUTH2_BASEURL,
|
||||
userProfileURL: process.env.CMD_OAUTH2_USER_PROFILE_URL,
|
||||
userProfileUsernameAttr: process.env.CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR,
|
||||
userProfileDisplayNameAttr: process.env.CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR,
|
||||
userProfileEmailAttr: process.env.CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR,
|
||||
tokenURL: process.env.CMD_OAUTH2_TOKEN_URL,
|
||||
authorizationURL: process.env.CMD_OAUTH2_AUTHORIZATION_URL,
|
||||
clientID: process.env.CMD_OAUTH2_CLIENT_ID,
|
||||
clientSecret: process.env.CMD_OAUTH2_CLIENT_SECRET,
|
||||
scope: process.env.CMD_OAUTH2_SCOPE
|
||||
},
|
||||
dropbox: {
|
||||
clientID: process.env.CMD_DROPBOX_CLIENTID,
|
||||
clientSecret: process.env.CMD_DROPBOX_CLIENTSECRET,
|
||||
appKey: process.env.CMD_DROPBOX_APPKEY
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.CMD_GOOGLE_CLIENTID,
|
||||
clientSecret: process.env.CMD_GOOGLE_CLIENTSECRET,
|
||||
hostedDomain: process.env.CMD_GOOGLE_HOSTEDDOMAIN
|
||||
},
|
||||
ldap: {
|
||||
providerName: process.env.CMD_LDAP_PROVIDERNAME,
|
||||
url: process.env.CMD_LDAP_URL,
|
||||
bindDn: process.env.CMD_LDAP_BINDDN,
|
||||
bindCredentials: process.env.CMD_LDAP_BINDCREDENTIALS,
|
||||
searchBase: process.env.CMD_LDAP_SEARCHBASE,
|
||||
searchFilter: process.env.CMD_LDAP_SEARCHFILTER,
|
||||
searchAttributes: toArrayConfig(process.env.CMD_LDAP_SEARCHATTRIBUTES),
|
||||
usernameField: process.env.CMD_LDAP_USERNAMEFIELD,
|
||||
useridField: process.env.CMD_LDAP_USERIDFIELD,
|
||||
tlsca: process.env.CMD_LDAP_TLS_CA
|
||||
},
|
||||
saml: {
|
||||
idpSsoUrl: process.env.CMD_SAML_IDPSSOURL,
|
||||
idpCert: process.env.CMD_SAML_IDPCERT,
|
||||
issuer: process.env.CMD_SAML_ISSUER,
|
||||
identifierFormat: process.env.CMD_SAML_IDENTIFIERFORMAT,
|
||||
disableRequestedAuthnContext: toBooleanConfig(process.env.CMD_SAML_DISABLEREQUESTEDAUTHNCONTEXT),
|
||||
groupAttribute: process.env.CMD_SAML_GROUPATTRIBUTE,
|
||||
externalGroups: toArrayConfig(process.env.CMD_SAML_EXTERNALGROUPS, '|', []),
|
||||
requiredGroups: toArrayConfig(process.env.CMD_SAML_REQUIREDGROUPS, '|', []),
|
||||
attribute: {
|
||||
id: process.env.CMD_SAML_ATTRIBUTE_ID,
|
||||
username: process.env.CMD_SAML_ATTRIBUTE_USERNAME,
|
||||
email: process.env.CMD_SAML_ATTRIBUTE_EMAIL
|
||||
}
|
||||
},
|
||||
email: toBooleanConfig(process.env.CMD_EMAIL),
|
||||
allowEmailRegister: toBooleanConfig(process.env.CMD_ALLOW_EMAIL_REGISTER),
|
||||
allowGravatar: toBooleanConfig(process.env.CMD_ALLOW_GRAVATAR),
|
||||
openID: toBooleanConfig(process.env.CMD_OPENID),
|
||||
linkifyHeaderStyle: process.env.CMD_LINKIFY_HEADER_STYLE
|
||||
}
|
118
old_src/lib/config/hackmdEnvironment.ts
Normal file
118
old_src/lib/config/hackmdEnvironment.ts
Normal file
|
@ -0,0 +1,118 @@
|
|||
import { toArrayConfig, toBooleanConfig, toIntegerConfig } from './utils'
|
||||
|
||||
export const hackmdEnvironment = {
|
||||
domain: process.env.HMD_DOMAIN,
|
||||
urlPath: process.env.HMD_URL_PATH,
|
||||
port: toIntegerConfig(process.env.HMD_PORT),
|
||||
urlAddPort: toBooleanConfig(process.env.HMD_URL_ADDPORT),
|
||||
useSSL: toBooleanConfig(process.env.HMD_USESSL),
|
||||
hsts: {
|
||||
enable: toBooleanConfig(process.env.HMD_HSTS_ENABLE),
|
||||
maxAgeSeconds: toIntegerConfig(process.env.HMD_HSTS_MAX_AGE),
|
||||
includeSubdomains: toBooleanConfig(process.env.HMD_HSTS_INCLUDE_SUBDOMAINS),
|
||||
preload: toBooleanConfig(process.env.HMD_HSTS_PRELOAD)
|
||||
},
|
||||
csp: {
|
||||
enable: toBooleanConfig(process.env.HMD_CSP_ENABLE),
|
||||
reportURI: process.env.HMD_CSP_REPORTURI
|
||||
},
|
||||
protocolUseSSL: toBooleanConfig(process.env.HMD_PROTOCOL_USESSL),
|
||||
allowOrigin: toArrayConfig(process.env.HMD_ALLOW_ORIGIN),
|
||||
useCDN: toBooleanConfig(process.env.HMD_USECDN),
|
||||
allowAnonymous: toBooleanConfig(process.env.HMD_ALLOW_ANONYMOUS),
|
||||
allowAnonymousEdits: toBooleanConfig(process.env.HMD_ALLOW_ANONYMOUS_EDITS),
|
||||
allowFreeURL: toBooleanConfig(process.env.HMD_ALLOW_FREEURL),
|
||||
defaultPermission: process.env.HMD_DEFAULT_PERMISSION,
|
||||
dbURL: process.env.HMD_DB_URL,
|
||||
sessionSecret: process.env.HMD_SESSION_SECRET,
|
||||
sessionLife: toIntegerConfig(process.env.HMD_SESSION_LIFE),
|
||||
imageUploadType: process.env.HMD_IMAGE_UPLOAD_TYPE,
|
||||
imgur: {
|
||||
clientID: process.env.HMD_IMGUR_CLIENTID
|
||||
},
|
||||
s3: {
|
||||
accessKeyId: process.env.HMD_S3_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.HMD_S3_SECRET_ACCESS_KEY,
|
||||
region: process.env.HMD_S3_REGION
|
||||
},
|
||||
minio: {
|
||||
accessKey: process.env.HMD_MINIO_ACCESS_KEY,
|
||||
secretKey: process.env.HMD_MINIO_SECRET_KEY,
|
||||
endPoint: process.env.HMD_MINIO_ENDPOINT,
|
||||
secure: toBooleanConfig(process.env.HMD_MINIO_SECURE),
|
||||
port: toIntegerConfig(process.env.HMD_MINIO_PORT)
|
||||
},
|
||||
s3bucket: process.env.HMD_S3_BUCKET,
|
||||
azure: {
|
||||
connectionString: process.env.HMD_AZURE_CONNECTION_STRING,
|
||||
container: process.env.HMD_AZURE_CONTAINER
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.HMD_FACEBOOK_CLIENTID,
|
||||
clientSecret: process.env.HMD_FACEBOOK_CLIENTSECRET
|
||||
},
|
||||
twitter: {
|
||||
consumerKey: process.env.HMD_TWITTER_CONSUMERKEY,
|
||||
consumerSecret: process.env.HMD_TWITTER_CONSUMERSECRET
|
||||
},
|
||||
github: {
|
||||
clientID: process.env.HMD_GITHUB_CLIENTID,
|
||||
clientSecret: process.env.HMD_GITHUB_CLIENTSECRET
|
||||
},
|
||||
gitlab: {
|
||||
baseURL: process.env.HMD_GITLAB_BASEURL,
|
||||
clientID: process.env.HMD_GITLAB_CLIENTID,
|
||||
clientSecret: process.env.HMD_GITLAB_CLIENTSECRET,
|
||||
scope: process.env.HMD_GITLAB_SCOPE
|
||||
},
|
||||
oauth2: {
|
||||
baseURL: process.env.HMD_OAUTH2_BASEURL,
|
||||
userProfileURL: process.env.HMD_OAUTH2_USER_PROFILE_URL,
|
||||
userProfileUsernameAttr: process.env.HMD_OAUTH2_USER_PROFILE_USERNAME_ATTR,
|
||||
userProfileDisplayNameAttr: process.env.HMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR,
|
||||
userProfileEmailAttr: process.env.HMD_OAUTH2_USER_PROFILE_EMAIL_ATTR,
|
||||
tokenURL: process.env.HMD_OAUTH2_TOKEN_URL,
|
||||
authorizationURL: process.env.HMD_OAUTH2_AUTHORIZATION_URL,
|
||||
clientID: process.env.HMD_OAUTH2_CLIENT_ID,
|
||||
clientSecret: process.env.HMD_OAUTH2_CLIENT_SECRET,
|
||||
scope: process.env.HMD_OAUTH2_SCOPE
|
||||
},
|
||||
dropbox: {
|
||||
clientID: process.env.HMD_DROPBOX_CLIENTID,
|
||||
clientSecret: process.env.HMD_DROPBOX_CLIENTSECRET,
|
||||
appKey: process.env.HMD_DROPBOX_APPKEY
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.HMD_GOOGLE_CLIENTID,
|
||||
clientSecret: process.env.HMD_GOOGLE_CLIENTSECRET
|
||||
},
|
||||
ldap: {
|
||||
providerName: process.env.HMD_LDAP_PROVIDERNAME,
|
||||
url: process.env.HMD_LDAP_URL,
|
||||
bindDn: process.env.HMD_LDAP_BINDDN,
|
||||
bindCredentials: process.env.HMD_LDAP_BINDCREDENTIALS,
|
||||
searchBase: process.env.HMD_LDAP_SEARCHBASE,
|
||||
searchFilter: process.env.HMD_LDAP_SEARCHFILTER,
|
||||
searchAttributes: toArrayConfig(process.env.HMD_LDAP_SEARCHATTRIBUTES),
|
||||
usernameField: process.env.HMD_LDAP_USERNAMEFIELD,
|
||||
useridField: process.env.HMD_LDAP_USERIDFIELD,
|
||||
tlsca: process.env.HMD_LDAP_TLS_CA
|
||||
},
|
||||
saml: {
|
||||
idpSsoUrl: process.env.HMD_SAML_IDPSSOURL,
|
||||
idpCert: process.env.HMD_SAML_IDPCERT,
|
||||
issuer: process.env.HMD_SAML_ISSUER,
|
||||
identifierFormat: process.env.HMD_SAML_IDENTIFIERFORMAT,
|
||||
disableRequestedAuthnContext: toBooleanConfig(process.env.HMD_SAML_DISABLEREQUESTEDAUTHNCONTEXT),
|
||||
groupAttribute: process.env.HMD_SAML_GROUPATTRIBUTE,
|
||||
externalGroups: toArrayConfig(process.env.HMD_SAML_EXTERNALGROUPS, '|', []),
|
||||
requiredGroups: toArrayConfig(process.env.HMD_SAML_REQUIREDGROUPS, '|', []),
|
||||
attribute: {
|
||||
id: process.env.HMD_SAML_ATTRIBUTE_ID,
|
||||
username: process.env.HMD_SAML_ATTRIBUTE_USERNAME,
|
||||
email: process.env.HMD_SAML_ATTRIBUTE_EMAIL
|
||||
}
|
||||
},
|
||||
email: toBooleanConfig(process.env.HMD_EMAIL),
|
||||
allowEmailRegister: toBooleanConfig(process.env.HMD_ALLOW_EMAIL_REGISTER)
|
||||
}
|
211
old_src/lib/config/index.ts
Normal file
211
old_src/lib/config/index.ts
Normal file
|
@ -0,0 +1,211 @@
|
|||
import crypto from 'crypto'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { merge } from 'lodash'
|
||||
import { Environment, Permission } from './enum'
|
||||
import { logger } from '../logger'
|
||||
import { getGitCommit, getGitHubURL } from './utils'
|
||||
import { defaultConfig } from './default'
|
||||
import { defaultSSL } from './defaultSSL'
|
||||
import { oldDefault } from './oldDefault'
|
||||
import { oldEnvironment } from './oldEnvironment'
|
||||
import { hackmdEnvironment } from './hackmdEnvironment'
|
||||
import { environment } from './environment'
|
||||
import { dockerSecret } from './dockerSecret'
|
||||
import deepFreeze = require('deep-freeze')
|
||||
|
||||
const appRootPath = path.resolve(__dirname, '../../../')
|
||||
const env = process.env.NODE_ENV || Environment.development
|
||||
const debugConfig = {
|
||||
debug: (env === Environment.development)
|
||||
}
|
||||
|
||||
// Get version string from package.json
|
||||
// TODO: There are other ways to geht the current version
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { version, repository } = require(path.join(appRootPath, 'package.json'))
|
||||
|
||||
const commitID = getGitCommit(appRootPath)
|
||||
const sourceURL = getGitHubURL(repository.url, commitID || version)
|
||||
const fullversion = commitID ? `${version}-${commitID}` : version
|
||||
|
||||
const packageConfig = {
|
||||
version: version,
|
||||
minimumCompatibleVersion: '0.5.0',
|
||||
fullversion: fullversion,
|
||||
sourceURL: sourceURL
|
||||
}
|
||||
|
||||
const configFilePath = path.resolve(appRootPath, process.env.CMD_CONFIG_FILE ||
|
||||
'config.json')
|
||||
const fileConfig = fs.existsSync(configFilePath) ? require(configFilePath)[env] : undefined
|
||||
merge(defaultConfig, defaultSSL)
|
||||
merge(defaultConfig, oldDefault)
|
||||
merge(defaultConfig, debugConfig)
|
||||
merge(defaultConfig, packageConfig)
|
||||
merge(defaultConfig, fileConfig)
|
||||
merge(defaultConfig, oldEnvironment)
|
||||
merge(defaultConfig, hackmdEnvironment)
|
||||
merge(defaultConfig, environment)
|
||||
merge(defaultConfig, dockerSecret)
|
||||
|
||||
if (['debug', 'verbose', 'info', 'warn', 'error'].includes(defaultConfig.loglevel)) {
|
||||
logger.level = defaultConfig.loglevel
|
||||
} else {
|
||||
logger.error('Selected loglevel %s doesn\'t exist, using default level \'debug\'. Available options: debug, verbose, info, warn, error', defaultConfig.loglevel)
|
||||
}
|
||||
|
||||
// load LDAP CA
|
||||
if (defaultConfig.ldap?.tlsca) {
|
||||
const ca = defaultConfig.ldap.tlsca.split(',')
|
||||
const caContent: string[] = []
|
||||
for (const i of ca) {
|
||||
if (fs.existsSync(i)) {
|
||||
caContent.push(fs.readFileSync(i, 'utf8'))
|
||||
}
|
||||
}
|
||||
const tlsOptions = {
|
||||
ca: caContent
|
||||
}
|
||||
defaultConfig.ldap.tlsOptions = defaultConfig.ldap.tlsOptions ? Object.assign(defaultConfig.ldap.tlsOptions, tlsOptions) : tlsOptions
|
||||
}
|
||||
|
||||
// Permission
|
||||
defaultConfig.permission = Permission
|
||||
if (!defaultConfig.allowAnonymous && !defaultConfig.allowAnonymousEdits) {
|
||||
delete defaultConfig.permission.freely
|
||||
}
|
||||
if (!(defaultConfig.defaultPermission in defaultConfig.permission)) {
|
||||
defaultConfig.defaultPermission = defaultConfig.permission.editable
|
||||
}
|
||||
|
||||
// cache result, cannot change config in runtime!!!
|
||||
defaultConfig.isStandardHTTPsPort = (function isStandardHTTPsPort (): boolean {
|
||||
return defaultConfig.useSSL && defaultConfig.port === 443
|
||||
})()
|
||||
defaultConfig.isStandardHTTPPort = (function isStandardHTTPPort (): boolean {
|
||||
return !defaultConfig.useSSL && defaultConfig.port === 80
|
||||
})()
|
||||
|
||||
// cache serverURL
|
||||
defaultConfig.serverURL = (function getserverurl (): string {
|
||||
let url = ''
|
||||
if (defaultConfig.domain) {
|
||||
const protocol = defaultConfig.protocolUseSSL ? 'https://' : 'http://'
|
||||
url = protocol + defaultConfig.domain
|
||||
if (defaultConfig.urlAddPort) {
|
||||
if (!defaultConfig.isStandardHTTPPort || !defaultConfig.isStandardHTTPsPort) {
|
||||
url += ':' + defaultConfig.port
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defaultConfig.urlPath) {
|
||||
url += '/' + defaultConfig.urlPath
|
||||
}
|
||||
return url
|
||||
})()
|
||||
|
||||
if (defaultConfig.serverURL === '') {
|
||||
logger.warn('Neither \'domain\' nor \'CMD_DOMAIN\' is configured. This can cause issues with various components.\nHint: Make sure \'protocolUseSSL\' and \'urlAddPort\' or \'CMD_PROTOCOL_USESSL\' and \'CMD_URL_ADDPORT\' are configured properly.')
|
||||
}
|
||||
|
||||
defaultConfig.Environment = Environment
|
||||
|
||||
// auth method
|
||||
defaultConfig.isFacebookEnable = defaultConfig.facebook?.clientID && defaultConfig.facebook.clientSecret
|
||||
defaultConfig.isGoogleEnable = defaultConfig.google?.clientID && defaultConfig.google.clientSecret
|
||||
defaultConfig.isDropboxEnable = defaultConfig.dropbox?.clientID && defaultConfig.dropbox.clientSecret
|
||||
defaultConfig.isTwitterEnable = defaultConfig.twitter?.consumerKey && defaultConfig.twitter.consumerSecret
|
||||
defaultConfig.isEmailEnable = defaultConfig.email
|
||||
defaultConfig.isOpenIDEnable = defaultConfig.openID
|
||||
defaultConfig.isGitHubEnable = defaultConfig.github?.clientID && defaultConfig.github.clientSecret
|
||||
defaultConfig.isGitLabEnable = defaultConfig.gitlab?.clientID && defaultConfig.gitlab.clientSecret
|
||||
defaultConfig.isLDAPEnable = defaultConfig.ldap?.url
|
||||
defaultConfig.isSAMLEnable = defaultConfig.saml?.idpSsoUrl
|
||||
defaultConfig.isOAuth2Enable = defaultConfig.oauth2?.clientID && defaultConfig.oauth2.clientSecret
|
||||
|
||||
// Check gitlab api version
|
||||
if (defaultConfig.gitlab && defaultConfig.gitlab.version !== 'v4' && defaultConfig.gitlab.version !== 'v3') {
|
||||
logger.warn('config.js contains wrong version (' + defaultConfig.gitlab.version + ') for gitlab api; it should be \'v3\' or \'v4\'. Defaulting to v4')
|
||||
defaultConfig.gitlab.version = 'v4'
|
||||
}
|
||||
// If gitlab scope is api, enable snippets Export/import
|
||||
defaultConfig.isGitlabSnippetsEnable = (!defaultConfig.gitlab?.scope || defaultConfig.gitlab.scope === 'api') && defaultConfig.isGitLabEnable
|
||||
|
||||
// Only update i18n files in development setups
|
||||
defaultConfig.updateI18nFiles = (env === Environment.development)
|
||||
|
||||
// merge legacy values
|
||||
const keys = Object.keys(defaultConfig)
|
||||
const uppercase = /[A-Z]/
|
||||
for (let i = keys.length; i--;) {
|
||||
const lowercaseKey = keys[i].toLowerCase()
|
||||
// if the config contains uppercase letters
|
||||
// and a lowercase version of this setting exists
|
||||
// and the config with uppercase is not set
|
||||
// we set the new config using the old key.
|
||||
if (uppercase.test(keys[i]) &&
|
||||
defaultConfig[lowercaseKey] !== undefined &&
|
||||
fileConfig[keys[i]] === undefined) {
|
||||
logger.warn('config.js contains deprecated lowercase setting for ' + keys[i] + '. Please change your config.js file to replace ' + lowercaseKey + ' with ' + keys[i])
|
||||
defaultConfig[keys[i]] = defaultConfig[lowercaseKey]
|
||||
}
|
||||
}
|
||||
|
||||
// Notify users about the prefix change and inform them they use legacy prefix for environment variables
|
||||
if (Object.keys(process.env).toString().includes('HMD_')) {
|
||||
logger.warn('Using legacy HMD prefix for environment variables. Please change your variables in future. For details see: https://github.com/codimd/server#environment-variables-will-overwrite-other-server-configs')
|
||||
}
|
||||
|
||||
// Generate session secret if it stays on default values
|
||||
if (defaultConfig.sessionSecret === 'secret') {
|
||||
logger.warn('Session secret not set. Using random generated one. Please set `sessionSecret` in your config.js file. All users will be logged out.')
|
||||
defaultConfig.sessionSecret = crypto.randomBytes(Math.ceil(defaultConfig.sessionSecretLen / 2)) // generate crypto graphic random number
|
||||
.toString('hex') // convert to hexadecimal format
|
||||
.slice(0, defaultConfig.sessionSecretLen) // return required number of characters
|
||||
}
|
||||
|
||||
// Validate upload upload providers
|
||||
if (!['filesystem', 's3', 'minio', 'imgur', 'azure', 'lutim'].includes(defaultConfig.imageUploadType)) {
|
||||
logger.error('"imageuploadtype" is not correctly set. Please use "filesystem", "s3", "minio", "azure", "lutim" or "imgur". Defaulting to "filesystem"')
|
||||
defaultConfig.imageUploadType = 'filesystem'
|
||||
}
|
||||
|
||||
// figure out mime types for image uploads
|
||||
switch (defaultConfig.imageUploadType) {
|
||||
case 'imgur':
|
||||
defaultConfig.allowedUploadMimeTypes = [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/jpg',
|
||||
'image/gif'
|
||||
]
|
||||
break
|
||||
default:
|
||||
defaultConfig.allowedUploadMimeTypes = [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/jpg',
|
||||
'image/gif',
|
||||
'image/svg+xml'
|
||||
]
|
||||
}
|
||||
|
||||
// generate correct path
|
||||
defaultConfig.sslCAPath.forEach(function (capath, i, array) {
|
||||
array[i] = path.resolve(appRootPath, capath)
|
||||
})
|
||||
|
||||
defaultConfig.sslCertPath = path.resolve(appRootPath, defaultConfig.sslCertPath)
|
||||
defaultConfig.sslKeyPath = path.resolve(appRootPath, defaultConfig.sslKeyPath)
|
||||
defaultConfig.dhParamPath = path.resolve(appRootPath, defaultConfig.dhParamPath)
|
||||
defaultConfig.viewPath = path.resolve(appRootPath, defaultConfig.viewPath)
|
||||
defaultConfig.tmpPath = path.resolve(appRootPath, defaultConfig.tmpPath)
|
||||
defaultConfig.publicPath = path.resolve(appRootPath, defaultConfig.publicPath)
|
||||
defaultConfig.defaultNotePath = path.resolve(appRootPath, defaultConfig.defaultNotePath)
|
||||
defaultConfig.docsPath = path.resolve(appRootPath, defaultConfig.docsPath)
|
||||
defaultConfig.uploadsPath = path.resolve(appRootPath, defaultConfig.uploadsPath)
|
||||
defaultConfig.localesPath = path.resolve(appRootPath, defaultConfig.localesPath)
|
||||
|
||||
// make config readonly
|
||||
export const config = deepFreeze(defaultConfig)
|
159
old_src/lib/config/interfaces.ts
Normal file
159
old_src/lib/config/interfaces.ts
Normal file
|
@ -0,0 +1,159 @@
|
|||
import { Permission } from './enum'
|
||||
import { IHelmetContentSecurityPolicyDirectives } from 'helmet'
|
||||
|
||||
type CSPDirectives = IHelmetContentSecurityPolicyDirectives
|
||||
|
||||
export interface Config {
|
||||
permission: Permission;
|
||||
domain: string;
|
||||
urlPath: string;
|
||||
host: string;
|
||||
port: number;
|
||||
loglevel: string;
|
||||
urlAddPort: boolean;
|
||||
allowOrigin: string[];
|
||||
useSSL: boolean;
|
||||
hsts: {
|
||||
enable: boolean;
|
||||
maxAgeSeconds: number;
|
||||
includeSubdomains: boolean;
|
||||
preload: boolean;
|
||||
};
|
||||
csp: {
|
||||
enable: boolean;
|
||||
directives?: CSPDirectives;
|
||||
addDefaults: boolean;
|
||||
addDisqus: boolean;
|
||||
addGoogleAnalytics: boolean;
|
||||
upgradeInsecureRequests: string | boolean;
|
||||
reportURI?: string;
|
||||
};
|
||||
protocolUseSSL: boolean;
|
||||
useCDN: boolean;
|
||||
allowAnonymous: boolean;
|
||||
allowAnonymousEdits: boolean;
|
||||
allowFreeURL: boolean;
|
||||
forbiddenNoteIDs: string[];
|
||||
defaultPermission: string;
|
||||
dbURL: string;
|
||||
db;
|
||||
sslKeyPath: string;
|
||||
sslCertPath: string;
|
||||
sslCAPath: string[];
|
||||
dhParamPath: string;
|
||||
publicPath: string;
|
||||
viewPath: string;
|
||||
tmpPath: string;
|
||||
defaultNotePath: string;
|
||||
docsPath: string;
|
||||
uploadsPath: string;
|
||||
sessionName: string;
|
||||
sessionSecret: string;
|
||||
sessionSecretLen: number;
|
||||
sessionLife: number;
|
||||
staticCacheTime: number;
|
||||
heartbeatInterval: number;
|
||||
heartbeatTimeout: number;
|
||||
tooBusyLag: number;
|
||||
documentMaxLength: number;
|
||||
imageUploadType: 'azure' | 'filesystem' | 'imgur' | 'lutim' | 'minio' | 's3';
|
||||
lutim?: {
|
||||
url: string;
|
||||
};
|
||||
imgur?: {
|
||||
clientID: string;
|
||||
};
|
||||
s3?: {
|
||||
accessKeyId: string;
|
||||
secretAccessKey: string;
|
||||
region: string;
|
||||
};
|
||||
minio?: {
|
||||
accessKey?: string;
|
||||
secretKey?: string;
|
||||
endPoint?: string;
|
||||
secure?: boolean;
|
||||
port?: number;
|
||||
};
|
||||
s3bucket?: string;
|
||||
azure?: {
|
||||
connectionString: string;
|
||||
container: string;
|
||||
};
|
||||
oauth2?: {
|
||||
providerName: string;
|
||||
authorizationURL: string;
|
||||
tokenURL: string;
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
};
|
||||
facebook?: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
};
|
||||
twitter?: {
|
||||
consumerKey: string;
|
||||
consumerSecret: string;
|
||||
};
|
||||
github?: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
};
|
||||
gitlab?: {
|
||||
baseURL?: string;
|
||||
clientID?: string;
|
||||
clientSecret?: string;
|
||||
scope?: string;
|
||||
version?: string;
|
||||
};
|
||||
dropbox?: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
appKey: string;
|
||||
};
|
||||
google?: {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
hostedDomain: string;
|
||||
};
|
||||
ldap?: {
|
||||
providerName: string;
|
||||
url: string;
|
||||
bindDn: string;
|
||||
bindCredentials: string;
|
||||
searchBase: string;
|
||||
searchFilter: string;
|
||||
searchAttributes: string;
|
||||
usernameField: string;
|
||||
useridField: string;
|
||||
tlsca: string;
|
||||
starttls?: boolean;
|
||||
tlsOptions: {
|
||||
ca: string[];
|
||||
};
|
||||
};
|
||||
saml?: {
|
||||
idpSsoUrl?: string;
|
||||
idpCert?: string;
|
||||
issuer?: string;
|
||||
identifierFormat?: string;
|
||||
disableRequestedAuthnContext?: boolean;
|
||||
groupAttribute?: string;
|
||||
externalGroups?: string[];
|
||||
requiredGroups?: string[];
|
||||
attribute?: {
|
||||
id?: string;
|
||||
username?: string;
|
||||
email?: string;
|
||||
};
|
||||
};
|
||||
email: boolean;
|
||||
allowEmailRegister: boolean;
|
||||
allowGravatar: boolean;
|
||||
openID: boolean;
|
||||
linkifyHeaderStyle: string;
|
||||
|
||||
// TODO: Remove escape hatch for dynamically added properties
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[propName: string]: any;
|
||||
}
|
39
old_src/lib/config/oldDefault.ts
Normal file
39
old_src/lib/config/oldDefault.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
export const oldDefault = {
|
||||
urlpath: undefined,
|
||||
urladdport: undefined,
|
||||
alloworigin: undefined,
|
||||
usessl: undefined,
|
||||
protocolusessl: undefined,
|
||||
usecdn: undefined,
|
||||
allowanonymous: undefined,
|
||||
allowanonymousedits: undefined,
|
||||
allowfreeurl: undefined,
|
||||
defaultpermission: undefined,
|
||||
dburl: undefined,
|
||||
// ssl path
|
||||
sslkeypath: undefined,
|
||||
sslcertpath: undefined,
|
||||
sslcapath: undefined,
|
||||
dhparampath: undefined,
|
||||
// other path
|
||||
tmppath: undefined,
|
||||
defaultnotepath: undefined,
|
||||
docspath: undefined,
|
||||
indexpath: undefined,
|
||||
hackmdpath: undefined,
|
||||
errorpath: undefined,
|
||||
prettypath: undefined,
|
||||
slidepath: undefined,
|
||||
// session
|
||||
sessionname: undefined,
|
||||
sessionsecret: undefined,
|
||||
sessionlife: undefined,
|
||||
staticcachetime: undefined,
|
||||
// socket.io
|
||||
heartbeatinterval: undefined,
|
||||
heartbeattimeout: undefined,
|
||||
// document
|
||||
documentmaxlength: undefined,
|
||||
imageuploadtype: undefined,
|
||||
allowemailregister: undefined
|
||||
}
|
8
old_src/lib/config/oldEnvironment.ts
Normal file
8
old_src/lib/config/oldEnvironment.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { toBooleanConfig } from './utils'
|
||||
|
||||
export const oldEnvironment = {
|
||||
debug: toBooleanConfig(process.env.DEBUG),
|
||||
dburl: process.env.DATABASE_URL,
|
||||
urlpath: process.env.URL_PATH,
|
||||
port: process.env.PORT
|
||||
}
|
53
old_src/lib/config/utils.ts
Normal file
53
old_src/lib/config/utils.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
export function toBooleanConfig (configValue: string | boolean | undefined): boolean | undefined {
|
||||
if (typeof configValue === 'string') {
|
||||
return (configValue === 'true')
|
||||
}
|
||||
return configValue
|
||||
}
|
||||
|
||||
export function toArrayConfig (configValue: string | undefined, separator = ',', fallback = []): string[] {
|
||||
if (configValue) {
|
||||
return (configValue.split(separator).map(arrayItem => arrayItem.trim()))
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
export function toIntegerConfig (configValue): number {
|
||||
if (configValue && typeof configValue === 'string') {
|
||||
return parseInt(configValue)
|
||||
}
|
||||
return configValue
|
||||
}
|
||||
|
||||
export function getGitCommit (repodir): string {
|
||||
if (!fs.existsSync(repodir + '/.git/HEAD')) {
|
||||
return ''
|
||||
}
|
||||
let reference = fs.readFileSync(repodir + '/.git/HEAD', 'utf8')
|
||||
if (reference.startsWith('ref: ')) {
|
||||
reference = reference.substr(5).replace('\n', '')
|
||||
reference = fs.readFileSync(path.resolve(repodir + '/.git', reference), 'utf8')
|
||||
}
|
||||
reference = reference.replace('\n', '')
|
||||
return reference
|
||||
}
|
||||
|
||||
export function getGitHubURL (repo, reference): string {
|
||||
// if it's not a github reference, we handle handle that anyway
|
||||
if (!repo.startsWith('https://github.com') && !repo.startsWith('git@github.com')) {
|
||||
return repo
|
||||
}
|
||||
if (repo.startsWith('git@github.com') || repo.startsWith('ssh://git@github.com')) {
|
||||
repo = repo.replace(/^(ssh:\/\/)?git@github.com:/, 'https://github.com/')
|
||||
}
|
||||
|
||||
if (repo.endsWith('.git')) {
|
||||
repo = repo.replace(/\.git$/, '/')
|
||||
} else if (!repo.endsWith('/')) {
|
||||
repo = repo + '/'
|
||||
}
|
||||
return repo + 'tree/' + reference
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue