Sync 2026-07-04 23:49:55

This commit is contained in:
github-actions[bot] 2026-07-04 23:49:55 +08:00
parent 17af4a44da
commit 1bca68cd89
10 changed files with 101 additions and 35 deletions

View File

@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-daede
PKG_VERSION:=1.14.7
PKG_RELEASE:=26
PKG_RELEASE:=27
PKG_MAINTAINER:=kenzok8
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

View File

@ -105,19 +105,29 @@ function graphQL(endpoint, query, variables, token) {
});
}
function requestDaedCredentials() {
function requestDaedCredentials(mode) {
const init = (mode === 'init');
return new Promise(function(resolve, reject) {
const username = E('input', { 'class': 'cbi-input-text', 'autocomplete': 'username', 'placeholder': _('Username') });
const password = E('input', { 'class': 'cbi-input-password', 'type': 'password', 'autocomplete': 'current-password', 'placeholder': _('Password') });
const password = E('input', { 'class': 'cbi-input-password', 'type': 'password', 'autocomplete': init ? 'new-password' : 'current-password', 'placeholder': _('Password') });
if (init) {
// prefill from the config-page account so the daed admin created here
// matches what cron subscription updates use.
username.value = uci.get('daed', 'config', 'dashboard_username') || '';
password.value = uci.get('daed', 'config', 'dashboard_password') || '';
}
const cancel = E('button', { 'class': 'btn cbi-button' }, _('Cancel'));
const login = E('button', { 'class': 'btn cbi-button cbi-button-positive' }, _('Sign in and import'));
const submit = E('button', { 'class': 'btn cbi-button cbi-button-positive' },
init ? _('Initialize and import') : _('Sign in and import'));
cancel.addEventListener('click', function() {
password.value = '';
ui.hideModal();
reject(new Error(_('Import cancelled')));
reject(new Error(init
? _('daed is not initialized yet. Open the daed web panel (port 2023) to create an admin account, then import again.')
: _('Import cancelled')));
});
login.addEventListener('click', function() {
submit.addEventListener('click', function() {
if (!username.value || !password.value)
return;
const result = { username: username.value, password: password.value };
@ -126,11 +136,15 @@ function requestDaedCredentials() {
resolve(result);
});
ui.showModal(_('Sign in to daed'), [ E('div', { 'class': 'dd-daed-login' }, [
E('p', {}, _('The password is not saved. Sign-in is remembered in this browser for up to 30 days.')),
const intro = init
? _('daed has not been initialized yet. The account below will be created as the daed admin (password needs at least 6 characters with both letters and numbers), then used to import.')
: _('The password is not saved. Sign-in is remembered in this browser for up to 30 days.');
ui.showModal(init ? _('Initialize daed') : _('Sign in to daed'), [ E('div', { 'class': 'dd-daed-login' }, [
E('p', {}, intro),
E('div', { 'class': 'cbi-value' }, [ E('label', { 'class': 'cbi-value-title' }, _('Username')), E('div', { 'class': 'cbi-value-field' }, username) ]),
E('div', { 'class': 'cbi-value' }, [ E('label', { 'class': 'cbi-value-title' }, _('Password')), E('div', { 'class': 'cbi-value-field' }, password) ]),
E('div', { 'class': 'right dd-daed-login-actions' }, [ cancel, ' ', login ])
E('div', { 'class': 'right dd-daed-login-actions' }, [ cancel, ' ', submit ])
]) ]);
username.focus();
});
@ -141,19 +155,28 @@ function requestDaedToken(endpoint, forceLogin) {
if (cached)
return Promise.resolve({ token: cached, cached: true });
let credentials;
return requestDaedCredentials().then(function(value) {
credentials = value;
return graphQL(endpoint,
'query Login($username:String!,$password:String!){token(username:$username,password:$password)}',
credentials);
}).then(function(login) {
daedSession.save(window.localStorage, login.token);
return { token: login.token, cached: false };
}).finally(function() {
if (credentials)
credentials.password = '';
credentials = null;
// numberUsers is unauthenticated; 0 means the daed panel was never
// initialized, so log-in can never succeed — bootstrap it with createUser.
return graphQL(endpoint, 'query Init{numberUsers}', {}).then(function(state) {
const needInit = !state || state.numberUsers === 0;
let credentials;
return requestDaedCredentials(needInit ? 'init' : 'login').then(function(value) {
credentials = value;
if (needInit)
return graphQL(endpoint,
'mutation Init($username:String!,$password:String!){createUser(username:$username,password:$password)}',
credentials).then(function(r) { return r.createUser; });
return graphQL(endpoint,
'query Login($username:String!,$password:String!){token(username:$username,password:$password)}',
credentials).then(function(r) { return r.token; });
}).then(function(token) {
daedSession.save(window.localStorage, token);
return { token: token, cached: false };
}).finally(function() {
if (credentials)
credentials.password = '';
credentials = null;
});
});
}

View File

@ -21,7 +21,7 @@ function renderDaedSettings() {
o.rmempty = false;
o = s.option(form.Value, 'dashboard_username', _('daed Username'),
_('Used by LuCI to update daed subscriptions through GraphQL. It does not change the daed Web login account.'));
_('Used by LuCI to access daed (subscription updates and import). If daed is not initialized yet, this account is used to create the daed admin.'));
o.placeholder = 'admin';
o.rmempty = false;

View File

@ -31,6 +31,7 @@ function currentPreset(gi, gs) {
const HEALTH_PATHS = {
btf: '/sys/kernel/btf/vmlinux',
btfDetached: '/usr/lib/debug/boot/vmlinux',
netns: '/run/netns/daens'
};
@ -270,6 +271,7 @@ return view.extend({
probeFile(DATA_PATHS.geoip),
probeFile(DATA_PATHS.geosite),
probeFile(HEALTH_PATHS.btf),
probeFile(HEALTH_PATHS.btfDetached),
backend.detectRunning(),
backend.serviceStatus(ctx.name)
];
@ -283,8 +285,8 @@ return view.extend({
probes.push(probeFile(HEALTH_PATHS.netns));
return Promise.all(probes).then(function(r) {
const geoip = r[0], geosite = r[1], btf = r[2], running = r[3], service = r[4];
const pkgOffset = 5;
const geoip = r[0], geosite = r[1], btf = r[2], btfDetached = r[3], running = r[4], service = r[5];
const pkgOffset = 6;
const coreInfo = {};
corePkgs.forEach(function(pkg, i) {
coreInfo[pkg] = r[pkgOffset + i];
@ -364,6 +366,8 @@ return view.extend({
if (btf.exists)
healthBody.appendChild(mkRow('✓', 'dd-up-ok', _('Kernel BTF'), HEALTH_PATHS.btf + ' · ' + fmtBytes(btf.size)));
else if (btfDetached.exists)
healthBody.appendChild(mkRow('✓', 'dd-up-ok', _('Kernel BTF'), HEALTH_PATHS.btfDetached + ' · ' + fmtBytes(btfDetached.size)));
else
healthBody.appendChild(mkRow('✗', 'dd-up-err', _('Kernel BTF'), _('not available — eBPF needs CONFIG_DEBUG_INFO_BTF or vmlinux-btf')));

View File

@ -109,7 +109,7 @@ msgstr ""
msgid "daed Username"
msgstr ""
msgid "Used by LuCI to update daed subscriptions through GraphQL. It does not change the daed Web login account."
msgid "Used by LuCI to access daed (subscription updates and import). If daed is not initialized yet, this account is used to create the daed admin."
msgstr ""
msgid "daed Password"
@ -562,6 +562,22 @@ msgstr ""
msgid "The password is not saved. Sign-in is remembered in this browser for up to 30 days."
msgstr ""
#: converter.js
msgid "Initialize daed"
msgstr ""
#: converter.js
msgid "Initialize and import"
msgstr ""
#: converter.js
msgid "daed has not been initialized yet. The account below will be created as the daed admin (password needs at least 6 characters with both letters and numbers), then used to import."
msgstr ""
#: converter.js
msgid "daed is not initialized yet. Open the daed web panel (port 2023) to create an admin account, then import again."
msgstr ""
msgid "3. Import Subscription"
msgstr ""

View File

@ -123,8 +123,8 @@ msgstr "日志设置"
msgid "daed Username"
msgstr "daed 用户名"
msgid "Used by LuCI to update daed subscriptions through GraphQL. It does not change the daed Web login account."
msgstr "LuCI 通过 GraphQL 更新 daed 订阅时使用;不会修改 daed Web 的登录账号。"
msgid "Used by LuCI to access daed (subscription updates and import). If daed is not initialized yet, this account is used to create the daed admin."
msgstr "供 LuCI 访问 daed 使用(订阅更新与导入)。若 daed 尚未初始化,将用此账号创建 daed 管理员。"
msgid "daed Password"
msgstr "daed 密码"
@ -782,6 +782,18 @@ msgstr "登录 daed"
msgid "The password is not saved. Sign-in is remembered in this browser for up to 30 days."
msgstr "不会保存密码。此浏览器将在 30 天内记住登录状态。"
msgid "Initialize daed"
msgstr "初始化 daed"
msgid "Initialize and import"
msgstr "初始化并导入"
msgid "daed has not been initialized yet. The account below will be created as the daed admin (password needs at least 6 characters with both letters and numbers), then used to import."
msgstr "daed 尚未初始化。下方账号将被创建为 daed 管理员(密码至少 6 位,且需同时包含字母和数字),随后用于导入。"
msgid "daed is not initialized yet. Open the daed web panel (port 2023) to create an admin account, then import again."
msgstr "daed 尚未初始化。请先打开 daed 网页面板2023 端口)创建管理员账号,再重新导入。"
msgid "3. Import Subscription"
msgstr "3. 导入订阅"

View File

@ -123,8 +123,8 @@ msgstr "日志设置"
msgid "daed Username"
msgstr "daed 用户名"
msgid "Used by LuCI to update daed subscriptions through GraphQL. It does not change the daed Web login account."
msgstr "LuCI 通过 GraphQL 更新 daed 订阅时使用;不会修改 daed Web 的登录账号。"
msgid "Used by LuCI to access daed (subscription updates and import). If daed is not initialized yet, this account is used to create the daed admin."
msgstr "供 LuCI 访问 daed 使用(订阅更新与导入)。若 daed 尚未初始化,将用此账号创建 daed 管理员。"
msgid "daed Password"
msgstr "daed 密码"
@ -782,6 +782,18 @@ msgstr "登录 daed"
msgid "The password is not saved. Sign-in is remembered in this browser for up to 30 days."
msgstr "不会保存密码。此浏览器将在 30 天内记住登录状态。"
msgid "Initialize daed"
msgstr "初始化 daed"
msgid "Initialize and import"
msgstr "初始化并导入"
msgid "daed has not been initialized yet. The account below will be created as the daed admin (password needs at least 6 characters with both letters and numbers), then used to import."
msgstr "daed 尚未初始化。下方账号将被创建为 daed 管理员(密码至少 6 位,且需同时包含字母和数字),随后用于导入。"
msgid "daed is not initialized yet. Open the daed web panel (port 2023) to create an admin account, then import again."
msgstr "daed 尚未初始化。请先打开 daed 网页面板2023 端口)创建管理员账号,再重新导入。"
msgid "3. Import Subscription"
msgstr "3. 导入订阅"

View File

@ -13,6 +13,7 @@
"/usr/share/v2ray/geoip.dat": [ "read" ],
"/usr/share/v2ray/geosite.dat": [ "read" ],
"/sys/kernel/btf/vmlinux": [ "read" ],
"/usr/lib/debug/boot/vmlinux": [ "read" ],
"/run/netns/daens": [ "read" ],
"/tmp/luci-app-daede.geoip.log": [ "read" ],
"/tmp/luci-app-daede.geosite.log": [ "read" ],

View File

@ -4,7 +4,7 @@ LUCI_TITLE:=luci-app-ssr-plus
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=196
PKG_RELEASE:=39
PKG_RELEASE:=40
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \

View File

@ -111,10 +111,8 @@ local function generate_apple(type)
end
end
end
if new_appledns and new_appledns ~= "" then
for _, domain in ipairs(domains) do
out:write(string.format("server=/%s/%s\n", domain, new_appledns))
end
for _, domain in ipairs(domains) do
out:write(string.format("server=/%s/%s\n", domain, new_appledns))
end
out:close()
os.remove("/tmp/ssr-update.tmp")