mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-20 06:02:17 +03:00
Instead of requiring a manual SOCKS5/HTTP URL, the panel now lets the admin pick an Xray outbound from a dropdown (same UX as Geodata Auto-Update). At runtime, injectPanelEgress appends a loopback SOCKS inbound (tag: panel-egress) and prepends a routing rule so the panel's own HTTP traffic — version checks, Telegram, normal geo-file updates — is routed through the chosen outbound. Xray-native Geodata Auto-Update is unaffected (it uses its own geodata.outbound inside Xray). Blackhole outbounds are excluded from both picker dropdowns since routing any download through one just drops it. Translations updated for all 13 locales.
432 lines
13 KiB
TypeScript
432 lines
13 KiB
TypeScript
// Code generated by tools/openapigen. DO NOT EDIT.
|
|
import { z } from 'zod';
|
|
export const ProcessStateSchema = z.string();
|
|
export type ProcessState = z.infer<typeof ProcessStateSchema>;
|
|
|
|
export const ProtocolSchema = z.string();
|
|
export type Protocol = z.infer<typeof ProtocolSchema>;
|
|
|
|
export const SubLinkProviderSchema = z.unknown();
|
|
export type SubLinkProvider = z.infer<typeof SubLinkProviderSchema>;
|
|
|
|
export const transportBitsSchema = z.number().int();
|
|
export type transportBits = z.infer<typeof transportBitsSchema>;
|
|
|
|
export const AllSettingSchema = z.object({
|
|
datepicker: z.string(),
|
|
expireDiff: z.number().int().min(0),
|
|
externalTrafficInformEnable: z.boolean(),
|
|
externalTrafficInformURI: z.string(),
|
|
ldapAutoCreate: z.boolean(),
|
|
ldapAutoDelete: z.boolean(),
|
|
ldapBaseDN: z.string(),
|
|
ldapBindDN: z.string(),
|
|
ldapDefaultExpiryDays: z.number().int().min(0),
|
|
ldapDefaultLimitIP: z.number().int().min(0),
|
|
ldapDefaultTotalGB: z.number().int().min(0),
|
|
ldapEnable: z.boolean(),
|
|
ldapFlagField: z.string(),
|
|
ldapHost: z.string(),
|
|
ldapInboundTags: z.string(),
|
|
ldapInvertFlag: z.boolean(),
|
|
ldapPassword: z.string(),
|
|
ldapPort: z.number().int().min(0).max(65535),
|
|
ldapSyncCron: z.string(),
|
|
ldapTruthyValues: z.string(),
|
|
ldapUseTLS: z.boolean(),
|
|
ldapUserAttr: z.string(),
|
|
ldapUserFilter: z.string(),
|
|
ldapVlessField: z.string(),
|
|
pageSize: z.number().int().min(0).max(1000),
|
|
panelOutbound: z.string(),
|
|
remarkModel: z.string(),
|
|
restartXrayOnClientDisable: z.boolean(),
|
|
sessionMaxAge: z.number().int().min(1).max(525600),
|
|
subAnnounce: z.string(),
|
|
subCertFile: z.string(),
|
|
subClashEnable: z.boolean(),
|
|
subClashEnableRouting: z.boolean(),
|
|
subClashPath: z.string(),
|
|
subClashRules: z.string(),
|
|
subClashURI: z.string(),
|
|
subDomain: z.string(),
|
|
subEmailInRemark: z.boolean(),
|
|
subEnable: z.boolean(),
|
|
subEnableRouting: z.boolean(),
|
|
subEncrypt: z.boolean(),
|
|
subJsonEnable: z.boolean(),
|
|
subJsonFinalMask: z.string(),
|
|
subJsonMux: z.string(),
|
|
subJsonPath: z.string(),
|
|
subJsonRules: z.string(),
|
|
subJsonURI: z.string(),
|
|
subKeyFile: z.string(),
|
|
subListen: z.string(),
|
|
subPath: z.string(),
|
|
subPort: z.number().int().min(1).max(65535),
|
|
subProfileUrl: z.string(),
|
|
subRoutingRules: z.string(),
|
|
subShowInfo: z.boolean(),
|
|
subSupportUrl: z.string(),
|
|
subThemeDir: z.string(),
|
|
subTitle: z.string(),
|
|
subURI: z.string(),
|
|
subUpdates: z.number().int().min(0).max(525600),
|
|
tgBotAPIServer: z.string(),
|
|
tgBotBackup: z.boolean(),
|
|
tgBotChatId: z.string(),
|
|
tgBotEnable: z.boolean(),
|
|
tgBotLoginNotify: z.boolean(),
|
|
tgBotProxy: z.string(),
|
|
tgBotToken: z.string(),
|
|
tgCpu: z.number().int().min(0).max(100),
|
|
tgLang: z.string(),
|
|
tgRunTime: z.string(),
|
|
timeLocation: z.string(),
|
|
trafficDiff: z.number().int().min(0).max(100),
|
|
trustedProxyCIDRs: z.string(),
|
|
twoFactorEnable: z.boolean(),
|
|
twoFactorToken: z.string(),
|
|
warpUpdateInterval: z.number().int().min(0),
|
|
webBasePath: z.string(),
|
|
webCertFile: z.string(),
|
|
webDomain: z.string(),
|
|
webKeyFile: z.string(),
|
|
webListen: z.string(),
|
|
webPort: z.number().int().min(1).max(65535),
|
|
});
|
|
export type AllSetting = z.infer<typeof AllSettingSchema>;
|
|
|
|
export const AllSettingViewSchema = z.object({
|
|
datepicker: z.string(),
|
|
expireDiff: z.number().int().min(0),
|
|
externalTrafficInformEnable: z.boolean(),
|
|
externalTrafficInformURI: z.string(),
|
|
hasApiToken: z.boolean(),
|
|
hasLdapPassword: z.boolean(),
|
|
hasNordSecret: z.boolean(),
|
|
hasTgBotToken: z.boolean(),
|
|
hasTwoFactorToken: z.boolean(),
|
|
hasWarpSecret: z.boolean(),
|
|
ldapAutoCreate: z.boolean(),
|
|
ldapAutoDelete: z.boolean(),
|
|
ldapBaseDN: z.string(),
|
|
ldapBindDN: z.string(),
|
|
ldapDefaultExpiryDays: z.number().int().min(0),
|
|
ldapDefaultLimitIP: z.number().int().min(0),
|
|
ldapDefaultTotalGB: z.number().int().min(0),
|
|
ldapEnable: z.boolean(),
|
|
ldapFlagField: z.string(),
|
|
ldapHost: z.string(),
|
|
ldapInboundTags: z.string(),
|
|
ldapInvertFlag: z.boolean(),
|
|
ldapPassword: z.string(),
|
|
ldapPort: z.number().int().min(0).max(65535),
|
|
ldapSyncCron: z.string(),
|
|
ldapTruthyValues: z.string(),
|
|
ldapUseTLS: z.boolean(),
|
|
ldapUserAttr: z.string(),
|
|
ldapUserFilter: z.string(),
|
|
ldapVlessField: z.string(),
|
|
pageSize: z.number().int().min(0).max(1000),
|
|
panelOutbound: z.string(),
|
|
remarkModel: z.string(),
|
|
restartXrayOnClientDisable: z.boolean(),
|
|
sessionMaxAge: z.number().int().min(1).max(525600),
|
|
subAnnounce: z.string(),
|
|
subCertFile: z.string(),
|
|
subClashEnable: z.boolean(),
|
|
subClashEnableRouting: z.boolean(),
|
|
subClashPath: z.string(),
|
|
subClashRules: z.string(),
|
|
subClashURI: z.string(),
|
|
subDomain: z.string(),
|
|
subEmailInRemark: z.boolean(),
|
|
subEnable: z.boolean(),
|
|
subEnableRouting: z.boolean(),
|
|
subEncrypt: z.boolean(),
|
|
subJsonEnable: z.boolean(),
|
|
subJsonFinalMask: z.string(),
|
|
subJsonMux: z.string(),
|
|
subJsonPath: z.string(),
|
|
subJsonRules: z.string(),
|
|
subJsonURI: z.string(),
|
|
subKeyFile: z.string(),
|
|
subListen: z.string(),
|
|
subPath: z.string(),
|
|
subPort: z.number().int().min(1).max(65535),
|
|
subProfileUrl: z.string(),
|
|
subRoutingRules: z.string(),
|
|
subShowInfo: z.boolean(),
|
|
subSupportUrl: z.string(),
|
|
subThemeDir: z.string(),
|
|
subTitle: z.string(),
|
|
subURI: z.string(),
|
|
subUpdates: z.number().int().min(0).max(525600),
|
|
tgBotAPIServer: z.string(),
|
|
tgBotBackup: z.boolean(),
|
|
tgBotChatId: z.string(),
|
|
tgBotEnable: z.boolean(),
|
|
tgBotLoginNotify: z.boolean(),
|
|
tgBotProxy: z.string(),
|
|
tgBotToken: z.string(),
|
|
tgCpu: z.number().int().min(0).max(100),
|
|
tgLang: z.string(),
|
|
tgRunTime: z.string(),
|
|
timeLocation: z.string(),
|
|
trafficDiff: z.number().int().min(0).max(100),
|
|
trustedProxyCIDRs: z.string(),
|
|
twoFactorEnable: z.boolean(),
|
|
twoFactorToken: z.string(),
|
|
warpUpdateInterval: z.number().int().min(0),
|
|
webBasePath: z.string(),
|
|
webCertFile: z.string(),
|
|
webDomain: z.string(),
|
|
webKeyFile: z.string(),
|
|
webListen: z.string(),
|
|
webPort: z.number().int().min(1).max(65535),
|
|
});
|
|
export type AllSettingView = z.infer<typeof AllSettingViewSchema>;
|
|
|
|
export const ApiTokenSchema = z.object({
|
|
createdAt: z.number().int(),
|
|
enabled: z.boolean(),
|
|
id: z.number().int(),
|
|
name: z.string(),
|
|
token: z.string(),
|
|
});
|
|
export type ApiToken = z.infer<typeof ApiTokenSchema>;
|
|
|
|
export const ApiTokenViewSchema = z.object({
|
|
createdAt: z.number().int(),
|
|
enabled: z.boolean(),
|
|
id: z.number().int(),
|
|
name: z.string(),
|
|
token: z.string().optional(),
|
|
});
|
|
export type ApiTokenView = z.infer<typeof ApiTokenViewSchema>;
|
|
|
|
export const ClientSchema = z.object({
|
|
auth: z.string().optional(),
|
|
comment: z.string(),
|
|
created_at: z.number().int().optional(),
|
|
email: z.string(),
|
|
enable: z.boolean(),
|
|
expiryTime: z.number().int(),
|
|
flow: z.string().optional(),
|
|
group: z.string().optional(),
|
|
id: z.string().optional(),
|
|
limitIp: z.number().int(),
|
|
password: z.string().optional(),
|
|
reset: z.number().int(),
|
|
reverse: z.lazy(() => ClientReverseSchema).nullable().optional(),
|
|
security: z.string(),
|
|
subId: z.string(),
|
|
tgId: z.number().int(),
|
|
totalGB: z.number().int(),
|
|
updated_at: z.number().int().optional(),
|
|
});
|
|
export type Client = z.infer<typeof ClientSchema>;
|
|
|
|
export const ClientInboundSchema = z.object({
|
|
clientId: z.number().int(),
|
|
createdAt: z.number().int(),
|
|
flowOverride: z.string(),
|
|
inboundId: z.number().int(),
|
|
});
|
|
export type ClientInbound = z.infer<typeof ClientInboundSchema>;
|
|
|
|
export const ClientRecordSchema = z.object({
|
|
auth: z.string(),
|
|
comment: z.string(),
|
|
createdAt: z.number().int(),
|
|
email: z.string(),
|
|
enable: z.boolean(),
|
|
expiryTime: z.number().int(),
|
|
flow: z.string(),
|
|
group: z.string(),
|
|
id: z.number().int(),
|
|
limitIp: z.number().int(),
|
|
password: z.string(),
|
|
reset: z.number().int(),
|
|
reverse: z.unknown(),
|
|
security: z.string(),
|
|
subId: z.string(),
|
|
tgId: z.number().int(),
|
|
totalGB: z.number().int(),
|
|
updatedAt: z.number().int(),
|
|
uuid: z.string(),
|
|
});
|
|
export type ClientRecord = z.infer<typeof ClientRecordSchema>;
|
|
|
|
export const ClientReverseSchema = z.object({
|
|
tag: z.string(),
|
|
});
|
|
export type ClientReverse = z.infer<typeof ClientReverseSchema>;
|
|
|
|
export const ClientTrafficSchema = z.object({
|
|
down: z.number().int(),
|
|
email: z.string(),
|
|
enable: z.boolean(),
|
|
expiryTime: z.number().int(),
|
|
id: z.number().int(),
|
|
inboundId: z.number().int(),
|
|
lastOnline: z.number().int(),
|
|
reset: z.number().int(),
|
|
subId: z.string(),
|
|
total: z.number().int(),
|
|
up: z.number().int(),
|
|
uuid: z.string(),
|
|
});
|
|
export type ClientTraffic = z.infer<typeof ClientTrafficSchema>;
|
|
|
|
export const FallbackParentInfoSchema = z.object({
|
|
masterId: z.number().int(),
|
|
path: z.string().optional(),
|
|
});
|
|
export type FallbackParentInfo = z.infer<typeof FallbackParentInfoSchema>;
|
|
|
|
export const HistoryOfSeedersSchema = z.object({
|
|
id: z.number().int(),
|
|
seederName: z.string(),
|
|
});
|
|
export type HistoryOfSeeders = z.infer<typeof HistoryOfSeedersSchema>;
|
|
|
|
export const InboundSchema = z.object({
|
|
clientStats: z.array(z.lazy(() => ClientTrafficSchema)),
|
|
down: z.number().int(),
|
|
enable: z.boolean(),
|
|
expiryTime: z.number().int(),
|
|
fallbackParent: z.lazy(() => FallbackParentInfoSchema).nullable().optional(),
|
|
id: z.number().int(),
|
|
lastTrafficResetTime: z.number().int(),
|
|
listen: z.string(),
|
|
nodeId: z.number().int().nullable().optional(),
|
|
originNodeGuid: z.string().optional(),
|
|
port: z.number().int().min(0).max(65535),
|
|
protocol: z.enum(['vmess', 'vless', 'trojan', 'shadowsocks', 'wireguard', 'hysteria', 'http', 'mixed', 'tunnel', 'tun', 'mtproto']),
|
|
remark: z.string(),
|
|
settings: z.unknown(),
|
|
sniffing: z.unknown(),
|
|
streamSettings: z.unknown(),
|
|
tag: z.string(),
|
|
total: z.number().int(),
|
|
trafficReset: z.enum(['never', 'hourly', 'daily', 'weekly', 'monthly']),
|
|
up: z.number().int(),
|
|
});
|
|
export type Inbound = z.infer<typeof InboundSchema>;
|
|
|
|
export const InboundClientIpsSchema = z.object({
|
|
clientEmail: z.string(),
|
|
id: z.number().int(),
|
|
ips: z.unknown(),
|
|
});
|
|
export type InboundClientIps = z.infer<typeof InboundClientIpsSchema>;
|
|
|
|
export const InboundFallbackSchema = z.object({
|
|
alpn: z.string(),
|
|
childId: z.number().int(),
|
|
dest: z.string(),
|
|
id: z.number().int(),
|
|
masterId: z.number().int(),
|
|
name: z.string(),
|
|
path: z.string(),
|
|
sortOrder: z.number().int(),
|
|
xver: z.number().int(),
|
|
});
|
|
export type InboundFallback = z.infer<typeof InboundFallbackSchema>;
|
|
|
|
export const InboundOptionSchema = z.object({
|
|
id: z.number().int(),
|
|
port: z.number().int(),
|
|
protocol: z.string(),
|
|
remark: z.string(),
|
|
ssMethod: z.string(),
|
|
tag: z.string(),
|
|
tlsFlowCapable: z.boolean(),
|
|
});
|
|
export type InboundOption = z.infer<typeof InboundOptionSchema>;
|
|
|
|
export const MsgSchema = z.object({
|
|
msg: z.string(),
|
|
obj: z.unknown(),
|
|
success: z.boolean(),
|
|
});
|
|
export type Msg = z.infer<typeof MsgSchema>;
|
|
|
|
export const NodeSchema = z.object({
|
|
address: z.string(),
|
|
allowPrivateAddress: z.boolean(),
|
|
apiToken: z.string(),
|
|
basePath: z.string(),
|
|
clientCount: z.number().int(),
|
|
configDirty: z.boolean(),
|
|
configDirtyAt: z.number().int(),
|
|
cpuPct: z.number(),
|
|
createdAt: z.number().int(),
|
|
depletedCount: z.number().int(),
|
|
enable: z.boolean(),
|
|
guid: z.string(),
|
|
id: z.number().int(),
|
|
inboundCount: z.number().int(),
|
|
lastError: z.string(),
|
|
lastHeartbeat: z.number().int(),
|
|
latencyMs: z.number().int(),
|
|
memPct: z.number(),
|
|
name: z.string(),
|
|
onlineCount: z.number().int(),
|
|
panelVersion: z.string(),
|
|
parentGuid: z.string().optional(),
|
|
pinnedCertSha256: z.string(),
|
|
port: z.number().int().min(1).max(65535),
|
|
remark: z.string(),
|
|
scheme: z.enum(['http', 'https']),
|
|
status: z.string(),
|
|
tlsVerifyMode: z.enum(['verify', 'skip', 'pin']),
|
|
transitive: z.boolean().optional(),
|
|
updatedAt: z.number().int(),
|
|
uptimeSecs: z.number().int(),
|
|
xrayError: z.string(),
|
|
xrayState: z.string(),
|
|
xrayVersion: z.string(),
|
|
});
|
|
export type Node = z.infer<typeof NodeSchema>;
|
|
|
|
export const OutboundTrafficsSchema = z.object({
|
|
down: z.number().int(),
|
|
id: z.number().int(),
|
|
tag: z.string(),
|
|
total: z.number().int(),
|
|
up: z.number().int(),
|
|
});
|
|
export type OutboundTraffics = z.infer<typeof OutboundTrafficsSchema>;
|
|
|
|
export const ProbeResultUISchema = z.object({
|
|
cpuPct: z.number(),
|
|
error: z.string(),
|
|
latencyMs: z.number().int(),
|
|
memPct: z.number(),
|
|
panelVersion: z.string(),
|
|
status: z.string(),
|
|
uptimeSecs: z.number().int(),
|
|
xrayError: z.string(),
|
|
xrayState: z.string(),
|
|
xrayVersion: z.string(),
|
|
});
|
|
export type ProbeResultUI = z.infer<typeof ProbeResultUISchema>;
|
|
|
|
export const SettingSchema = z.object({
|
|
id: z.number().int(),
|
|
key: z.string(),
|
|
value: z.string(),
|
|
});
|
|
export type Setting = z.infer<typeof SettingSchema>;
|
|
|
|
export const UserSchema = z.object({
|
|
id: z.number().int(),
|
|
password: z.string(),
|
|
username: z.string(),
|
|
});
|
|
export type User = z.infer<typeof UserSchema>;
|
|
|