mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-26 20:50:30 +08:00
feat: add authentication token support
This commit is contained in:
parent
47fd7add5f
commit
f541b5ead1
@ -142,6 +142,7 @@ export async function createProfile(item: Partial<IProfileItem>): Promise<IProfi
|
|||||||
useProxy: item.useProxy || false,
|
useProxy: item.useProxy || false,
|
||||||
allowFixedInterval: item.allowFixedInterval || false,
|
allowFixedInterval: item.allowFixedInterval || false,
|
||||||
autoUpdate: item.autoUpdate ?? false,
|
autoUpdate: item.autoUpdate ?? false,
|
||||||
|
authToken: item.authToken,
|
||||||
updated: new Date().getTime()
|
updated: new Date().getTime()
|
||||||
} as IProfileItem
|
} as IProfileItem
|
||||||
switch (newItem.type) {
|
switch (newItem.type) {
|
||||||
@ -159,14 +160,24 @@ export async function createProfile(item: Partial<IProfileItem>): Promise<IProfi
|
|||||||
} else {
|
} else {
|
||||||
urlObj.searchParams.delete('proxy')
|
urlObj.searchParams.delete('proxy')
|
||||||
}
|
}
|
||||||
res = await chromeRequest.get(urlObj.toString(), {
|
const headers: Record<string, string> = {
|
||||||
headers: {
|
|
||||||
'User-Agent': userAgent || `mihomo.party/v${app.getVersion()} (clash.meta)`
|
'User-Agent': userAgent || `mihomo.party/v${app.getVersion()} (clash.meta)`
|
||||||
},
|
}
|
||||||
|
if (item.authToken) {
|
||||||
|
headers['Authorization'] = item.authToken
|
||||||
|
}
|
||||||
|
res = await chromeRequest.get(urlObj.toString(), {
|
||||||
|
headers,
|
||||||
responseType: 'text',
|
responseType: 'text',
|
||||||
timeout: subscriptionTimeout
|
timeout: subscriptionTimeout
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
'User-Agent': userAgent || `mihomo.party/v${app.getVersion()} (clash.meta)`
|
||||||
|
}
|
||||||
|
if (item.authToken) {
|
||||||
|
headers['Authorization'] = item.authToken
|
||||||
|
}
|
||||||
res = await chromeRequest.get(item.url, {
|
res = await chromeRequest.get(item.url, {
|
||||||
proxy: newItem.useProxy
|
proxy: newItem.useProxy
|
||||||
? {
|
? {
|
||||||
@ -175,9 +186,7 @@ export async function createProfile(item: Partial<IProfileItem>): Promise<IProfi
|
|||||||
port: mixedPort
|
port: mixedPort
|
||||||
}
|
}
|
||||||
: false,
|
: false,
|
||||||
headers: {
|
headers,
|
||||||
'User-Agent': userAgent || `mihomo.party/v${app.getVersion()} (clash.meta)`
|
|
||||||
},
|
|
||||||
responseType: 'text',
|
responseType: 'text',
|
||||||
timeout: subscriptionTimeout
|
timeout: subscriptionTimeout
|
||||||
})
|
})
|
||||||
|
|||||||
@ -91,6 +91,18 @@ const EditInfoModal: React.FC<Props> = (props) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
<SettingItem title={t('profiles.editInfo.authToken')}>
|
||||||
|
<Input
|
||||||
|
size="sm"
|
||||||
|
type="password"
|
||||||
|
className={cn(inputWidth)}
|
||||||
|
value={values.authToken || ''}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
setValues({ ...values, authToken: v })
|
||||||
|
}}
|
||||||
|
placeholder={t('profiles.editInfo.authTokenPlaceholder')}
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
<SettingItem title={t('profiles.editInfo.useProxy')}>
|
<SettingItem title={t('profiles.editInfo.useProxy')}>
|
||||||
<Switch
|
<Switch
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -438,6 +438,8 @@
|
|||||||
"profiles.editInfo.title": "Edit Information",
|
"profiles.editInfo.title": "Edit Information",
|
||||||
"profiles.editInfo.name": "Name",
|
"profiles.editInfo.name": "Name",
|
||||||
"profiles.editInfo.url": "Subscription URL",
|
"profiles.editInfo.url": "Subscription URL",
|
||||||
|
"profiles.editInfo.authToken": "Authorization Token",
|
||||||
|
"profiles.editInfo.authTokenPlaceholder": "Bearer token or other auth header value",
|
||||||
"profiles.editInfo.useProxy": "Use Proxy to Update",
|
"profiles.editInfo.useProxy": "Use Proxy to Update",
|
||||||
"profiles.editInfo.interval": "Upd. Interval",
|
"profiles.editInfo.interval": "Upd. Interval",
|
||||||
"profiles.editInfo.intervalPlaceholder": "e.g.: 30 or '0 * * * *'",
|
"profiles.editInfo.intervalPlaceholder": "e.g.: 30 or '0 * * * *'",
|
||||||
|
|||||||
@ -443,6 +443,8 @@
|
|||||||
"profiles.editInfo.title": "编辑信息",
|
"profiles.editInfo.title": "编辑信息",
|
||||||
"profiles.editInfo.name": "名称",
|
"profiles.editInfo.name": "名称",
|
||||||
"profiles.editInfo.url": "订阅地址",
|
"profiles.editInfo.url": "订阅地址",
|
||||||
|
"profiles.editInfo.authToken": "授权令牌",
|
||||||
|
"profiles.editInfo.authTokenPlaceholder": "Bearer token 或其他认证头值",
|
||||||
"profiles.editInfo.useProxy": "使用代理更新",
|
"profiles.editInfo.useProxy": "使用代理更新",
|
||||||
"profiles.editInfo.interval": "更新间隔",
|
"profiles.editInfo.interval": "更新间隔",
|
||||||
"profiles.editInfo.intervalPlaceholder": "例如:30 或 '0 * * * *'",
|
"profiles.editInfo.intervalPlaceholder": "例如:30 或 '0 * * * *'",
|
||||||
|
|||||||
@ -7,7 +7,8 @@ import {
|
|||||||
DropdownItem,
|
DropdownItem,
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownTrigger,
|
DropdownTrigger,
|
||||||
Input
|
Input,
|
||||||
|
Tooltip
|
||||||
} from '@heroui/react'
|
} from '@heroui/react'
|
||||||
import BasePage from '@renderer/components/base/base-page'
|
import BasePage from '@renderer/components/base/base-page'
|
||||||
import ProfileItem from '@renderer/components/profiles/profile-item'
|
import ProfileItem from '@renderer/components/profiles/profile-item'
|
||||||
@ -50,6 +51,8 @@ const Profiles: React.FC = () => {
|
|||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [sortedItems, setSortedItems] = useState(items)
|
const [sortedItems, setSortedItems] = useState(items)
|
||||||
const [useProxy, setUseProxy] = useState(false)
|
const [useProxy, setUseProxy] = useState(false)
|
||||||
|
const [authToken, setAuthToken] = useState('')
|
||||||
|
const [showAdvanced, setShowAdvanced] = useState(false)
|
||||||
const [subStoreImporting, setSubStoreImporting] = useState(false)
|
const [subStoreImporting, setSubStoreImporting] = useState(false)
|
||||||
const [importing, setImporting] = useState(false)
|
const [importing, setImporting] = useState(false)
|
||||||
const [updating, setUpdating] = useState(false)
|
const [updating, setUpdating] = useState(false)
|
||||||
@ -125,8 +128,15 @@ const Profiles: React.FC = () => {
|
|||||||
}, [subs, collections])
|
}, [subs, collections])
|
||||||
const handleImport = async (): Promise<void> => {
|
const handleImport = async (): Promise<void> => {
|
||||||
setImporting(true)
|
setImporting(true)
|
||||||
await addProfileItem({ name: '', type: 'remote', url, useProxy })
|
await addProfileItem({
|
||||||
|
name: '',
|
||||||
|
type: 'remote',
|
||||||
|
url,
|
||||||
|
useProxy,
|
||||||
|
authToken: authToken || undefined
|
||||||
|
})
|
||||||
setUrl('')
|
setUrl('')
|
||||||
|
setAuthToken('')
|
||||||
setImporting(false)
|
setImporting(false)
|
||||||
}
|
}
|
||||||
const pageRef = useRef<HTMLDivElement>(null)
|
const pageRef = useRef<HTMLDivElement>(null)
|
||||||
@ -225,13 +235,15 @@ const Profiles: React.FC = () => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="sticky profiles-sticky top-0 z-40 bg-background">
|
<div className="sticky profiles-sticky top-0 z-40 bg-background">
|
||||||
<div className="flex p-2">
|
<div className="flex flex-col gap-2 p-2">
|
||||||
|
<div className="flex gap-2">
|
||||||
<Input
|
<Input
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder={t('profiles.input.placeholder')}
|
placeholder={t('profiles.input.placeholder')}
|
||||||
value={url}
|
value={url}
|
||||||
onValueChange={setUrl}
|
onValueChange={setUrl}
|
||||||
onKeyUp={handleInputKeyUp}
|
onKeyUp={handleInputKeyUp}
|
||||||
|
className="flex-1"
|
||||||
endContent={
|
endContent={
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
@ -258,10 +270,19 @@ const Profiles: React.FC = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Tooltip content={t('profiles.editInfo.authToken')} placement="bottom">
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant={showAdvanced ? 'solid' : 'light'}
|
||||||
|
isIconOnly
|
||||||
|
onPress={() => setShowAdvanced(!showAdvanced)}
|
||||||
|
>
|
||||||
|
🔑
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
color="primary"
|
color="primary"
|
||||||
className="ml-2"
|
|
||||||
isDisabled={isUrlEmpty}
|
isDisabled={isUrlEmpty}
|
||||||
isLoading={importing}
|
isLoading={importing}
|
||||||
onPress={handleImport}
|
onPress={handleImport}
|
||||||
@ -279,7 +300,7 @@ const Profiles: React.FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
isLoading={subStoreImporting}
|
isLoading={subStoreImporting}
|
||||||
title="Sub-Store"
|
title="Sub-Store"
|
||||||
className="ml-2 substore-import"
|
className="substore-import"
|
||||||
size="sm"
|
size="sm"
|
||||||
isIconOnly
|
isIconOnly
|
||||||
color="primary"
|
color="primary"
|
||||||
@ -346,7 +367,7 @@ const Profiles: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
<Dropdown>
|
<Dropdown>
|
||||||
<DropdownTrigger>
|
<DropdownTrigger>
|
||||||
<Button className="ml-2 new-profile" size="sm" isIconOnly color="primary">
|
<Button className="new-profile" size="sm" isIconOnly color="primary">
|
||||||
<FaPlus />
|
<FaPlus />
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownTrigger>
|
</DropdownTrigger>
|
||||||
@ -377,6 +398,19 @@ const Profiles: React.FC = () => {
|
|||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
{showAdvanced && (
|
||||||
|
<Input
|
||||||
|
size="sm"
|
||||||
|
type="password"
|
||||||
|
placeholder={t('profiles.editInfo.authTokenPlaceholder')}
|
||||||
|
value={authToken}
|
||||||
|
onValueChange={setAuthToken}
|
||||||
|
onKeyUp={handleInputKeyUp}
|
||||||
|
className="w-full"
|
||||||
|
startContent={<span className="text-default-400 text-sm">🔑</span>}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<Divider />
|
<Divider />
|
||||||
</div>
|
</div>
|
||||||
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={onDragEnd}>
|
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={onDragEnd}>
|
||||||
|
|||||||
1
src/shared/types.d.ts
vendored
1
src/shared/types.d.ts
vendored
@ -492,6 +492,7 @@ interface IProfileItem {
|
|||||||
substore?: boolean
|
substore?: boolean
|
||||||
allowFixedInterval?: boolean
|
allowFixedInterval?: boolean
|
||||||
autoUpdate?: boolean
|
autoUpdate?: boolean
|
||||||
|
authToken?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ISubStoreSub {
|
interface ISubStoreSub {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user