dify/web/app/device/components/authorize-account.tsx
Yunlu Wen a728e0ac69
feat: adding dify cli (#36348)
Co-authored-by: GareArc <garethcxy@dify.ai>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: L1nSn0w <l1nsn0w@qq.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: gigglewang <gigglewang@dify.ai>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Xiyuan Chen <52963600+GareArc@users.noreply.github.com>
2026-05-26 01:12:36 +00:00

122 lines
3.0 KiB
TypeScript

'use client'
import type { FC } from 'react'
import { Avatar } from '@langgenius/dify-ui/avatar'
import { Button } from '@langgenius/dify-ui/button'
import { useState } from 'react'
import { deviceApproveAccount, deviceDenyAccount } from '@/service/device-flow'
import { approveErrorCopy } from '../utils/error-copy'
type Props = {
userCode: string
accountEmail?: string
accountName?: string
accountAvatarUrl?: string | null
defaultWorkspace?: string
onApproved: () => void
onDenied: () => void
onError: (message: string) => void
}
/**
* AuthorizeAccount is the account-branch authorize screen. Called with a
* live console session already established (user bounced through /signin).
* Posts to /openapi/v1/oauth/device/{approve,deny}; these endpoints mint
* the dfoa_ token server-side.
*/
const AuthorizeAccount: FC<Props> = ({
userCode,
accountEmail,
accountName,
accountAvatarUrl,
defaultWorkspace,
onApproved,
onDenied,
onError,
}) => {
const [busy, setBusy] = useState(false)
const approve = async () => {
setBusy(true)
try {
await deviceApproveAccount(userCode)
onApproved()
}
catch (e) {
onError(approveErrorCopy(e))
}
finally {
setBusy(false)
}
}
const deny = async () => {
setBusy(true)
try {
await deviceDenyAccount(userCode)
onDenied()
}
catch (e) {
onError(approveErrorCopy(e))
}
finally {
setBusy(false)
}
}
return (
<div className="flex flex-col gap-5">
<div>
<h2 className="text-2xl font-semibold text-text-primary">Authorize Dify CLI</h2>
<p className="mt-2 text-sm text-text-secondary">
difyctl is requesting access. If you didn&apos;t start this from your terminal, click Cancel.
</p>
</div>
<div className="flex items-center gap-2.5 rounded-lg bg-background-section-burn px-3 py-2.5">
<Avatar
size="md"
avatar={accountAvatarUrl ?? null}
name={accountName || accountEmail || ''}
/>
<div>
{accountName && (
<p className="text-sm font-semibold text-text-primary">{accountName}</p>
)}
{accountEmail && (
<p className="text-xs text-text-secondary">{accountEmail}</p>
)}
</div>
</div>
{defaultWorkspace && (
<div className="rounded-lg bg-background-section-burn px-3 py-2 text-sm text-text-secondary">
Workspace:
{' '}
<span className="font-semibold text-text-primary">{defaultWorkspace}</span>
</div>
)}
<div className="flex gap-3">
<Button
variant="primary"
size="large"
className="flex-1"
onClick={approve}
disabled={busy}
>
Authorize
</Button>
<Button
variant="secondary"
size="large"
className="flex-1"
onClick={deny}
disabled={busy}
>
Cancel
</Button>
</div>
</div>
)
}
export default AuthorizeAccount