@weibaohui/dsh-git-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/client/bundle.js +2356 -0
- package/client/index.js +2342 -0
- package/cordis.patch.yml +11 -0
- package/package.json +70 -0
- package/server/dist/api/v1.js +2029 -0
- package/server/dist/authx/password.js +43 -0
- package/server/dist/authx/um.js +157 -0
- package/server/dist/conf.js +323 -0
- package/server/dist/context.js +701 -0
- package/server/dist/db/actions.js +202 -0
- package/server/dist/db/db.js +838 -0
- package/server/dist/dshapi.js +1416 -0
- package/server/dist/editorconfig.js +104 -0
- package/server/dist/gitx/git.js +580 -0
- package/server/dist/gitx/http.js +232 -0
- package/server/dist/gitx/paths.js +28 -0
- package/server/dist/gitx/service.js +251 -0
- package/server/dist/gosprintf.js +167 -0
- package/server/dist/hook.js +53 -0
- package/server/dist/index.js +112 -0
- package/server/dist/lfsx.js +265 -0
- package/server/dist/mailer.js +127 -0
- package/server/dist/markup.js +317 -0
- package/server/dist/metrics.js +18 -0
- package/server/dist/mirror.js +203 -0
- package/server/dist/multipart.js +33 -0
- package/server/dist/repox.js +99 -0
- package/server/dist/router.js +185 -0
- package/server/dist/serv.js +43 -0
- package/server/dist/server.js +382 -0
- package/server/dist/sshx/dispatch.js +160 -0
- package/server/dist/sshx/lfs-transfer.js +289 -0
- package/server/dist/sshx/server.js +107 -0
- package/server/dist/toolx.js +108 -0
- package/server/dist/twofactor.js +160 -0
- package/server/dist/webapi.js +377 -0
- package/server/dist/webhook.js +128 -0
- package/server/package.json +34 -0
- package/server/public/img/avatar_default.png +0 -0
- package/server/tsconfig.json +19 -0
- package/server/vendored-conf/app.ini +538 -0
- package/server/vendored-conf/gitignore/Actionscript +11 -0
- package/server/vendored-conf/gitignore/Ada +5 -0
- package/server/vendored-conf/gitignore/Agda +1 -0
- package/server/vendored-conf/gitignore/Android +32 -0
- package/server/vendored-conf/gitignore/Anjuta +3 -0
- package/server/vendored-conf/gitignore/AppEngine +2 -0
- package/server/vendored-conf/gitignore/AppceleratorTitanium +3 -0
- package/server/vendored-conf/gitignore/ArchLinuxPackages +13 -0
- package/server/vendored-conf/gitignore/Archives +27 -0
- package/server/vendored-conf/gitignore/Autotools +14 -0
- package/server/vendored-conf/gitignore/BricxCC +4 -0
- package/server/vendored-conf/gitignore/C +32 -0
- package/server/vendored-conf/gitignore/C Sharp +108 -0
- package/server/vendored-conf/gitignore/C++ +28 -0
- package/server/vendored-conf/gitignore/CFWheels +12 -0
- package/server/vendored-conf/gitignore/CMake +6 -0
- package/server/vendored-conf/gitignore/CUDA +6 -0
- package/server/vendored-conf/gitignore/CakePHP +13 -0
- package/server/vendored-conf/gitignore/ChefCookbook +9 -0
- package/server/vendored-conf/gitignore/Cloud9 +3 -0
- package/server/vendored-conf/gitignore/CodeIgniter +6 -0
- package/server/vendored-conf/gitignore/CodeKit +3 -0
- package/server/vendored-conf/gitignore/CommonLisp +3 -0
- package/server/vendored-conf/gitignore/Composer +6 -0
- package/server/vendored-conf/gitignore/Concrete5 +3 -0
- package/server/vendored-conf/gitignore/Coq +3 -0
- package/server/vendored-conf/gitignore/CraftCMS +3 -0
- package/server/vendored-conf/gitignore/DM +5 -0
- package/server/vendored-conf/gitignore/Dart +15 -0
- package/server/vendored-conf/gitignore/DartEditor +2 -0
- package/server/vendored-conf/gitignore/Delphi +57 -0
- package/server/vendored-conf/gitignore/Dreamweaver +3 -0
- package/server/vendored-conf/gitignore/Drupal +36 -0
- package/server/vendored-conf/gitignore/EPiServer +4 -0
- package/server/vendored-conf/gitignore/Eagle +36 -0
- package/server/vendored-conf/gitignore/Eclipse +39 -0
- package/server/vendored-conf/gitignore/EiffelStudio +2 -0
- package/server/vendored-conf/gitignore/Elisp +5 -0
- package/server/vendored-conf/gitignore/Elixir +4 -0
- package/server/vendored-conf/gitignore/Emacs +32 -0
- package/server/vendored-conf/gitignore/Ensime +4 -0
- package/server/vendored-conf/gitignore/Erlang +10 -0
- package/server/vendored-conf/gitignore/Espresso +1 -0
- package/server/vendored-conf/gitignore/ExpressionEngine +19 -0
- package/server/vendored-conf/gitignore/ExtJs +4 -0
- package/server/vendored-conf/gitignore/Fancy +2 -0
- package/server/vendored-conf/gitignore/Finale +13 -0
- package/server/vendored-conf/gitignore/FlexBuilder +3 -0
- package/server/vendored-conf/gitignore/ForceDotCom +4 -0
- package/server/vendored-conf/gitignore/FuelPHP +2 -0
- package/server/vendored-conf/gitignore/GWT +28 -0
- package/server/vendored-conf/gitignore/Gcov +5 -0
- package/server/vendored-conf/gitignore/GitBook +16 -0
- package/server/vendored-conf/gitignore/Go +24 -0
- package/server/vendored-conf/gitignore/Gradle +8 -0
- package/server/vendored-conf/gitignore/Grails +33 -0
- package/server/vendored-conf/gitignore/Haskell +16 -0
- package/server/vendored-conf/gitignore/IGORPro +5 -0
- package/server/vendored-conf/gitignore/IPythonNotebook +2 -0
- package/server/vendored-conf/gitignore/Idris +2 -0
- package/server/vendored-conf/gitignore/JDeveloper +13 -0
- package/server/vendored-conf/gitignore/Java +12 -0
- package/server/vendored-conf/gitignore/Jboss +19 -0
- package/server/vendored-conf/gitignore/Jekyll +3 -0
- package/server/vendored-conf/gitignore/JetBrains +46 -0
- package/server/vendored-conf/gitignore/Joomla +525 -0
- package/server/vendored-conf/gitignore/KDevelop4 +2 -0
- package/server/vendored-conf/gitignore/Kate +3 -0
- package/server/vendored-conf/gitignore/KiCAD +13 -0
- package/server/vendored-conf/gitignore/Kohana +2 -0
- package/server/vendored-conf/gitignore/LabVIEW +16 -0
- package/server/vendored-conf/gitignore/Laravel +4 -0
- package/server/vendored-conf/gitignore/Lazarus +30 -0
- package/server/vendored-conf/gitignore/Leiningen +12 -0
- package/server/vendored-conf/gitignore/LemonStand +21 -0
- package/server/vendored-conf/gitignore/LibreOffice +2 -0
- package/server/vendored-conf/gitignore/Lilypond +6 -0
- package/server/vendored-conf/gitignore/Linux +7 -0
- package/server/vendored-conf/gitignore/Lithium +2 -0
- package/server/vendored-conf/gitignore/Lua +41 -0
- package/server/vendored-conf/gitignore/LyX +4 -0
- package/server/vendored-conf/gitignore/Magento +126 -0
- package/server/vendored-conf/gitignore/Matlab +16 -0
- package/server/vendored-conf/gitignore/Maven +9 -0
- package/server/vendored-conf/gitignore/Mercurial +6 -0
- package/server/vendored-conf/gitignore/Mercury +13 -0
- package/server/vendored-conf/gitignore/MetaProgrammingSystem +16 -0
- package/server/vendored-conf/gitignore/MicrosoftOffice +10 -0
- package/server/vendored-conf/gitignore/ModelSim +23 -0
- package/server/vendored-conf/gitignore/Momentics +8 -0
- package/server/vendored-conf/gitignore/MonoDevelop +8 -0
- package/server/vendored-conf/gitignore/Nanoc +10 -0
- package/server/vendored-conf/gitignore/NetBeans +8 -0
- package/server/vendored-conf/gitignore/Nim +1 -0
- package/server/vendored-conf/gitignore/Ninja +2 -0
- package/server/vendored-conf/gitignore/Node +28 -0
- package/server/vendored-conf/gitignore/NotepadPP +2 -0
- package/server/vendored-conf/gitignore/OCaml +20 -0
- package/server/vendored-conf/gitignore/Objective-C +43 -0
- package/server/vendored-conf/gitignore/Opa +13 -0
- package/server/vendored-conf/gitignore/OpenCart +11 -0
- package/server/vendored-conf/gitignore/OracleForms +8 -0
- package/server/vendored-conf/gitignore/Packer +5 -0
- package/server/vendored-conf/gitignore/Perl +20 -0
- package/server/vendored-conf/gitignore/Phalcon +2 -0
- package/server/vendored-conf/gitignore/PhpStorm +63 -0
- package/server/vendored-conf/gitignore/PlayFramework +17 -0
- package/server/vendored-conf/gitignore/Plone +18 -0
- package/server/vendored-conf/gitignore/Prestashop +25 -0
- package/server/vendored-conf/gitignore/Processing +7 -0
- package/server/vendored-conf/gitignore/Python +58 -0
- package/server/vendored-conf/gitignore/Qooxdoo +5 -0
- package/server/vendored-conf/gitignore/Qt +34 -0
- package/server/vendored-conf/gitignore/R +16 -0
- package/server/vendored-conf/gitignore/ROS +47 -0
- package/server/vendored-conf/gitignore/Rails +35 -0
- package/server/vendored-conf/gitignore/Redcar +1 -0
- package/server/vendored-conf/gitignore/Redis +3 -0
- package/server/vendored-conf/gitignore/RhodesRhomobile +9 -0
- package/server/vendored-conf/gitignore/Ruby +36 -0
- package/server/vendored-conf/gitignore/Rust +11 -0
- package/server/vendored-conf/gitignore/SBT +9 -0
- package/server/vendored-conf/gitignore/SCons +2 -0
- package/server/vendored-conf/gitignore/SVN +1 -0
- package/server/vendored-conf/gitignore/Sass +2 -0
- package/server/vendored-conf/gitignore/Scala +17 -0
- package/server/vendored-conf/gitignore/Scrivener +7 -0
- package/server/vendored-conf/gitignore/Sdcc +8 -0
- package/server/vendored-conf/gitignore/SeamGen +26 -0
- package/server/vendored-conf/gitignore/SketchUp +1 -0
- package/server/vendored-conf/gitignore/SlickEdit +11 -0
- package/server/vendored-conf/gitignore/Stella +12 -0
- package/server/vendored-conf/gitignore/SublimeText +14 -0
- package/server/vendored-conf/gitignore/SugarCRM +25 -0
- package/server/vendored-conf/gitignore/Swift +43 -0
- package/server/vendored-conf/gitignore/Symfony +37 -0
- package/server/vendored-conf/gitignore/SymphonyCMS +6 -0
- package/server/vendored-conf/gitignore/SynopsysVCS +36 -0
- package/server/vendored-conf/gitignore/Tags +14 -0
- package/server/vendored-conf/gitignore/TeX +136 -0
- package/server/vendored-conf/gitignore/TextMate +3 -0
- package/server/vendored-conf/gitignore/Textpattern +11 -0
- package/server/vendored-conf/gitignore/TortoiseGit +2 -0
- package/server/vendored-conf/gitignore/TurboGears2 +20 -0
- package/server/vendored-conf/gitignore/Typo3 +20 -0
- package/server/vendored-conf/gitignore/Umbraco +17 -0
- package/server/vendored-conf/gitignore/Unity +21 -0
- package/server/vendored-conf/gitignore/UnrealEngine +76 -0
- package/server/vendored-conf/gitignore/VVVV +6 -0
- package/server/vendored-conf/gitignore/Vagrant +1 -0
- package/server/vendored-conf/gitignore/Vim +6 -0
- package/server/vendored-conf/gitignore/VirtualEnv +10 -0
- package/server/vendored-conf/gitignore/VisualStudio +217 -0
- package/server/vendored-conf/gitignore/VisualStudioCode +2 -0
- package/server/vendored-conf/gitignore/Waf +3 -0
- package/server/vendored-conf/gitignore/WebMethods +14 -0
- package/server/vendored-conf/gitignore/WebStorm +63 -0
- package/server/vendored-conf/gitignore/Windows +18 -0
- package/server/vendored-conf/gitignore/WordPress +18 -0
- package/server/vendored-conf/gitignore/Xcode +23 -0
- package/server/vendored-conf/gitignore/XilinxISE +57 -0
- package/server/vendored-conf/gitignore/Xojo +11 -0
- package/server/vendored-conf/gitignore/Yeoman +6 -0
- package/server/vendored-conf/gitignore/Yii +6 -0
- package/server/vendored-conf/gitignore/ZendFramework +20 -0
- package/server/vendored-conf/gitignore/Zephir +26 -0
- package/server/vendored-conf/gitignore/macOS +25 -0
- package/server/vendored-conf/label/Default +7 -0
- package/server/vendored-conf/license/Abstyles License +10 -0
- package/server/vendored-conf/license/Academic Free License v1.1 +22 -0
- package/server/vendored-conf/license/Academic Free License v1.2 +27 -0
- package/server/vendored-conf/license/Academic Free License v2.0 +43 -0
- package/server/vendored-conf/license/Academic Free License v2.1 +44 -0
- package/server/vendored-conf/license/Academic Free License v3.0 +42 -0
- package/server/vendored-conf/license/Affero General Public License v1.0 +84 -0
- package/server/vendored-conf/license/Apache License 1.0 +19 -0
- package/server/vendored-conf/license/Apache License 1.1 +20 -0
- package/server/vendored-conf/license/Apache License 2.0 +72 -0
- package/server/vendored-conf/license/Artistic License 1.0 +48 -0
- package/server/vendored-conf/license/Artistic License 2.0 +84 -0
- package/server/vendored-conf/license/BSD 2-clause License +8 -0
- package/server/vendored-conf/license/BSD 3-clause License +10 -0
- package/server/vendored-conf/license/BSD 4-clause License +13 -0
- package/server/vendored-conf/license/Creative Commons CC0 1.0 Universal +39 -0
- package/server/vendored-conf/license/Eclipse Public License 1.0 +72 -0
- package/server/vendored-conf/license/Educational Community License v1.0 +22 -0
- package/server/vendored-conf/license/Educational Community License v2.0 +97 -0
- package/server/vendored-conf/license/GNU Affero General Public License v3.0 +241 -0
- package/server/vendored-conf/license/GNU Free Documentation License v1.1 +118 -0
- package/server/vendored-conf/license/GNU Free Documentation License v1.2 +129 -0
- package/server/vendored-conf/license/GNU Free Documentation License v1.3 +148 -0
- package/server/vendored-conf/license/GNU General Public License v1.0 +99 -0
- package/server/vendored-conf/license/GNU General Public License v2.0 +116 -0
- package/server/vendored-conf/license/GNU General Public License v3.0 +231 -0
- package/server/vendored-conf/license/GNU Lesser General Public License v2.1 +174 -0
- package/server/vendored-conf/license/GNU Lesser General Public License v3.0 +70 -0
- package/server/vendored-conf/license/GNU Library General Public License v2.0 +173 -0
- package/server/vendored-conf/license/ISC license +6 -0
- package/server/vendored-conf/license/MIT License +8 -0
- package/server/vendored-conf/license/Mozilla Public License 1.0 +122 -0
- package/server/vendored-conf/license/Mozilla Public License 1.1 +142 -0
- package/server/vendored-conf/license/Mozilla Public License 2.0 +143 -0
- package/server/vendored-conf/readme/Default +3 -0
- package/src/dsh-host.js +168 -0
- package/src/index.js +682 -0
- package/src/runner.js +364 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Password hashing compatible with gogs: PBKDF2-HMAC-SHA256, 10000 iterations,
|
|
2
|
+
// 50-byte key, hex encoded. Salt: 10 random alphanumeric chars.
|
|
3
|
+
import * as crypto from 'node:crypto';
|
|
4
|
+
export function encodePassword(password, salt) {
|
|
5
|
+
return crypto.pbkdf2Sync(password, salt, 10000, 50, 'sha256').toString('hex');
|
|
6
|
+
}
|
|
7
|
+
export function verifyPassword(password, salt, encoded) {
|
|
8
|
+
const candidate = encodePassword(password, salt);
|
|
9
|
+
const a = Buffer.from(candidate, 'hex');
|
|
10
|
+
const b = Buffer.from(encoded, 'hex');
|
|
11
|
+
return a.length === b.length && crypto.timingSafeEqual(a, b);
|
|
12
|
+
}
|
|
13
|
+
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
14
|
+
export function randomSalt() {
|
|
15
|
+
const bytes = crypto.randomBytes(10);
|
|
16
|
+
let out = '';
|
|
17
|
+
for (let i = 0; i < 10; i++)
|
|
18
|
+
out += ALPHABET[bytes[i] % ALPHABET.length];
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
export function md5(input) {
|
|
22
|
+
return crypto.createHash('md5').update(input).digest('hex');
|
|
23
|
+
}
|
|
24
|
+
export function sha1(input) {
|
|
25
|
+
return crypto.createHash('sha1').update(input).digest('hex');
|
|
26
|
+
}
|
|
27
|
+
export function sha256(input) {
|
|
28
|
+
return crypto.createHash('sha256').update(input).digest('hex');
|
|
29
|
+
}
|
|
30
|
+
export function newTokenSHA1() {
|
|
31
|
+
return crypto.randomBytes(20).toString('hex');
|
|
32
|
+
}
|
|
33
|
+
export function basicAuthDecode(encoded) {
|
|
34
|
+
const decoded = Buffer.from(encoded, 'base64').toString('utf8');
|
|
35
|
+
const idx = decoded.indexOf(':');
|
|
36
|
+
if (idx < 0)
|
|
37
|
+
return [decoded, ''];
|
|
38
|
+
return [decoded.slice(0, idx), decoded.slice(idx + 1)];
|
|
39
|
+
}
|
|
40
|
+
export function basicAuthEncode(username, password) {
|
|
41
|
+
return Buffer.from(`${username}:${password}`).toString('base64');
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=password.js.map
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// dsh 服务桥:登录认证直接走 user-management 插件的 service。
|
|
2
|
+
//
|
|
3
|
+
// 注入方式(dsh 插件 service 模式):本模块按 DSH_UM_STORE_PATH 加载
|
|
4
|
+
// user-management 插件的 store 模块(src/store.js,CJS),createStore 后
|
|
5
|
+
// 调用其公开 API(checkLogin / findUserByUsername)——与 UM 网关进程
|
|
6
|
+
// 完全同一代码路径。不再复刻 scrypt 校验,也不把密码同步进本库。
|
|
7
|
+
//
|
|
8
|
+
// 本库 user 表只承载「影子账号」:身份/仓库所有权/令牌归属。passwd 字段
|
|
9
|
+
// 永远是不可用占位(随机盐+随机哈希),任何登录路径都不校验它。
|
|
10
|
+
//
|
|
11
|
+
// 一致性:UM 网关是另一进程,users.json 的外部写入(建号/改密/禁用)
|
|
12
|
+
// 通过 mtime+size 指纹检测——变化即重建 store 实例(load 重读文件),
|
|
13
|
+
// 未变化时复用实例(checkLogin 仅付 scrypt 成本,约几十毫秒)。
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as os from 'node:os';
|
|
16
|
+
import * as path from 'node:path';
|
|
17
|
+
import { createRequire } from 'node:module';
|
|
18
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
19
|
+
import * as dbm from '../db/db.js';
|
|
20
|
+
const requireCjs = createRequire(import.meta.url);
|
|
21
|
+
let storeMod = null; // user-management store 模块(一次性加载)
|
|
22
|
+
let storeInst = null; // 当前 store 实例(users.json 指纹未变时复用)
|
|
23
|
+
let storeStamp = null;
|
|
24
|
+
let storeHome = null;
|
|
25
|
+
export function umStorePath() {
|
|
26
|
+
return process.env.DSH_UM_STORE_PATH || '';
|
|
27
|
+
}
|
|
28
|
+
export function umServiceEnabled() {
|
|
29
|
+
return !!umStorePath();
|
|
30
|
+
}
|
|
31
|
+
/** dsh 数据根(store 的 <home>/user-management)。 */
|
|
32
|
+
function dshHome() {
|
|
33
|
+
return process.env.DSH_UM_HOME ? path.resolve(process.env.DSH_UM_HOME) : path.join(os.homedir(), '.dsh');
|
|
34
|
+
}
|
|
35
|
+
/** 取可用的 store 实例;users.json 指纹变化时重建。 */
|
|
36
|
+
async function getStore() {
|
|
37
|
+
const modPath = umStorePath();
|
|
38
|
+
if (!modPath)
|
|
39
|
+
return null;
|
|
40
|
+
try {
|
|
41
|
+
if (!storeMod)
|
|
42
|
+
storeMod = requireCjs(modPath);
|
|
43
|
+
if (!storeHome)
|
|
44
|
+
storeHome = dshHome();
|
|
45
|
+
const usersFile = path.join(storeHome, 'user-management', 'users.json');
|
|
46
|
+
let stamp = 'missing';
|
|
47
|
+
try {
|
|
48
|
+
const st = fs.statSync(usersFile);
|
|
49
|
+
stamp = `${st.mtimeMs}:${st.size}`;
|
|
50
|
+
}
|
|
51
|
+
catch { }
|
|
52
|
+
if (!storeInst || stamp !== storeStamp) {
|
|
53
|
+
const inst = storeMod.createStore({ home: storeHome });
|
|
54
|
+
await inst.load();
|
|
55
|
+
storeInst = inst;
|
|
56
|
+
storeStamp = stamp;
|
|
57
|
+
}
|
|
58
|
+
return storeInst;
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
storeInst = null;
|
|
62
|
+
storeStamp = null;
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** 服务可用性:'ok'(store 模块可加载)| 'missing'(模块缺失)| 'disabled'。 */
|
|
67
|
+
export function umAvailability() {
|
|
68
|
+
if (!umServiceEnabled())
|
|
69
|
+
return 'disabled';
|
|
70
|
+
try {
|
|
71
|
+
fs.accessSync(umStorePath());
|
|
72
|
+
return 'ok';
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return 'missing';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 登录校验(直接调 UM service 的 checkLogin):
|
|
80
|
+
* result 'ok' → { ok: true, user }(UM publicUser:id/username/role/disabled/totpEnabled…)
|
|
81
|
+
* TOTP 账号明确拒绝(Basic/网页直登无处输入动态码)
|
|
82
|
+
* 'disabled' → reason 'disabled';'invalid' → reason 'bad-password'
|
|
83
|
+
* store 模块/用户库不可用 → unavailable(上层回退本地兜底账号)
|
|
84
|
+
*/
|
|
85
|
+
export async function umCheckLogin(username, password) {
|
|
86
|
+
if (typeof username !== 'string' || !username || typeof password !== 'string' || !password) {
|
|
87
|
+
return { ok: false };
|
|
88
|
+
}
|
|
89
|
+
const store = await getStore();
|
|
90
|
+
if (!store)
|
|
91
|
+
return { ok: false, unavailable: true };
|
|
92
|
+
try {
|
|
93
|
+
const outcome = await store.checkLogin(username, password);
|
|
94
|
+
if (outcome.result === 'ok' && outcome.user) {
|
|
95
|
+
if (outcome.user.totpEnabled)
|
|
96
|
+
return { ok: false, reason: 'totp' };
|
|
97
|
+
return { ok: true, user: outcome.user };
|
|
98
|
+
}
|
|
99
|
+
return { ok: false, reason: outcome.result === 'disabled' ? 'disabled' : 'bad-password' };
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return { ok: false, unavailable: true };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** 按 username 查 UM 用户(publicUser 形态);服务不可用返回 null。 */
|
|
106
|
+
export async function umFindUser(username) {
|
|
107
|
+
const store = await getStore();
|
|
108
|
+
if (!store || typeof store.findUserByUsername !== 'function')
|
|
109
|
+
return null;
|
|
110
|
+
try {
|
|
111
|
+
const u = store.findUserByUsername(username);
|
|
112
|
+
return u ? { id: u.id, username: u.username, role: u.role, disabled: !!u.disabled, totpEnabled: !!u.totpSecret } : null;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 影子开户/对齐:按 UM profile 维护本库同名行(仓库所有权/令牌归属的载体)。
|
|
120
|
+
* 只同步身份与角色(UM admin → 本库管理员);密码永不同步——passwd 为
|
|
121
|
+
* 随机不可用占位,任何登录路径都不校验它(校验永远走 UM service)。
|
|
122
|
+
*/
|
|
123
|
+
export function ensureShadowUser(profile) {
|
|
124
|
+
if (!profile || !profile.username)
|
|
125
|
+
return null;
|
|
126
|
+
if (profile.disabled)
|
|
127
|
+
return null;
|
|
128
|
+
const username = String(profile.username);
|
|
129
|
+
const isAdmin = profile.role === 'admin' ? 1 : 0;
|
|
130
|
+
const now = Math.floor(Date.now() / 1000);
|
|
131
|
+
const bootstrapName = (process.env.DSH_BOOTSTRAP_ADMIN || '').split(':')[0] || 'root';
|
|
132
|
+
let user = dbm.getUserByUsername(username);
|
|
133
|
+
if (!user) {
|
|
134
|
+
const salt = randomBytes(16).toString('hex');
|
|
135
|
+
const unusable = createHash('sha256').update(randomBytes(32).toString('hex') + username).digest('hex');
|
|
136
|
+
dbm.db().prepare('INSERT INTO user (name, lower_name, email, passwd, salt, type, is_admin, created_unix, updated_unix) VALUES (?, ?, ?, ?, ?, 0, ?, ?, ?)').run(username, username.toLowerCase(), `${username.toLowerCase()}@users.dsh.local`, unusable, salt, isAdmin, now, now);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// 既有影子账号:passwd 重置为随机不可用占位(清除历史版本同步过的密码;
|
|
140
|
+
// 兜底管理员除外——它是 service 不可用时的紧急登录通道)
|
|
141
|
+
const patch = [];
|
|
142
|
+
const args = [];
|
|
143
|
+
if ((user.is_admin === 1 ? 1 : 0) !== isAdmin) {
|
|
144
|
+
patch.push('is_admin = ?');
|
|
145
|
+
args.push(isAdmin);
|
|
146
|
+
}
|
|
147
|
+
if (username !== bootstrapName) {
|
|
148
|
+
patch.push('passwd = ?', 'salt = ?');
|
|
149
|
+
args.push(createHash('sha256').update(randomBytes(32).toString('hex') + username).digest('hex'), randomBytes(16).toString('hex'));
|
|
150
|
+
}
|
|
151
|
+
if (patch.length) {
|
|
152
|
+
dbm.db().prepare(`UPDATE user SET ${patch.join(', ')}, updated_unix = ? WHERE id = ?`).run(...args, now, user.id);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return dbm.getUserByUsername(username) ?? null;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=um.js.map
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
// Configuration loading, mirroring gogs internal/conf semantics:
|
|
2
|
+
// vendored defaults (vendored-conf/app.ini) overlaid by custom/conf/app.ini,
|
|
3
|
+
// %(VAR)s interpolation, ExternalURL/Subpath normalization, absolute paths.
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import * as os from 'node:os';
|
|
7
|
+
import * as crypto from 'node:crypto';
|
|
8
|
+
import { parse as parseIni } from 'ini';
|
|
9
|
+
function toBool(v, def) {
|
|
10
|
+
if (v === undefined || v === '')
|
|
11
|
+
return def;
|
|
12
|
+
return v.toLowerCase() === 'true' || v === '1';
|
|
13
|
+
}
|
|
14
|
+
function toInt(v, def) {
|
|
15
|
+
if (v === undefined || v === '')
|
|
16
|
+
return def;
|
|
17
|
+
const n = Number(v);
|
|
18
|
+
return Number.isFinite(n) ? n : def;
|
|
19
|
+
}
|
|
20
|
+
export class Conf {
|
|
21
|
+
/** raw merged ini sections (uppercase keys) */
|
|
22
|
+
raw = {};
|
|
23
|
+
// [server]
|
|
24
|
+
protocol = 'http';
|
|
25
|
+
domain = 'localhost';
|
|
26
|
+
httpAddr = '0.0.0.0';
|
|
27
|
+
httpPort = 3000;
|
|
28
|
+
externalURL = 'http://localhost:3000/';
|
|
29
|
+
url;
|
|
30
|
+
subpath = '';
|
|
31
|
+
subpathDepth = 0;
|
|
32
|
+
localRootURL = '';
|
|
33
|
+
appDataPath = 'data';
|
|
34
|
+
disableRouterLog = true;
|
|
35
|
+
enableGzip = false;
|
|
36
|
+
loadAssetsFromDisk = false;
|
|
37
|
+
landingURL = '/';
|
|
38
|
+
offlineMode = false;
|
|
39
|
+
staticRootPath = '';
|
|
40
|
+
// ssh
|
|
41
|
+
disableSSH = false;
|
|
42
|
+
sshDomain = 'localhost';
|
|
43
|
+
sshPort = 22;
|
|
44
|
+
startSSHServer = false;
|
|
45
|
+
rewriteAuthorizedKeysAtStart = false;
|
|
46
|
+
// [app]
|
|
47
|
+
brandName = 'dsh Git';
|
|
48
|
+
runUser = '';
|
|
49
|
+
runMode = 'prod';
|
|
50
|
+
version = '0.13.0+dev';
|
|
51
|
+
buildCommit = 'unknown';
|
|
52
|
+
buildTime = 'unknown';
|
|
53
|
+
// [database]
|
|
54
|
+
dbType = 'sqlite3';
|
|
55
|
+
dbPath = 'data/gogs.db';
|
|
56
|
+
dbHost = '127.0.0.1:5432';
|
|
57
|
+
dbName = 'gogs';
|
|
58
|
+
dbUser = 'gogs';
|
|
59
|
+
dbPassword = '';
|
|
60
|
+
// [security]
|
|
61
|
+
installLock = false;
|
|
62
|
+
secretKey = '';
|
|
63
|
+
loginRememberDays = 7;
|
|
64
|
+
cookieRememberName = 'gogs_incredible';
|
|
65
|
+
cookieUserName = 'i_like_gogs';
|
|
66
|
+
reverseProxyAuthUserHeader = 'X-Forwarded-User';
|
|
67
|
+
reverseProxyAuthEmailHeader = '';
|
|
68
|
+
enableLoginStatusCookie = false;
|
|
69
|
+
loginStatusCookieName = 'login_status';
|
|
70
|
+
// [auth]
|
|
71
|
+
requireSigninView = false;
|
|
72
|
+
disableRegistration = false;
|
|
73
|
+
enableRegistrationCaptcha = true;
|
|
74
|
+
activateCodeLives = 180;
|
|
75
|
+
resetPwdCodeLives = 180;
|
|
76
|
+
requireEmailConfirmation = false;
|
|
77
|
+
enableNotifyMail = false;
|
|
78
|
+
enableReverseProxyAuthentication = false;
|
|
79
|
+
enableReverseProxyAutoRegistration = false;
|
|
80
|
+
showRegistrationButton = true;
|
|
81
|
+
// [session]
|
|
82
|
+
sessionProvider = 'memory';
|
|
83
|
+
sessionConfig = 'data/sessions';
|
|
84
|
+
sessionCookieSecure = false;
|
|
85
|
+
// [repository]
|
|
86
|
+
repositoryRoot = '';
|
|
87
|
+
scriptType = 'bash';
|
|
88
|
+
forcePrivate = false;
|
|
89
|
+
maxCreationLimit = -1;
|
|
90
|
+
preferredLicenses = [];
|
|
91
|
+
disableHTTPGit = false;
|
|
92
|
+
defaultBranch = 'master';
|
|
93
|
+
uploadEnabled = true;
|
|
94
|
+
uploadTempPath = 'data/tmp/uploads';
|
|
95
|
+
uploadFileMaxSize = 3;
|
|
96
|
+
uploadMaxFiles = 5;
|
|
97
|
+
// [ui]
|
|
98
|
+
explorePagingNum = 20;
|
|
99
|
+
issuePagingNum = 10;
|
|
100
|
+
feedsPagingNum = 20;
|
|
101
|
+
userRepoPagingNum = 15;
|
|
102
|
+
themeColorMetaTag = '#6cc644';
|
|
103
|
+
maxDisplayFileSize = 8388608;
|
|
104
|
+
// [api]
|
|
105
|
+
maxResponseItems = 50;
|
|
106
|
+
defaultGitTreesPerPage = 1000;
|
|
107
|
+
// [picture]
|
|
108
|
+
gravatarSource = 'https://gravatar.com/avatar/';
|
|
109
|
+
disableGravatar = false;
|
|
110
|
+
enableFederatedAvatar = false;
|
|
111
|
+
avatarUploadPath = 'data/avatars';
|
|
112
|
+
repositoryAvatarUploadPath = 'data/repo-avatars';
|
|
113
|
+
// [time]
|
|
114
|
+
timeFormatLayout = '2006-01-02 15:04:05';
|
|
115
|
+
timeFormatJS = 'YYYY-MM-DD HH:mm:ss';
|
|
116
|
+
timeZone = '';
|
|
117
|
+
// [markdown]
|
|
118
|
+
markdownFileExtensions = ['.md', '.markdown', '.mdown', '.mkd'];
|
|
119
|
+
enableHardLineBreak = false;
|
|
120
|
+
customURLSchemes = [];
|
|
121
|
+
// [webhook]
|
|
122
|
+
webhookTypes = ['gogs', 'slack', 'discord', 'dingtalk'];
|
|
123
|
+
deliverTimeout = 5;
|
|
124
|
+
skipVerify = false;
|
|
125
|
+
pagingNum = 10;
|
|
126
|
+
// [mirror]
|
|
127
|
+
defaultMirrorInterval = 8;
|
|
128
|
+
// [git]
|
|
129
|
+
maxDiffFiles = 1000;
|
|
130
|
+
maxDiffLines = 5000;
|
|
131
|
+
maxDiffLineCharacters = 2000;
|
|
132
|
+
gitTimeoutMigrate = 600;
|
|
133
|
+
gitTimeoutMirror = 300;
|
|
134
|
+
gitTimeoutClone = 300;
|
|
135
|
+
gitTimeoutPull = 300;
|
|
136
|
+
gitTimeoutGC = 60;
|
|
137
|
+
// [i18n](已随 /api/web 裁撤,不再加载语言)
|
|
138
|
+
// [prometheus]
|
|
139
|
+
prometheusEnabled = false;
|
|
140
|
+
prometheusEnableBasicAuth = false;
|
|
141
|
+
// [mailer]
|
|
142
|
+
emailEnabled = false;
|
|
143
|
+
emailHost = '';
|
|
144
|
+
emailPort = 587;
|
|
145
|
+
emailFrom = '';
|
|
146
|
+
emailUser = '';
|
|
147
|
+
emailPasswd = '';
|
|
148
|
+
emailSkipVerify = false;
|
|
149
|
+
emailUseTLS = true;
|
|
150
|
+
emailSubjectPrefix = '[Gogs] ';
|
|
151
|
+
// [other]
|
|
152
|
+
showFooterBranding = false;
|
|
153
|
+
showFooterTemplateLoadTime = true;
|
|
154
|
+
/** resolved absolute paths */
|
|
155
|
+
workDir;
|
|
156
|
+
customDir;
|
|
157
|
+
customConf;
|
|
158
|
+
interpolate(value) {
|
|
159
|
+
return String(value ?? '').replace(/%\((\w+)\)s/g, (_m, key) => {
|
|
160
|
+
const section = this.raw['DEFAULT'] ?? {};
|
|
161
|
+
const server = this.raw['server'] ?? {};
|
|
162
|
+
const v = section[key] ?? server[key];
|
|
163
|
+
return typeof v === 'string' ? v : '';
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
sect(name) {
|
|
167
|
+
return this.raw[name] ?? {};
|
|
168
|
+
}
|
|
169
|
+
get(name, key) {
|
|
170
|
+
const v = this.sect(name)[key];
|
|
171
|
+
return v === undefined ? undefined : this.interpolate(v);
|
|
172
|
+
}
|
|
173
|
+
load(workDir, customDir, customConf) {
|
|
174
|
+
this.workDir = workDir;
|
|
175
|
+
this.customDir = customDir;
|
|
176
|
+
this.customConf = customConf ?? path.join(customDir, 'conf', 'app.ini');
|
|
177
|
+
// 1. vendored defaults
|
|
178
|
+
const defaultIni = fs.readFileSync(path.join(workDir, 'vendored-conf', 'app.ini'), 'utf8');
|
|
179
|
+
this.raw = parseIni(defaultIni);
|
|
180
|
+
// 2. custom overrides
|
|
181
|
+
if (fs.existsSync(this.customConf)) {
|
|
182
|
+
const custom = parseIni(fs.readFileSync(this.customConf, 'utf8'));
|
|
183
|
+
for (const [sect, kv] of Object.entries(custom)) {
|
|
184
|
+
if (typeof kv !== 'object' || kv === null) {
|
|
185
|
+
// top-level key → DEFAULT section
|
|
186
|
+
this.raw['DEFAULT'] = this.raw['DEFAULT'] ?? {};
|
|
187
|
+
this.raw['DEFAULT'][sect] = String(kv);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (!this.raw[sect] || typeof this.raw[sect] !== 'object')
|
|
191
|
+
this.raw[sect] = {};
|
|
192
|
+
Object.assign(this.raw[sect], kv);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// 3. programmatic defaults & computed values
|
|
196
|
+
this.brandName = this.get('app', 'BRAND_NAME') ?? 'dsh Git';
|
|
197
|
+
this.runUser = this.raw['DEFAULT']?.RUN_USER ?? this.get('server', 'RUN_USER') ?? process.env.USER ?? '';
|
|
198
|
+
this.runMode = this.get('app', 'RUN_MODE') ?? 'prod';
|
|
199
|
+
this.protocol = (this.get('server', 'PROTOCOL') ?? 'http').toLowerCase();
|
|
200
|
+
this.domain = this.get('server', 'DOMAIN') ?? 'localhost';
|
|
201
|
+
this.httpAddr = this.get('server', 'HTTP_ADDR') ?? '0.0.0.0';
|
|
202
|
+
this.httpPort = toInt(this.get('server', 'HTTP_PORT'), 3000);
|
|
203
|
+
let ext = this.get('server', 'EXTERNAL_URL') ?? '';
|
|
204
|
+
if (!ext)
|
|
205
|
+
ext = `${this.protocol}://${this.domain}:${this.httpPort}/`;
|
|
206
|
+
if (!ext.endsWith('/'))
|
|
207
|
+
ext += '/';
|
|
208
|
+
this.externalURL = ext;
|
|
209
|
+
this.url = new URL(this.externalURL);
|
|
210
|
+
this.subpath = this.url.pathname.replace(/\/+$/, '');
|
|
211
|
+
this.subpathDepth = this.subpath === '' ? 0 : this.subpath.split('/').length - 1;
|
|
212
|
+
this.localRootURL = this.get('server', 'LOCAL_ROOT_URL') ?? `${this.protocol}://${this.httpAddr}:${this.httpPort}/`;
|
|
213
|
+
this.appDataPath = this.ensureAbs(this.get('server', 'APP_DATA_PATH') ?? 'data');
|
|
214
|
+
this.disableRouterLog = toBool(this.get('server', 'DISABLE_ROUTER_LOG'), true);
|
|
215
|
+
this.enableGzip = toBool(this.get('server', 'ENABLE_GZIP'), false);
|
|
216
|
+
this.loadAssetsFromDisk = toBool(this.get('server', 'LOAD_ASSETS_FROM_DISK'), false);
|
|
217
|
+
this.landingURL = this.get('server', 'LANDING_URL') ?? '/';
|
|
218
|
+
this.offlineMode = toBool(this.get('server', 'OFFLINE_MODE'), false);
|
|
219
|
+
this.staticRootPath = path.join(this.workDir, 'public');
|
|
220
|
+
this.disableSSH = toBool(this.get('server', 'DISABLE_SSH'), false);
|
|
221
|
+
this.sshDomain = this.get('server', 'SSH_DOMAIN') ?? this.domain;
|
|
222
|
+
this.sshPort = toInt(this.get('server', 'SSH_PORT'), 22);
|
|
223
|
+
this.startSSHServer = toBool(this.get('server', 'START_SSH_SERVER'), false);
|
|
224
|
+
this.rewriteAuthorizedKeysAtStart = toBool(this.get('server', 'REWRITE_AUTHORIZED_KEYS_AT_START'), false);
|
|
225
|
+
this.dbType = (this.get('database', 'TYPE') ?? 'sqlite3').toLowerCase();
|
|
226
|
+
this.dbPath = this.ensureAbs(this.get('database', 'PATH') ?? 'data/gogs.db');
|
|
227
|
+
this.dbHost = this.get('database', 'HOST') ?? '127.0.0.1:5432';
|
|
228
|
+
this.dbName = this.get('database', 'NAME') ?? 'gogs';
|
|
229
|
+
this.dbUser = this.get('database', 'USER') ?? 'gogs';
|
|
230
|
+
this.dbPassword = this.get('database', 'PASSWORD') ?? '';
|
|
231
|
+
this.installLock = toBool(this.get('security', 'INSTALL_LOCK'), false);
|
|
232
|
+
this.secretKey = this.get('security', 'SECRET_KEY') ?? '';
|
|
233
|
+
this.loginRememberDays = toInt(this.get('security', 'LOGIN_REMEMBER_DAYS'), 7);
|
|
234
|
+
this.cookieRememberName = this.get('security', 'COOKIE_REMEMBER_NAME') ?? 'gogs_incredible';
|
|
235
|
+
this.cookieUserName = this.get('security', 'COOKIE_USERNAME') ?? 'i_like_gogs';
|
|
236
|
+
this.enableLoginStatusCookie = toBool(this.get('security', 'ENABLE_LOGIN_STATUS_COOKIE'), false);
|
|
237
|
+
this.loginStatusCookieName = this.get('security', 'LOGIN_STATUS_COOKIE_NAME') ?? 'login_status';
|
|
238
|
+
this.requireSigninView = toBool(this.get('auth', 'REQUIRE_SIGNIN_VIEW'), false);
|
|
239
|
+
this.disableRegistration = toBool(this.get('auth', 'DISABLE_REGISTRATION'), false);
|
|
240
|
+
this.enableRegistrationCaptcha = toBool(this.get('auth', 'ENABLE_REGISTRATION_CAPTCHA'), true);
|
|
241
|
+
this.requireEmailConfirmation = toBool(this.get('auth', 'REQUIRE_EMAIL_CONFIRMATION'), false);
|
|
242
|
+
this.enableNotifyMail = toBool(this.get('auth', 'ENABLE_NOTIFY_MAIL'), false);
|
|
243
|
+
this.sessionProvider = this.get('session', 'PROVIDER') ?? 'memory';
|
|
244
|
+
this.sessionConfig = this.get('session', 'PROVIDER_CONFIG') ?? 'data/sessions';
|
|
245
|
+
this.sessionCookieSecure = toBool(this.get('session', 'COOKIE_SECURE'), false);
|
|
246
|
+
const root = this.get('repository', 'ROOT') ?? '';
|
|
247
|
+
this.repositoryRoot = this.ensureAbs(root || path.join(os.homedir(), 'gogs-repositories'));
|
|
248
|
+
this.scriptType = this.get('repository', 'SCRIPT_TYPE') ?? 'bash';
|
|
249
|
+
this.forcePrivate = toBool(this.get('repository', 'FORCE_PRIVATE'), false);
|
|
250
|
+
this.maxCreationLimit = toInt(this.get('repository', 'MAX_CREATION_LIMIT'), -1);
|
|
251
|
+
this.preferredLicenses = (this.get('repository', 'PREFERRED_LICENSES') ?? 'Apache License 2.0, MIT License').split(',').map((s) => s.trim());
|
|
252
|
+
this.disableHTTPGit = toBool(this.get('repository', 'DISABLE_HTTP_GIT'), false);
|
|
253
|
+
this.defaultBranch = this.get('repository', 'DEFAULT_BRANCH') ?? 'master';
|
|
254
|
+
this.uploadEnabled = toBool(this.get('repository.upload', 'ENABLED'), true);
|
|
255
|
+
this.uploadTempPath = this.ensureAbs(this.get('repository.upload', 'TEMP_PATH') ?? 'data/tmp/uploads');
|
|
256
|
+
this.uploadFileMaxSize = toInt(this.get('repository.upload', 'FILE_MAX_SIZE'), 3);
|
|
257
|
+
this.uploadMaxFiles = toInt(this.get('repository.upload', 'MAX_FILES'), 5);
|
|
258
|
+
this.explorePagingNum = toInt(this.get('ui', 'EXPLORE_PAGING_NUM'), 20);
|
|
259
|
+
this.issuePagingNum = toInt(this.get('ui', 'ISSUE_PAGING_NUM'), 10);
|
|
260
|
+
this.feedsPagingNum = toInt(this.get('ui', 'FEEDS_PAGING_NUM'), 20);
|
|
261
|
+
this.userRepoPagingNum = toInt(this.get('ui.user', 'REPO_PAGING_NUM'), 15);
|
|
262
|
+
this.themeColorMetaTag = this.get('ui', 'THEME_COLOR_META_TAG') ?? '#6cc644';
|
|
263
|
+
this.maxDisplayFileSize = toInt(this.get('ui', 'MAX_DISPLAY_FILE_SIZE'), 8388608);
|
|
264
|
+
this.maxResponseItems = toInt(this.get('api', 'MAX_RESPONSE_ITEMS'), 50);
|
|
265
|
+
this.defaultGitTreesPerPage = toInt(this.get('api', 'DEFAULT_GIT_TREES_PER_PAGE'), 1000);
|
|
266
|
+
this.gravatarSource = this.get('picture', 'GRAVATAR_SOURCE') ?? 'https://gravatar.com/avatar/';
|
|
267
|
+
this.disableGravatar = toBool(this.get('picture', 'DISABLE_GRAVATAR'), false);
|
|
268
|
+
this.enableFederatedAvatar = toBool(this.get('picture', 'ENABLE_FEDERATED_AVATAR'), false);
|
|
269
|
+
this.avatarUploadPath = this.ensureAbs(this.get('picture', 'AVATAR_UPLOAD_PATH') ?? 'data/avatars');
|
|
270
|
+
this.repositoryAvatarUploadPath = this.ensureAbs(this.get('picture', 'REPOSITORY_AVATAR_UPLOAD_PATH') ?? 'data/repo-avatars');
|
|
271
|
+
this.timeFormatLayout = this.get('time', 'FORMAT') ?? '2006-01-02 15:04:05';
|
|
272
|
+
this.timeFormatJS = this.get('time', 'FORMAT_JS') ?? 'YYYY-MM-DD HH:mm:ss';
|
|
273
|
+
const exts = this.get('markdown', 'FILE_EXTENSIONS');
|
|
274
|
+
if (exts) {
|
|
275
|
+
this.markdownFileExtensions = exts.split(',').map((s) => s.trim());
|
|
276
|
+
}
|
|
277
|
+
this.enableHardLineBreak = toBool(this.get('markdown', 'ENABLE_HARD_LINE_BREAK'), false);
|
|
278
|
+
const schemes = this.get('markdown', 'CUSTOM_URL_SCHEMES');
|
|
279
|
+
this.customURLSchemes = schemes ? schemes.split(',').map((s) => s.trim()) : [];
|
|
280
|
+
this.deliverTimeout = toInt(this.get('webhook', 'DELIVER_TIMEOUT'), 5);
|
|
281
|
+
this.skipVerify = toBool(this.get('webhook', 'SKIP_VERIFY'), false);
|
|
282
|
+
this.pagingNum = toInt(this.get('webhook', 'PAGING_NUM'), 10);
|
|
283
|
+
this.defaultMirrorInterval = toInt(this.get('mirror', 'DEFAULT_INTERVAL'), 8);
|
|
284
|
+
this.maxDiffFiles = toInt(this.get('git', 'MAX_GIT_DIFF_FILES'), 1000);
|
|
285
|
+
this.maxDiffLines = toInt(this.get('git', 'MAX_GIT_DIFF_LINES'), 5000);
|
|
286
|
+
this.maxDiffLineCharacters = toInt(this.get('git', 'MAX_GIT_DIFF_LINE_CHARACTERS'), 2000);
|
|
287
|
+
this.gitTimeoutMigrate = toInt(this.get('git.timeout', 'MIGRATE'), 600);
|
|
288
|
+
this.gitTimeoutMirror = toInt(this.get('git.timeout', 'MIRROR'), 300);
|
|
289
|
+
this.gitTimeoutClone = toInt(this.get('git.timeout', 'CLONE'), 300);
|
|
290
|
+
this.gitTimeoutPull = toInt(this.get('git.timeout', 'PULL'), 300);
|
|
291
|
+
this.gitTimeoutGC = toInt(this.get('git.timeout', 'GC'), 60);
|
|
292
|
+
this.prometheusEnabled = toBool(this.get('prometheus', 'ENABLED'), false);
|
|
293
|
+
this.prometheusEnableBasicAuth = toBool(this.get('prometheus', 'ENABLE_BASIC_AUTH'), false);
|
|
294
|
+
this.emailEnabled = toBool(this.get('mailer', 'ENABLED'), false);
|
|
295
|
+
this.emailHost = this.get('mailer', 'HOST') ?? '';
|
|
296
|
+
this.emailPort = toInt(this.get('mailer', 'PORT'), 587);
|
|
297
|
+
this.emailFrom = this.get('mailer', 'FROM') ?? '';
|
|
298
|
+
this.emailUser = this.get('mailer', 'USER') ?? '';
|
|
299
|
+
this.emailPasswd = this.get('mailer', 'PASSWD') ?? '';
|
|
300
|
+
this.emailSkipVerify = toBool(this.get('mailer', 'SKIP_VERIFY'), false);
|
|
301
|
+
this.emailUseTLS = toBool(this.get('mailer', 'USE_TLS'), true);
|
|
302
|
+
this.emailSubjectPrefix = this.get('mailer', 'SUBJECT_PREFIX') ?? '[Gogs] ';
|
|
303
|
+
this.showFooterBranding = toBool(this.get('other', 'SHOW_FOOTER_BRANDING'), false);
|
|
304
|
+
this.showFooterTemplateLoadTime = toBool(this.get('other', 'SHOW_FOOTER_TEMPLATE_LOAD_TIME'), true);
|
|
305
|
+
// generate a secret key for a fresh install if not present
|
|
306
|
+
if (!this.secretKey) {
|
|
307
|
+
this.secretKey = crypto.randomBytes(15).toString('hex');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
isProdMode() {
|
|
311
|
+
return this.runMode === 'prod';
|
|
312
|
+
}
|
|
313
|
+
ensureAbs(p) {
|
|
314
|
+
if (path.isAbsolute(p))
|
|
315
|
+
return p;
|
|
316
|
+
return path.join(this.workDir, p);
|
|
317
|
+
}
|
|
318
|
+
homeDir() {
|
|
319
|
+
return os.homedir();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
export const conf = new Conf();
|
|
323
|
+
//# sourceMappingURL=conf.js.map
|