diff --git a/luci-app-adguardhome/htdocs/luci-static/resources/view/adguardhome/config.js b/luci-app-adguardhome/htdocs/luci-static/resources/view/adguardhome/config.js
index 7b94d579b..5e5d3695d 100644
--- a/luci-app-adguardhome/htdocs/luci-static/resources/view/adguardhome/config.js
+++ b/luci-app-adguardhome/htdocs/luci-static/resources/view/adguardhome/config.js
@@ -4,6 +4,39 @@
'require view';
'require poll';
+const DEFAULT_CONFIG_FILE = '/etc/adguardhome/adguardhome.yaml';
+const DEFAULT_WORK_DIR = '/var/lib/adguardhome';
+const DEFAULT_USER = 'adguardhome';
+const DEFAULT_GROUP = DEFAULT_USER;
+
+const PATH_REGEX = new RegExp('^/etc(/[^/]+)?/?$');
+
+function validateConfigFile(_unused, value) {
+ if (value == null || value === '') {
+ return true;
+ }
+ if (!value.startsWith('/')) {
+ return _('Path must be absolute.');
+ }
+ if (value.endsWith('/')) {
+ return _('Path must not end with a slash.');
+ }
+ if (PATH_REGEX.test(value)) {
+ return _('Configuration file must be stored in its own directory, and not in \'/etc\'.');
+ }
+ return true;
+}
+
+function validateWorkDir(_unused, value) {
+ if (value == null || value === '') {
+ return true;
+ }
+ if (!value.startsWith('/')) {
+ return _('Path must be absolute.');
+ }
+ return true;
+}
+
function renderStatus(status, agh_config) {
var spanTemp = '%s %s';
var renderHTML;
@@ -65,9 +98,23 @@ return view.extend({
o.default = o.disabled;
o.rmempty = false;
- o = s.option(form.Value, 'workdir', _('Work Dir'));
+ o = s.option(form.Value, 'config_file', _('Configuration file'));
o.datatype = 'string';
- o.default = '/var/lib/adguardhome';
+ o.placeholder = DEFAULT_CONFIG_FILE;
+ o.validate = validateConfigFile;
+
+ o = s.option(form.Value, 'work_dir', _('Work Dir'));
+ o.datatype = 'string';
+ o.placeholder = DEFAULT_WORK_DIR;
+ o.validate = validateWorkDir;
+
+ o = s.option(form.Value, 'user', _('Service user'), _('User the service runs under.'));
+ o.datatype = 'string';
+ o.placeholder = DEFAULT_USER;
+
+ o = s.option(form.Value, 'group', _('Service group'), _('Group the service runs under.'));
+ o.datatype = 'string';
+ o.placeholder = DEFAULT_GROUP;
// 添加重定向模式选择
o = s.option(form.ListValue, 'redirect', _('Redirect'), _('AdGuardHome redirect mode'));
diff --git a/luci-app-adguardhome/po/zh_Hans/adguardhome.po b/luci-app-adguardhome/po/zh_Hans/adguardhome.po
index 3481472b5..deaa0907b 100644
--- a/luci-app-adguardhome/po/zh_Hans/adguardhome.po
+++ b/luci-app-adguardhome/po/zh_Hans/adguardhome.po
@@ -163,8 +163,17 @@ msgstr "使用53端口替换dnsmasq"
msgid "AdGuardHome redirect mode"
msgstr "重定向模式"
+msgid "Change Password"
+msgstr "修改密码"
+
msgid "Work Dir"
msgstr "工作目录"
-msgid "Change Password"
-msgstr "修改密码"
+msgid "Service user"
+msgstr "以此用户权限运行"
+
+msgid "Service group"
+msgstr "以此用户组权限运行"
+
+msgid "Configuration file"
+msgstr "配置文件"
diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm b/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm
index edbbec228..e59a21c05 100644
--- a/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm
+++ b/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm
@@ -5,6 +5,10 @@ local api = require "luci.passwall.api"