main
45
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a690ecd3f4 |
fix(auth,ui): reduce SQLite busy 503; TCP/UDP dual connection chart
Auth user lookup retries briefly on DB lock; SQLite opens with busy_timeout and a single connection. Dashboard tracks TCP/UDP series and draws them as solid/dashed lines like traffic rates. |
||
|
|
fec9733baa |
docs: remove third-party panel name references from copy
Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. docs: remove third-party panel name references from copy Drop and external m-ui product names from docs, UI strings, and code comments. Keep functional descriptions of server egress and WARP. |
||
|
|
c79e0b7a17 |
feat(auth): optional GitHub OAuth for panel login
Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. feat(auth): optional GitHub OAuth for panel login Store client id/secret and allowed GitHub usernames in settings. OAuth start/callback issues the same session JWT as password login; first allowed login can bind to matching or sole admin account. Login page shows Continue with GitHub when enabled. |
||
|
|
7e8094938c | fix(ci): remove unused log import in database.go | ||
|
|
fee8f6535d | fix(ci): gofmt database.go and user/api.go | ||
|
|
64609d43d1 | chore: delete HWID package and model | ||
|
|
79e6c778a1 | chore: remove HWID feature (subscription device binding) | ||
|
|
37a5fa0284 |
feat(traffic): per-node usage + traffic multiplier billing
- Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) feat(traffic): per-node usage + traffic multiplier billing - Listener.traffic_multiplier (default 1): billable = raw × multiplier - user_node_traffics: raw per user per node; user quota uses billable totals - Collector attributes deltas by inbound name; resets clear node rows - API GET /users/:id/node-traffic - UI: node multiplier on Listeners; Users node-traffic modal (desktop+mobile) |
||
|
|
277e65c09a |
fix(db): drop legacy HWID index before AutoMigrate
SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. fix(db): drop legacy HWID index before AutoMigrate SQLite index names are global; uidx_user_hwid left by hw_id_devices blocked creating hwid_devices and rolled back panel updates. prepareHWIDDeviceSchema now runs before AutoMigrate and drops the conflicting index plus legacy/broken HWID tables. |
||
|
|
00cc0b9f4b |
fix(db): HWID table column hwid (GORM acronym mapping)
GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. fix(db): HWID table column hwid (GORM acronym mapping) GORM snake_case mapped HWID -> h_w_i_d and table -> hw_id_devices, so SELECT ... hwid failed with "no such column: hwid". Explicit column tags, table name hwid_devices, and startup repair that drops broken tables. |
||
|
|
9cf0df62d3 |
feat: 5s IP-limit poll; per-user subscription pull limit (24h)
- traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached feat: 5s IP-limit poll; per-user subscription pull limit (24h) - traffic.DefaultInterval 10s → 5s for faster concurrent IP enforcement - sub_pull_limit: max successful sub fetches per rolling 24h (0=unlimited) - Users form + i18n; 429 when limit reached |
||
|
|
23faed3ad9 |
fix(hwid): enforce limit properly; accept real client device ids
- When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors fix(hwid): enforce limit properly; accept real client device ids - When hwid_limit>0, require valid x-hwid (deny bare clients with 403) - Relax pattern (UUID/base64/8-128 chars); expand column to 128 - Query ?hwid= fallback; unique-race refresh; surface enforce errors |
||
|
|
2c4ed3cb4a |
style: gofmt all backend Go files (CI gofmt check was failing)
style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) style: gofmt all backend Go files (CI gofmt check was failing) |
||
|
|
4778c43c79 |
feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path
- Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections feat: online ops parity — HWID devices UI, first-use expiry, external subs, TOTP, web_path - Users: start_on_first_use + expire_days_after_first; TouchFirstUse on sub/traffic - External subscription URLs merged into Clash/Mihomo client YAML - HWID device list/kick/clear wired in Users (API already present) - Admin TOTP 2FA (setup/enable/disable + login second step) - Optional server.web_path panel prefix (config.yaml) - subscription-userinfo already present; Traffic page shows live connections |
||
|
|
3a5b0d7e66 |
feat: sub path/port, user groups/tags/cycle renew, export links, WARP register
- server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles feat: sub path/port, user groups/tags/cycle renew, export links, WARP register - server.sub_path / sub_port / env overrides; custom /sub/:token + optional second listener - subscription URLs use configured path; legacy API path kept - proxy users: group, tags, traffic_reset_days, expire_renew_days + background cycle job - GET /users/export-links for one-click subscription link export - POST /system/templates/warp/register (Cloudflare WARP one-click) + Settings UI - Share page export-all; Users form fields for group/tags/cycles |
||
|
|
2c625c8790 |
fix(db): silence GORM record-not-found noise for optional settings
Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. fix(db): silence GORM record-not-found noise for optional settings Telegram and traffic_reset_day lookups are expected to miss until configured; default Info logger flooded journal every scheduler tick and looked like errors. |
||
|
|
2e6256fb6a |
feat(distribution): add complete installation and recovery workflows
Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. feat(distribution): add complete installation and recovery workflows Ship stable-only Linux bundles and multiarch Docker images with a pinned Mihomo core. Share secure first-run initialization across native and container installs. Validate downloads before downtime, snapshot persistent state before updates, and restore the previous installation after a failed upgrade. Add backup, restore, healthcheck, and randomized administrator reset commands. Add release verification, lifecycle regression tests, and installation documentation. |
||
|
|
0e5af8a096 |
feat(listeners)!: select REALITY targets with server-side checks
BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. feat(listeners)!: select REALITY targets with server-side checks BREAKING CHANGE: REALITY create and update requests require an explicit reality-config.dest; implicit Microsoft and SNI-derived destinations are no longer supplied. |
||
|
|
7ce3796d9b |
feat(hwid): Happ/Remnawave-compatible subscription HWID device limit
- Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field feat(hwid): Happ/Remnawave-compatible subscription HWID device limit - Track x-hwid / x-device-os / x-ver-os / x-device-model on sub fetch - Per-user hwid_limit; response headers x-hwid-active|not-supported|max-devices-reached - Admin API list/delete/clear devices; user form field |
||
|
|
812373aa27 |
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
fix(audit): cluster JWT storage size, Telegram chat_ids/events robustness
- Store remote panel JWT as text (HS256 tokens can exceed 256 chars)
- Accept chat_ids as JSON array or comma-separated string
- Default enabled_events when empty; EventEnabled falls back to login,cpu,crash
- Gate CPU Telegram alerts by EventEnabled("cpu")
|
||
|
|
bcb1d50393 |
feat(cluster): sync remote node mirrors and merge into local user subscription
- Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog feat(cluster): sync remote node mirrors and merge into local user subscription - Cache remote nodes + URI/client_yaml via POST /cluster/:id/sync-nodes - Bind local users to mirrors; Clash YAML and v2ray base64 subs merge remote entries - UI: Sync nodes on cluster page; remote multi-select in user bind dialog |
||
|
|
dc13e69951 |
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean |
||
|
|
69df7e5165 | fix(db): Unscoped dedupe so unique indexes cannot block panel boot | ||
|
|
9d95c97e7e | fix(security): InitDB dedupe + cluster private URL hardening | ||
|
|
e0e301cfc4 | fix(security): unique listener/sub_token indexes; harden cluster SSRF | ||
|
|
8d116f9c61 | feat: multi-node remote panel registry, health-all, restricted remote control | ||
|
|
885a68e57f | chore: remove internal parity wording from comments and UI | ||
|
|
6b3a09a09c |
update
update update update update update update update update update update update |
||
|
|
ef236c6a6f | feat: per-node Access Profile fields on Listener model | ||
|
|
5fa916d982 |
security: restrict SQLite database filesystem permissions
security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions security: restrict SQLite database filesystem permissions |
||
|
|
0e297a9786 | fix(audit): SubToken index (avoid empty unique clash) + token uniqueness retry + tests | ||
|
|
768a428154 | feat: user SubToken model + monthly traffic reset + panel-settings API | ||
|
|
62a8f83b24 | feat(users): ip_limit + remark ( limitIP parity) | ||
|
|
d9fcbae4e2 | fix(ci): BaseModel test literals for go test/vet | ||
|
|
211e2b600f | fix: migrate remaining models to BaseModel (lowercase id JSON) | ||
|
|
48da56065d | fix: BaseModel with json id to fix Listener delete invalid node id | ||
|
|
80c6ef4996 | feat: migrate listener templates and versions | ||
|
|
229a588352 | feat: add listener templates | ||
|
|
222d6614cf | feat: add listener version history | ||
|
|
7c17d3d99f | feat(telegram): link proxy users to Telegram accounts | ||
|
|
be035f26e2 | test: prevent listener ID JSON regression | ||
|
|
96167d27ea | fix: expose listener ID as id in JSON API | ||
|
|
d238ba470e | feat: migrate PanelSetting/RemoteServer; ACME/nginx templates | ||
|
|
2409060e14 | feat(telegram): client, settings store, block notifier | ||
|
|
5b4cb63a73 |
fix: align listener generation with mihomo official spec
- Port now supports mihomo ports format (single/range/list) - Add explicit RoutingMark field support - Auto-propagate UDP flag for vmess/vless/trojan/anytls/trusttunnel - Update validator to accept port ranges - Sync visual config and client converter port types - Rename module from dzx941 to kazeyukiro - Fix missing ExpiresAt in JWTClaims - Fix nodeDTO Port type to string - Fix frontend tsconfig and add missing dependencies |