tool oauth

pull/22338/head^2
zxhlyh 10 months ago
parent bda76080a9
commit bdf5af7a6f

@ -5,15 +5,16 @@ import {
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import type { ButtonProps } from '@/app/components/base/button' import type { ButtonProps } from '@/app/components/base/button'
import ApiKeyModal from './api-key-modal' import ApiKeyModal from './api-key-modal'
import type { PluginPayload } from '../types'
export type AddApiKeyButtonProps = { export type AddApiKeyButtonProps = {
provider?: string pluginPayload: PluginPayload
buttonVariant?: ButtonProps['variant'] buttonVariant?: ButtonProps['variant']
buttonText?: string buttonText?: string
disabled?: boolean disabled?: boolean
} }
const AddApiKeyButton = ({ const AddApiKeyButton = ({
provider = '', pluginPayload,
buttonVariant = 'secondary-accent', buttonVariant = 'secondary-accent',
buttonText = 'use api key', buttonText = 'use api key',
disabled, disabled,
@ -33,7 +34,7 @@ const AddApiKeyButton = ({
{ {
isApiKeyModalOpen && ( isApiKeyModalOpen && (
<ApiKeyModal <ApiKeyModal
provider={provider} pluginPayload={pluginPayload}
onClose={() => setIsApiKeyModalOpen(false)} onClose={() => setIsApiKeyModalOpen(false)}
/> />
) )

@ -7,8 +7,10 @@ import Button from '@/app/components/base/button'
import type { ButtonProps } from '@/app/components/base/button' import type { ButtonProps } from '@/app/components/base/button'
import OAuthClientSettings from './oauth-client-settings' import OAuthClientSettings from './oauth-client-settings'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import type { PluginPayload } from '../types'
export type AddOAuthButtonProps = { export type AddOAuthButtonProps = {
pluginPayload: PluginPayload
buttonVariant?: ButtonProps['variant'] buttonVariant?: ButtonProps['variant']
buttonText?: string buttonText?: string
className?: string className?: string

@ -8,28 +8,29 @@ import { useTranslation } from 'react-i18next'
import { RiExternalLinkLine } from '@remixicon/react' import { RiExternalLinkLine } from '@remixicon/react'
import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security' import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security'
import Modal from '@/app/components/base/modal/modal' import Modal from '@/app/components/base/modal/modal'
import {
useAddPluginToolCredential,
useGetPluginToolCredentialSchema,
useInvalidPluginToolCredentialInfo,
useUpdatePluginToolCredential,
} from '@/service/use-plugins-auth'
import { CredentialTypeEnum } from '../types' import { CredentialTypeEnum } from '../types'
import { transformFormSchemasSecretInput } from '../utils' import { transformFormSchemasSecretInput } from '../utils'
import AuthForm from '@/app/components/base/form/form-scenarios/auth' import AuthForm from '@/app/components/base/form/form-scenarios/auth'
import type { FromRefObject } from '@/app/components/base/form/types' import type { FromRefObject } from '@/app/components/base/form/types'
import { FormTypeEnum } from '@/app/components/base/form/types' import { FormTypeEnum } from '@/app/components/base/form/types'
import { useToastContext } from '@/app/components/base/toast' import { useToastContext } from '@/app/components/base/toast'
import type { PluginPayload } from '../types'
import {
useAddPluginCredentialHook,
useGetPluginCredentialSchemaHook,
useInvalidPluginCredentialInfoHook,
useUpdatePluginCredentialHook,
} from '../hooks/use-credential'
export type ApiKeyModalProps = { export type ApiKeyModalProps = {
provider: string pluginPayload: PluginPayload
onClose?: () => void onClose?: () => void
editValues?: Record<string, any> editValues?: Record<string, any>
onRemove?: () => void onRemove?: () => void
disabled?: boolean disabled?: boolean
} }
const ApiKeyModal = ({ const ApiKeyModal = ({
provider, pluginPayload,
onClose, onClose,
editValues, editValues,
onRemove, onRemove,
@ -37,7 +38,7 @@ const ApiKeyModal = ({
}: ApiKeyModalProps) => { }: ApiKeyModalProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const { notify } = useToastContext() const { notify } = useToastContext()
const { data = [] } = useGetPluginToolCredentialSchema(provider, CredentialTypeEnum.API_KEY) const { data = [] } = useGetPluginCredentialSchemaHook(pluginPayload, CredentialTypeEnum.API_KEY)
const formSchemas = useMemo(() => { const formSchemas = useMemo(() => {
return [ return [
{ {
@ -49,9 +50,9 @@ const ApiKeyModal = ({
...data, ...data,
] ]
}, [data]) }, [data])
const { mutateAsync: addPluginToolCredential } = useAddPluginToolCredential(provider) const { mutateAsync: addPluginCredential } = useAddPluginCredentialHook(pluginPayload)
const { mutateAsync: updatePluginToolCredential } = useUpdatePluginToolCredential(provider) const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload)
const invalidatePluginToolCredentialInfo = useInvalidPluginToolCredentialInfo(provider) const invalidatePluginCredentialInfo = useInvalidPluginCredentialInfoHook(pluginPayload)
const formRef = useRef<FromRefObject>(null) const formRef = useRef<FromRefObject>(null)
const handleConfirm = useCallback(async () => { const handleConfirm = useCallback(async () => {
const form = formRef.current?.getForm() const form = formRef.current?.getForm()
@ -73,7 +74,7 @@ const ApiKeyModal = ({
const transformedValues = transformFormSchemasSecretInput(isPristineSecretInputNames, values) const transformedValues = transformFormSchemasSecretInput(isPristineSecretInputNames, values)
if (editValues) { if (editValues) {
await updatePluginToolCredential({ await updatePluginCredential({
credentials: transformedValues, credentials: transformedValues,
credential_id: __credential_id__, credential_id: __credential_id__,
type: CredentialTypeEnum.API_KEY, type: CredentialTypeEnum.API_KEY,
@ -81,7 +82,7 @@ const ApiKeyModal = ({
}) })
} }
else { else {
await addPluginToolCredential({ await addPluginCredential({
credentials: transformedValues, credentials: transformedValues,
type: CredentialTypeEnum.API_KEY, type: CredentialTypeEnum.API_KEY,
name: __name__ || '', name: __name__ || '',
@ -93,8 +94,8 @@ const ApiKeyModal = ({
}) })
onClose?.() onClose?.()
invalidatePluginToolCredentialInfo() invalidatePluginCredentialInfo()
}, [addPluginToolCredential, onClose, invalidatePluginToolCredentialInfo, updatePluginToolCredential, notify, t, editValues, formSchemas]) }, [addPluginCredential, onClose, invalidatePluginCredentialInfo, updatePluginCredential, notify, t, editValues, formSchemas])
return ( return (
<Modal <Modal

@ -6,9 +6,10 @@ import AddOAuthButton from './add-oauth-button'
import type { AddOAuthButtonProps } from './add-oauth-button' import type { AddOAuthButtonProps } from './add-oauth-button'
import AddApiKeyButton from './add-api-key-button' import AddApiKeyButton from './add-api-key-button'
import type { AddApiKeyButtonProps } from './add-api-key-button' import type { AddApiKeyButtonProps } from './add-api-key-button'
import type { PluginPayload } from '../types'
type AuthorizeProps = { type AuthorizeProps = {
provider?: string pluginPayload: PluginPayload
theme?: 'primary' | 'secondary' theme?: 'primary' | 'secondary'
showDivider?: boolean showDivider?: boolean
canOAuth?: boolean canOAuth?: boolean
@ -16,7 +17,7 @@ type AuthorizeProps = {
disabled?: boolean disabled?: boolean
} }
const Authorize = ({ const Authorize = ({
provider = '', pluginPayload,
theme = 'primary', theme = 'primary',
showDivider = true, showDivider = true,
canOAuth, canOAuth,
@ -32,28 +33,30 @@ const Authorize = ({
buttonLeftClassName: 'hover:bg-components-button-secondary-bg-hover', buttonLeftClassName: 'hover:bg-components-button-secondary-bg-hover',
buttonRightClassName: 'hover:bg-components-button-secondary-bg-hover', buttonRightClassName: 'hover:bg-components-button-secondary-bg-hover',
dividerClassName: 'bg-divider-regular opacity-100', dividerClassName: 'bg-divider-regular opacity-100',
pluginPayload,
} }
} }
return { return {
buttonText: !canApiKey ? 'Use OAuth Authorization' : 'Use OAuth', buttonText: !canApiKey ? 'Use OAuth Authorization' : 'Use OAuth',
pluginPayload,
} }
}, [canApiKey, theme]) }, [canApiKey, theme, pluginPayload])
const apiKeyButtonProps: AddApiKeyButtonProps = useMemo(() => { const apiKeyButtonProps: AddApiKeyButtonProps = useMemo(() => {
if (theme === 'secondary') { if (theme === 'secondary') {
return { return {
provider, pluginPayload,
buttonVariant: 'secondary', buttonVariant: 'secondary',
buttonText: !canOAuth ? 'API Key Authorization Configuration' : 'Add API Key', buttonText: !canOAuth ? 'API Key Authorization Configuration' : 'Add API Key',
} }
} }
return { return {
provider, pluginPayload,
buttonText: !canOAuth ? 'API Key Authorization Configuration' : 'Use API Key', buttonText: !canOAuth ? 'API Key Authorization Configuration' : 'Use API Key',
buttonVariant: !canOAuth ? 'primary' : 'secondary-accent', buttonVariant: !canOAuth ? 'primary' : 'secondary-accent',
} }
}, [canOAuth, theme, provider]) }, [canOAuth, theme, pluginPayload])
return ( return (
<> <>

@ -1,26 +1,28 @@
import { import {
memo, memo,
useCallback, useCallback,
useMemo,
useState, useState,
} from 'react' } from 'react'
import { RiArrowDownSLine } from '@remixicon/react' import { RiArrowDownSLine } from '@remixicon/react'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import Indicator from '@/app/components/header/indicator' import Indicator from '@/app/components/header/indicator'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import type { Credential } from './types' import type {
Credential,
PluginPayload,
} from './types'
import { import {
Authorized, Authorized,
usePluginAuth, usePluginAuth,
} from '.' } from '.'
type AuthorizedInNodeProps = { type AuthorizedInNodeProps = {
provider: string pluginPayload: PluginPayload
onAuthorizationItemClick: (id: string) => void onAuthorizationItemClick: (id: string) => void
credentialId?: string credentialId?: string
} }
const AuthorizedInNode = ({ const AuthorizedInNode = ({
provider = '', pluginPayload,
onAuthorizationItemClick, onAuthorizationItemClick,
credentialId, credentialId,
}: AuthorizedInNodeProps) => { }: AuthorizedInNodeProps) => {
@ -30,29 +32,40 @@ const AuthorizedInNode = ({
canOAuth, canOAuth,
credentials, credentials,
disabled, disabled,
} = usePluginAuth(provider, isOpen) } = usePluginAuth(pluginPayload, isOpen || !!credentialId)
const label = useMemo(() => {
if (!credentialId)
return 'Workspace default'
const credential = credentials.find(c => c.id === credentialId)
if (!credential)
return 'Auth removed'
return credential.name
}, [credentials, credentialId])
const renderTrigger = useCallback((open?: boolean) => { const renderTrigger = useCallback((open?: boolean) => {
let label = ''
let removed = false
if (!credentialId) {
label = 'Workspace default'
}
else {
const credential = credentials.find(c => c.id === credentialId)
label = credential ? credential.name : 'Auth removed'
removed = !credential
}
return ( return (
<Button <Button
size='small' size='small'
className={cn(open && 'bg-components-button-ghost-bg-hover')} className={cn(
open && !removed && 'bg-components-button-ghost-bg-hover',
removed && 'bg-transparent text-text-destructive',
)}
> >
<Indicator className='mr-1.5' /> <Indicator
className='mr-1.5'
color={removed ? 'red' : 'green'}
/>
{label} {label}
<RiArrowDownSLine className='h-3.5 w-3.5 text-components-button-ghost-text' /> <RiArrowDownSLine
className={cn(
'h-3.5 w-3.5 text-components-button-ghost-text',
removed && 'text-text-destructive',
)}
/>
</Button> </Button>
) )
}, [label]) }, [credentialId, credentials])
const extraAuthorizationItems: Credential[] = [ const extraAuthorizationItems: Credential[] = [
{ {
id: '__workspace_default__', id: '__workspace_default__',
@ -72,7 +85,7 @@ const AuthorizedInNode = ({
return ( return (
<Authorized <Authorized
provider={provider} pluginPayload={pluginPayload}
credentials={credentials} credentials={credentials}
canOAuth={canOAuth} canOAuth={canOAuth}
canApiKey={canApiKey} canApiKey={canApiKey}

@ -25,15 +25,16 @@ import type { Credential } from '../types'
import { CredentialTypeEnum } from '../types' import { CredentialTypeEnum } from '../types'
import ApiKeyModal from '../authorize/api-key-modal' import ApiKeyModal from '../authorize/api-key-modal'
import Item from './item' import Item from './item'
import {
useDeletePluginToolCredential,
useInvalidPluginToolCredentialInfo,
useSetPluginToolDefaultCredential,
} from '@/service/use-plugins-auth'
import { useToastContext } from '@/app/components/base/toast' import { useToastContext } from '@/app/components/base/toast'
import type { PluginPayload } from '../types'
import {
useDeletePluginCredentialHook,
useInvalidPluginCredentialInfoHook,
useSetPluginDefaultCredentialHook,
} from '../hooks/use-credential'
type AuthorizedProps = { type AuthorizedProps = {
provider: string pluginPayload: PluginPayload
credentials: Credential[] credentials: Credential[]
canOAuth?: boolean canOAuth?: boolean
canApiKey?: boolean canApiKey?: boolean
@ -50,7 +51,7 @@ type AuthorizedProps = {
extraAuthorizationItems?: Credential[] extraAuthorizationItems?: Credential[]
} }
const Authorized = ({ const Authorized = ({
provider, pluginPayload,
credentials, credentials,
canOAuth, canOAuth,
canApiKey, canApiKey,
@ -80,8 +81,8 @@ const Authorized = ({
const apiKeyCredentials = credentials.filter(credential => credential.credential_type === CredentialTypeEnum.API_KEY) const apiKeyCredentials = credentials.filter(credential => credential.credential_type === CredentialTypeEnum.API_KEY)
const pendingOperationCredentialId = useRef<string | null>(null) const pendingOperationCredentialId = useRef<string | null>(null)
const [deleteCredentialId, setDeleteCredentialId] = useState<string | null>(null) const [deleteCredentialId, setDeleteCredentialId] = useState<string | null>(null)
const { mutateAsync: deletePluginToolCredential } = useDeletePluginToolCredential(provider) const { mutateAsync: deletePluginCredential } = useDeletePluginCredentialHook(pluginPayload)
const invalidatePluginToolCredentialInfo = useInvalidPluginToolCredentialInfo(provider) const invalidatePluginCredentialInfo = useInvalidPluginCredentialInfoHook(pluginPayload)
const openConfirm = useCallback((credentialId?: string) => { const openConfirm = useCallback((credentialId?: string) => {
if (credentialId) if (credentialId)
pendingOperationCredentialId.current = credentialId pendingOperationCredentialId.current = credentialId
@ -98,15 +99,15 @@ const Authorized = ({
return return
} }
await deletePluginToolCredential({ credential_id: pendingOperationCredentialId.current }) await deletePluginCredential({ credential_id: pendingOperationCredentialId.current })
notify({ notify({
type: 'success', type: 'success',
message: t('common.api.actionSuccess'), message: t('common.api.actionSuccess'),
}) })
invalidatePluginToolCredentialInfo() invalidatePluginCredentialInfo()
setDeleteCredentialId(null) setDeleteCredentialId(null)
pendingOperationCredentialId.current = null pendingOperationCredentialId.current = null
}, [deletePluginToolCredential, invalidatePluginToolCredentialInfo, notify, t]) }, [deletePluginCredential, invalidatePluginCredentialInfo, notify, t])
const [editValues, setEditValues] = useState<Record<string, any> | null>(null) const [editValues, setEditValues] = useState<Record<string, any> | null>(null)
const handleEdit = useCallback((id: string, values: Record<string, any>) => { const handleEdit = useCallback((id: string, values: Record<string, any>) => {
pendingOperationCredentialId.current = id pendingOperationCredentialId.current = id
@ -115,15 +116,15 @@ const Authorized = ({
const handleRemove = useCallback(() => { const handleRemove = useCallback(() => {
setDeleteCredentialId(pendingOperationCredentialId.current) setDeleteCredentialId(pendingOperationCredentialId.current)
}, []) }, [])
const { mutateAsync: setPluginToolDefaultCredential } = useSetPluginToolDefaultCredential(provider) const { mutateAsync: setPluginDefaultCredential } = useSetPluginDefaultCredentialHook(pluginPayload)
const handleSetDefault = useCallback(async (id: string) => { const handleSetDefault = useCallback(async (id: string) => {
await setPluginToolDefaultCredential(id) await setPluginDefaultCredential(id)
notify({ notify({
type: 'success', type: 'success',
message: t('common.api.actionSuccess'), message: t('common.api.actionSuccess'),
}) })
invalidatePluginToolCredentialInfo() invalidatePluginCredentialInfo()
}, [setPluginToolDefaultCredential, invalidatePluginToolCredentialInfo, notify, t]) }, [setPluginDefaultCredential, invalidatePluginCredentialInfo, notify, t])
return ( return (
<> <>
@ -224,7 +225,7 @@ const Authorized = ({
<div className='h-[1px] bg-divider-subtle'></div> <div className='h-[1px] bg-divider-subtle'></div>
<div className='p-2'> <div className='p-2'>
<Authorize <Authorize
provider={provider} pluginPayload={pluginPayload}
theme='secondary' theme='secondary'
showDivider={false} showDivider={false}
canOAuth={canOAuth} canOAuth={canOAuth}
@ -249,7 +250,7 @@ const Authorized = ({
{ {
!!editValues && ( !!editValues && (
<ApiKeyModal <ApiKeyModal
provider={provider} pluginPayload={pluginPayload}
editValues={editValues} editValues={editValues}
onClose={() => { onClose={() => {
setEditValues(null) setEditValues(null)

@ -0,0 +1,53 @@
import {
useAddPluginCredential,
useDeletePluginCredential,
useGetPluginCredentialInfo,
useGetPluginCredentialSchema,
useInvalidPluginCredentialInfo,
useSetPluginDefaultCredential,
useUpdatePluginCredential,
} from '@/service/use-plugins-auth'
import { useGetApi } from './use-get-api'
import type { PluginPayload } from '../types'
import type { CredentialTypeEnum } from '../types'
export const useGetPluginCredentialInfoHook = (pluginPayload: PluginPayload, enable?: boolean) => {
const apiMap = useGetApi(pluginPayload)
return useGetPluginCredentialInfo(enable ? apiMap.getCredentialInfo : '')
}
export const useDeletePluginCredentialHook = (pluginPayload: PluginPayload) => {
const apiMap = useGetApi(pluginPayload)
return useDeletePluginCredential(apiMap.deleteCredential)
}
export const useInvalidPluginCredentialInfoHook = (pluginPayload: PluginPayload) => {
const apiMap = useGetApi(pluginPayload)
return useInvalidPluginCredentialInfo(apiMap.getCredentialInfo)
}
export const useSetPluginDefaultCredentialHook = (pluginPayload: PluginPayload) => {
const apiMap = useGetApi(pluginPayload)
return useSetPluginDefaultCredential(apiMap.setDefaultCredential)
}
export const useGetPluginCredentialSchemaHook = (pluginPayload: PluginPayload, credentialType: CredentialTypeEnum) => {
const apiMap = useGetApi(pluginPayload)
return useGetPluginCredentialSchema(apiMap.getCredentialSchema(credentialType))
}
export const useAddPluginCredentialHook = (pluginPayload: PluginPayload) => {
const apiMap = useGetApi(pluginPayload)
return useAddPluginCredential(apiMap.addCredential)
}
export const useUpdatePluginCredentialHook = (pluginPayload: PluginPayload) => {
const apiMap = useGetApi(pluginPayload)
return useUpdatePluginCredential(apiMap.updateCredential)
}

@ -0,0 +1,39 @@
import {
AuthCategory,
} from '../types'
import type {
CredentialTypeEnum,
PluginPayload,
} from '../types'
export const useGetApi = ({ category = AuthCategory.tool, provider }: PluginPayload) => {
if (category === AuthCategory.tool) {
return {
getCredentialInfo: `/workspaces/current/tool-provider/builtin/${provider}/credential/info`,
setDefaultCredential: `/workspaces/current/tool-provider/builtin/${provider}/default-credential`,
getCredentials: `/workspaces/current/tool-provider/builtin/${provider}/credentials`,
addCredential: `/workspaces/current/tool-provider/builtin/${provider}/add`,
updateCredential: `/workspaces/current/tool-provider/builtin/${provider}/update`,
deleteCredential: `/workspaces/current/tool-provider/builtin/${provider}/delete`,
getCredentialSchema: (credential_type: CredentialTypeEnum) => `/workspaces/current/tool-provider/builtin/${provider}/credential/schema/${credential_type}`,
getOauthUrl: `/oauth/plugin/${provider}/tool/authorization-url`,
getOauthClientSchema: `/workspaces/current/tool-provider/builtin/${provider}/oauth/client-schema`,
setCustomOauthClient: `/workspaces/current/tool-provider/builtin/${provider}/oauth/custom-client`,
getCustomOAuthClient: `/workspaces/current/tool-provider/builtin/${provider}/oauth/custom-client`,
}
}
return {
getCredentialInfo: '',
setDefaultCredential: '',
getCredentials: '',
addCredential: '',
updateCredential: '',
deleteCredential: '',
getCredentialSchema: () => '',
getOauthUrl: '',
getOauthClientSchema: '',
setCustomOauthClient: '',
getCustomOAuthClient: '',
}
}

@ -1,9 +1,10 @@
import { useAppContext } from '@/context/app-context' import { useAppContext } from '@/context/app-context'
import { useGetPluginToolCredentialInfo } from '@/service/use-plugins-auth' import { useGetPluginCredentialInfoHook } from './use-credential'
import { CredentialTypeEnum } from './types' import { CredentialTypeEnum } from '../types'
import type { PluginPayload } from '../types'
export const usePluginAuth = (provider: string, enable?: boolean) => { export const usePluginAuth = (pluginPayload: PluginPayload, enable?: boolean) => {
const { data } = useGetPluginToolCredentialInfo(enable ? provider : '') const { data } = useGetPluginCredentialInfoHook(pluginPayload, enable)
const { isCurrentWorkspaceManager } = useAppContext() const { isCurrentWorkspaceManager } = useAppContext()
const isAuthorized = !!data?.credentials.length const isAuthorized = !!data?.credentials.length
const canOAuth = data?.supported_credential_types.includes(CredentialTypeEnum.OAUTH2) const canOAuth = data?.supported_credential_types.includes(CredentialTypeEnum.OAUTH2)
@ -14,7 +15,6 @@ export const usePluginAuth = (provider: string, enable?: boolean) => {
canOAuth, canOAuth,
canApiKey, canApiKey,
credentials: data?.credentials || [], credentials: data?.credentials || [],
provider,
disabled: !isCurrentWorkspaceManager, disabled: !isCurrentWorkspaceManager,
} }
} }

@ -1,4 +1,5 @@
export { default as PluginAuth } from './plugin-auth' export { default as PluginAuth } from './plugin-auth'
export { default as Authorized } from './authorized' export { default as Authorized } from './authorized'
export { default as AuthorizedInNode } from './authorized-in-node' export { default as AuthorizedInNode } from './authorized-in-node'
export { usePluginAuth } from './hooks' export { usePluginAuth } from './hooks/use-plugin-auth'
export * from './types'

@ -1,44 +1,45 @@
import { memo } from 'react' import { memo } from 'react'
import Authorize from './authorize' import Authorize from './authorize'
import Authorized from './authorized' import Authorized from './authorized'
import { useAppContext } from '@/context/app-context' import type { PluginPayload } from './types'
import { useGetPluginToolCredentialInfo } from '@/service/use-plugins-auth' import { usePluginAuth } from './hooks/use-plugin-auth'
import { CredentialTypeEnum } from './types'
type PluginAuthProps = { type PluginAuthProps = {
provider?: string pluginPayload: PluginPayload
children?: React.ReactNode children?: React.ReactNode
} }
const PluginAuth = ({ const PluginAuth = ({
provider = '', pluginPayload,
children, children,
}: PluginAuthProps) => { }: PluginAuthProps) => {
const { data } = useGetPluginToolCredentialInfo(provider) const {
const { isCurrentWorkspaceManager } = useAppContext() isAuthorized,
const isAuthorized = !!data?.credentials.length canOAuth,
const canOAuth = data?.supported_credential_types.includes(CredentialTypeEnum.OAUTH2) canApiKey,
const canApiKey = data?.supported_credential_types.includes(CredentialTypeEnum.API_KEY) credentials,
disabled,
} = usePluginAuth(pluginPayload, true)
return ( return (
<> <>
{ {
!isAuthorized && ( !isAuthorized && (
<Authorize <Authorize
provider={provider} pluginPayload={pluginPayload}
canOAuth={canOAuth} canOAuth={canOAuth}
canApiKey={canApiKey} canApiKey={canApiKey}
disabled={!isCurrentWorkspaceManager} disabled={disabled}
/> />
) )
} }
{ {
isAuthorized && !children && ( isAuthorized && !children && (
<Authorized <Authorized
provider={provider} pluginPayload={pluginPayload}
credentials={data?.credentials} credentials={credentials}
canOAuth={canOAuth} canOAuth={canOAuth}
canApiKey={canApiKey} canApiKey={canApiKey}
disabled={!isCurrentWorkspaceManager} disabled={disabled}
/> />
) )
} }

@ -1,3 +1,14 @@
export enum AuthCategory {
tool = 'tool',
datasource = 'datasource',
model = 'model',
}
export type PluginPayload = {
category: AuthCategory
provider: string
}
export enum CredentialTypeEnum { export enum CredentialTypeEnum {
OAUTH2 = 'oauth2', OAUTH2 = 'oauth2',
API_KEY = 'api-key', API_KEY = 'api-key',

@ -37,6 +37,7 @@ import { API_PREFIX } from '@/config'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { getMarketplaceUrl } from '@/utils/var' import { getMarketplaceUrl } from '@/utils/var'
import { PluginAuth } from '@/app/components/plugins/plugin-auth' import { PluginAuth } from '@/app/components/plugins/plugin-auth'
import { AuthCategory } from '@/app/components/plugins/plugin-auth'
import { useAllToolProviders } from '@/service/use-tools' import { useAllToolProviders } from '@/service/use-tools'
const i18nPrefix = 'plugin.action' const i18nPrefix = 'plugin.action'
@ -275,7 +276,10 @@ const DetailHeader = ({
{ {
category === PluginType.tool && ( category === PluginType.tool && (
<PluginAuth <PluginAuth
provider={provider?.name} pluginPayload={{
provider: provider?.name || '',
category: AuthCategory.tool,
}}
/> />
) )
} }

@ -63,6 +63,7 @@ import {
AuthorizedInNode, AuthorizedInNode,
PluginAuth, PluginAuth,
} from '@/app/components/plugins/plugin-auth' } from '@/app/components/plugins/plugin-auth'
import { AuthCategory } from '@/app/components/plugins/plugin-auth'
import { canFindTool } from '@/utils' import { canFindTool } from '@/utils'
type BasePanelProps = { type BasePanelProps = {
@ -227,14 +228,14 @@ const BasePanel: FC<BasePanelProps> = ({
const showPluginAuth = useMemo(() => { const showPluginAuth = useMemo(() => {
return data.type === BlockEnum.Tool && currCollection?.allow_delete && !currCollection.is_team_authorization return data.type === BlockEnum.Tool && currCollection?.allow_delete && !currCollection.is_team_authorization
}, [currCollection, data.type]) }, [currCollection, data.type])
const handleAuthorizationItemClick = useCallback((id: string) => { const handleAuthorizationItemClick = useCallback((credential_id: string) => {
handleNodeDataUpdate({ handleNodeDataUpdate({
id, id,
data: { data: {
credential_id: id === '__workspace_default__' ? undefined : id, credential_id: credential_id === '__workspace_default__' ? undefined : credential_id,
}, },
}) })
}, [handleNodeDataUpdate]) }, [handleNodeDataUpdate, id])
if(logParams.showSpecialResultPanel) { if(logParams.showSpecialResultPanel) {
return ( return (
@ -371,7 +372,10 @@ const BasePanel: FC<BasePanelProps> = ({
{ {
showPluginAuth && ( showPluginAuth && (
<PluginAuth <PluginAuth
provider={currCollection?.name} pluginPayload={{
provider: currCollection?.name || '',
category: AuthCategory.tool,
}}
> >
<div className='pl-4'> <div className='pl-4'>
<Tab <Tab
@ -392,7 +396,10 @@ const BasePanel: FC<BasePanelProps> = ({
{ {
currCollection?.allow_delete && ( currCollection?.allow_delete && (
<AuthorizedInNode <AuthorizedInNode
provider={currCollection?.name} pluginPayload={{
provider: currCollection?.name || '',
category: AuthCategory.tool,
}}
onAuthorizationItemClick={handleAuthorizationItemClick} onAuthorizationItemClick={handleAuthorizationItemClick}
credentialId={data.credential_id} credentialId={data.credential_id}
/> />

@ -12,48 +12,48 @@ import type { FormSchema } from '@/app/components/base/form/types'
const NAME_SPACE = 'plugins-auth' const NAME_SPACE = 'plugins-auth'
export const useGetPluginToolCredentialInfo = ( export const useGetPluginCredentialInfo = (
provider: string, url: string,
) => { ) => {
return useQuery({ return useQuery({
enabled: !!provider, enabled: !!url,
queryKey: [NAME_SPACE, 'credential-info', provider], queryKey: [NAME_SPACE, 'credential-info', url],
queryFn: () => get<{ queryFn: () => get<{
supported_credential_types: string[] supported_credential_types: string[]
credentials: Credential[] credentials: Credential[]
is_oauth_custom_client_enabled: boolean is_oauth_custom_client_enabled: boolean
}>(`/workspaces/current/tool-provider/builtin/${provider}/credential/info`), }>(url),
staleTime: 0, staleTime: 0,
}) })
} }
export const useInvalidPluginToolCredentialInfo = ( export const useInvalidPluginCredentialInfo = (
provider: string, url: string,
) => { ) => {
return useInvalid([NAME_SPACE, 'credential-info', provider]) return useInvalid([NAME_SPACE, 'credential-info', url])
} }
export const useSetPluginToolDefaultCredential = ( export const useSetPluginDefaultCredential = (
provider: string, url: string,
) => { ) => {
return useMutation({ return useMutation({
mutationFn: (id: string) => { mutationFn: (id: string) => {
return post(`/workspaces/current/tool-provider/builtin/${provider}/default-credential`, { body: { id } }) return post(url, { body: { id } })
}, },
}) })
} }
export const useGetPluginToolCredentialList = ( export const useGetPluginCredentialList = (
provider: string, url: string,
) => { ) => {
return useQuery({ return useQuery({
queryKey: [NAME_SPACE, 'credential-list', provider], queryKey: [NAME_SPACE, 'credential-list', url],
queryFn: () => get(`/workspaces/current/tool-provider/builtin/${provider}/credentials`), queryFn: () => get(url),
}) })
} }
export const useAddPluginToolCredential = ( export const useAddPluginCredential = (
provider: string, url: string,
) => { ) => {
return useMutation({ return useMutation({
mutationFn: (params: { mutationFn: (params: {
@ -61,13 +61,13 @@ export const useAddPluginToolCredential = (
type: CredentialTypeEnum type: CredentialTypeEnum
name?: string name?: string
}) => { }) => {
return post(`/workspaces/current/tool-provider/builtin/${provider}/add`, { body: params }) return post(url, { body: params })
}, },
}) })
} }
export const useUpdatePluginToolCredential = ( export const useUpdatePluginCredential = (
provider: string, url: string,
) => { ) => {
return useMutation({ return useMutation({
mutationFn: (params: { mutationFn: (params: {
@ -76,64 +76,63 @@ export const useUpdatePluginToolCredential = (
type: CredentialTypeEnum type: CredentialTypeEnum
name?: string name?: string
}) => { }) => {
return post(`/workspaces/current/tool-provider/builtin/${provider}/update`, { body: params }) return post(url, { body: params })
}, },
}) })
} }
export const useDeletePluginToolCredential = ( export const useDeletePluginCredential = (
provider: string, url: string,
) => { ) => {
return useMutation({ return useMutation({
mutationFn: (params: { credential_id: string }) => { mutationFn: (params: { credential_id: string }) => {
return post(`/workspaces/current/tool-provider/builtin/${provider}/delete`, { body: params }) return post(url, { body: params })
}, },
}) })
} }
export const useGetPluginToolCredentialSchema = ( export const useGetPluginCredentialSchema = (
provider: string, url: string,
credential_type: CredentialTypeEnum,
) => { ) => {
return useQuery({ return useQuery({
queryKey: [NAME_SPACE, 'credential-schema', provider, credential_type], queryKey: [NAME_SPACE, 'credential-schema', url],
queryFn: () => get<FormSchema[]>(`/workspaces/current/tool-provider/builtin/${provider}/credential/schema/${credential_type}`), queryFn: () => get<FormSchema[]>(url),
}) })
} }
export const useGetPluginToolOAuthUrl = ( export const useGetPluginOAuthUrl = (
provider: string, url: string,
) => { ) => {
return useQuery({ return useQuery({
queryKey: [NAME_SPACE, 'oauth-url', provider], queryKey: [NAME_SPACE, 'oauth-url', url],
queryFn: () => get(`oauth/plugin/${provider}/tool/authorization-url`), queryFn: () => get(url),
}) })
} }
export const useGetPluginToolOAuthClientSchema = ( export const useGetPluginOAuthClientSchema = (
provider: string, url: string,
) => { ) => {
return useQuery({ return useQuery({
queryKey: [NAME_SPACE, 'oauth-client-schema', provider], queryKey: [NAME_SPACE, 'oauth-client-schema', url],
queryFn: () => get(`/workspaces/current/tool-provider/builtin/${provider}/oauth/client-schema`), queryFn: () => get(url),
}) })
} }
export const useSetPluginToolOAuthCustomClient = ( export const useSetPluginOAuthCustomClient = (
provider: string, url: string,
) => { ) => {
return useMutation({ return useMutation({
mutationFn: (params) => { mutationFn: (params) => {
return post(`/workspaces/current/tool-provider/builtin/${provider}/oauth/custom-client`, { body: params }) return post(url, { body: params })
}, },
}) })
} }
export const useGetPluginToolOAuthCustomClientSchema = ( export const useGetPluginOAuthCustomClientSchema = (
provider: string, url: string,
) => { ) => {
return useQuery({ return useQuery({
queryKey: [NAME_SPACE, 'oauth-custom-client-schema', provider], queryKey: [NAME_SPACE, 'oauth-custom-client-schema', url],
queryFn: () => get(`/workspaces/current/tool-provider/builtin/${provider}/oauth/custom-client`), queryFn: () => get(url),
}) })
} }

Loading…
Cancel
Save