mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-14 04:08:46 +00:00
refac
This commit is contained in:
parent
3a54306c50
commit
4ab60527e7
4 changed files with 55 additions and 7 deletions
|
|
@ -102,6 +102,8 @@ class AppInteractionForm(StrictModel):
|
|||
|
||||
class AppManifestForm(StrictModel):
|
||||
url: str = Field(max_length=2048)
|
||||
api_key: SecretStr | None = Field(default=None, min_length=1, max_length=4096)
|
||||
app_id: str | None = None
|
||||
|
||||
|
||||
class AppForm(StrictModel):
|
||||
|
|
|
|||
|
|
@ -76,13 +76,30 @@ async def get_apps(user=Depends(get_verified_user), db: AsyncSession = Depends(g
|
|||
|
||||
|
||||
@router.post('/manifest/preview', response_model=Manifest)
|
||||
async def preview_app_manifest(form_data: AppManifestForm, user=Depends(get_admin_user)):
|
||||
async def preview_app_manifest(
|
||||
form_data: AppManifestForm, user=Depends(get_admin_user), db: AsyncSession = Depends(get_async_session)
|
||||
):
|
||||
if not await Config.get('apps.enable'):
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Apps are disabled')
|
||||
api_key = form_data.api_key.get_secret_value() if form_data.api_key is not None else None
|
||||
if form_data.app_id:
|
||||
app = await get_app_by_id(form_data.app_id, db=db)
|
||||
if form_data.url != app.data['url']:
|
||||
raise HTTPException(400, 'App URL does not match the installed app')
|
||||
if api_key is None and app.api_key:
|
||||
api_key = get_app_encryption_cipher().decrypt(app.api_key.encode()).decode()
|
||||
if not api_key:
|
||||
raise HTTPException(400, 'An app API key is required')
|
||||
try:
|
||||
status_code, raw = await send_app_request(form_data.url)
|
||||
status_code, raw = await send_app_request(
|
||||
form_data.url, headers={'Authorization': f'Bearer {api_key}'}
|
||||
)
|
||||
if status_code in (401, 403):
|
||||
raise HTTPException(400, 'App rejected the API key. Check the API key configured on the app server.')
|
||||
if status_code != 200:
|
||||
raise HTTPException(502, f'App manifest endpoint returned HTTP {status_code}. Check the URL or enter details manually.')
|
||||
raise HTTPException(
|
||||
502, f'App manifest endpoint returned HTTP {status_code}. Check the URL or enter details manually.'
|
||||
)
|
||||
manifest = Manifest.model_validate(raw)
|
||||
return manifest.model_dump()
|
||||
except HTTPException:
|
||||
|
|
|
|||
|
|
@ -157,7 +157,11 @@ export const deleteAppById = async (token: string = '', app_id: string) => {
|
|||
return res;
|
||||
};
|
||||
|
||||
export const previewAppManifest = async (token: string = '', url: string) => {
|
||||
export const previewAppManifest = async (
|
||||
token: string = '',
|
||||
url: string,
|
||||
data: { api_key?: string; app_id?: string }
|
||||
) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/apps/manifest/preview`, {
|
||||
|
|
@ -167,7 +171,7 @@ export const previewAppManifest = async (token: string = '', url: string) => {
|
|||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ url })
|
||||
body: JSON.stringify({ url, ...data })
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
|
|
|
|||
|
|
@ -77,7 +77,10 @@
|
|||
async function submit() {
|
||||
await run(async () => {
|
||||
if (!manifest) {
|
||||
manifest = await previewAppManifest(localStorage.token, url);
|
||||
manifest = await previewAppManifest(localStorage.token, url, {
|
||||
...(apiKey ? { api_key: apiKey } : {}),
|
||||
...(app ? { app_id: app.id } : {})
|
||||
});
|
||||
manual = false;
|
||||
name = manifest.name;
|
||||
slug =
|
||||
|
|
@ -288,6 +291,24 @@
|
|||
placeholder="https://app.example.com/events"
|
||||
/>
|
||||
</AdminSettingField>
|
||||
<AdminSettingField
|
||||
label={$i18n.t('API Key')}
|
||||
forId="app-api-key"
|
||||
description={app?.configured
|
||||
? $i18n.t('Leave empty to keep the current API key.')
|
||||
: $i18n.t('Enter the API key provided by the app.')}
|
||||
>
|
||||
<input
|
||||
id="app-api-key"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
class={inputClass}
|
||||
bind:value={apiKey}
|
||||
required={!app?.configured}
|
||||
maxlength="4096"
|
||||
placeholder={app?.configured ? '••••••••' : ''}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
{:else}
|
||||
<div class="flex gap-3">
|
||||
<AdminSettingField label={$i18n.t('Name')} forId="app-name" className="min-w-0 flex-1"
|
||||
|
|
@ -342,7 +363,10 @@
|
|||
class="mt-2 text-xs text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white hover:underline"
|
||||
on:click={() =>
|
||||
run(async () => {
|
||||
manifest = await previewAppManifest(localStorage.token, url);
|
||||
manifest = await previewAppManifest(localStorage.token, url, {
|
||||
...(apiKey ? { api_key: apiKey } : {}),
|
||||
...(app ? { app_id: app.id } : {})
|
||||
});
|
||||
scopes = scopes.filter((scope) => manifest.requested_scopes.includes(scope));
|
||||
manifestUpdated = true;
|
||||
showScopes = true;
|
||||
|
|
@ -360,6 +384,7 @@
|
|||
{$i18n.t('Saving approves the updated app identity and selected scopes.')}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<AdminSettingField
|
||||
label={$i18n.t('API Key')}
|
||||
forId="app-api-key"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue