mirror of
https://github.com/twentyhq/twenty
synced 2026-04-21 13:37:22 +00:00
i18n - docs translations (#19934)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
parent
65e01400c0
commit
44ba7725ae
41 changed files with 454 additions and 454 deletions
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: الأخطاء والطلبات وطلبات السحب
|
||||
icon: bug
|
||||
icon: خلل
|
||||
info: أبلغ عن المشكلات، واطلب الميزات، وساهم بالشفرة البرمجية
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ npx nx typecheck twenty-front
|
|||
npx nx typecheck twenty-server
|
||||
```
|
||||
|
||||
## "الاختبار"
|
||||
## الاختبار
|
||||
|
||||
```bash
|
||||
# Frontend
|
||||
|
|
@ -61,7 +61,7 @@ npx nx run twenty-front:graphql:generate # Regenerate typ
|
|||
npx nx run twenty-front:graphql:generate --configuration=metadata # Metadata schema
|
||||
```
|
||||
|
||||
## "الترجمات"
|
||||
## الترجمات
|
||||
|
||||
```bash
|
||||
npx nx run twenty-front:lingui:extract # Extract strings
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
---
|
||||
title: دليل الأسلوب
|
||||
icon: paintbrush
|
||||
description: Code conventions and best practices for contributing to Twenty.
|
||||
icon: فرشاة الرسم},{
|
||||
description: اتفاقيات الشيفرة وأفضل الممارسات للمساهمة في Twenty.
|
||||
---
|
||||
|
||||
## React
|
||||
|
||||
### Functional components only
|
||||
### المكوّنات الوظيفية فقط
|
||||
|
||||
Always use TSX functional components with named exports.
|
||||
استخدم دائمًا مكوّنات TSX الوظيفية مع تصديرات مسمّاة.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -23,9 +23,9 @@ export function MyComponent() {
|
|||
};
|
||||
```
|
||||
|
||||
### الإزاحة
|
||||
### الخصائص
|
||||
|
||||
Create a type named `{ComponentName}Props`. Use destructuring. Don't use `React.FC`.
|
||||
أنشئ نوعًا باسم `{ComponentName}Props`. استخدم التفكيك. لا تستخدم `React.FC`.
|
||||
|
||||
```tsx
|
||||
type MyComponentProps = {
|
||||
|
|
@ -35,7 +35,7 @@ type MyComponentProps = {
|
|||
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
|
||||
```
|
||||
|
||||
### No single-variable prop spreading
|
||||
### لا تستخدم نشر الخصائص من متغير واحد
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -45,9 +45,9 @@ const MyComponent = (props: MyComponentProps) => <Other {...props} />;
|
|||
const MyComponent = ({ prop1, prop2 }: MyComponentProps) => <Other {...{ prop1, prop2 }} />;
|
||||
```
|
||||
|
||||
## "إدارة الحالة"
|
||||
## إدارة الحالة
|
||||
|
||||
### Jotai atoms for global state
|
||||
### ذرات Jotai للحالة العامة
|
||||
|
||||
```tsx
|
||||
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
|
||||
|
|
@ -59,16 +59,16 @@ export const myAtomState = createAtomState<string>({
|
|||
});
|
||||
```
|
||||
|
||||
* Prefer atoms over prop drilling
|
||||
* Don't use `useRef` for state — use `useState` or atoms
|
||||
* Use atom families and selectors for lists
|
||||
* فضّل الذرات على تمرير الخصائص عبر المستويات (prop drilling)
|
||||
* لا تستخدم `useRef` للحالة — استخدم `useState` أو الذرات
|
||||
* استخدم عائلات الذرات والمحددات للقوائم
|
||||
|
||||
### Avoid unnecessary re-renders
|
||||
### تجنّب عمليات إعادة التصيير غير الضرورية
|
||||
|
||||
* Extract `useEffect` and data fetching into sibling sidecar components
|
||||
* Prefer event handlers (`handleClick`, `handleChange`) over `useEffect`
|
||||
* Don't use `React.memo()` — fix the root cause instead
|
||||
* Limit `useCallback` / `useMemo` usage
|
||||
* انقل `useEffect` وجلب البيانات إلى مكوّنات جانبية شقيقة (sidecar)
|
||||
* فضّل معالِجات الأحداث (`handleClick`, `handleChange`) على `useEffect`
|
||||
* لا تستخدم `React.memo()` — أصلِح السبب الجذري بدلًا من ذلك
|
||||
* حدّد استخدام `useCallback` / `useMemo`
|
||||
|
||||
```tsx
|
||||
// ❌ Bad — useEffect in the same component causes re-renders
|
||||
|
|
@ -94,11 +94,11 @@ export const Page = () => {
|
|||
|
||||
## TypeScript
|
||||
|
||||
* **`type` over `interface`** — more flexible, easier to compose
|
||||
* **String literals over enums** — except for GraphQL codegen enums and internal library APIs
|
||||
* **No `any`** — strict TypeScript enforced
|
||||
* **No type imports** — use regular imports (enforced by Oxlint `typescript/consistent-type-imports`)
|
||||
* **Use [Zod](https://github.com/colinhacks/zod)** for runtime validation of untyped objects
|
||||
* **`type` بدلًا من `interface`** — أكثر مرونة وأسهل في التركيب
|
||||
* **النصوص الحرفية بدل التعدادات** — باستثناء تعدادات codegen الخاصة بـ GraphQL وواجهات برمجة تطبيقات المكتبة الداخلية
|
||||
* **بدون `any`** — يتم فرض TypeScript الصارم
|
||||
* **عدم استيراد الأنواع** — استخدم استيرادات عادية (مفروض بواسطة Oxlint `typescript/consistent-type-imports`)
|
||||
* **استخدم [Zod](https://github.com/colinhacks/zod)** للتحقق وقت التشغيل من الكائنات غير محددة النوع
|
||||
|
||||
## JavaScript
|
||||
|
||||
|
|
@ -112,17 +112,17 @@ onClick?.();
|
|||
|
||||
## التسمية
|
||||
|
||||
* **Variables**: camelCase, descriptive (`email` not `value`, `fieldMetadata` not `fm`)
|
||||
* **Constants**: SCREAMING_SNAKE_CASE
|
||||
* **Types/Classes**: PascalCase
|
||||
* **Files/directories**: kebab-case (`.component.tsx`, `.service.ts`, `.entity.ts`)
|
||||
* **Event handlers**: `handleClick` (not `onClick` for the handler function)
|
||||
* **Component props**: prefix with component name (`ButtonProps`)
|
||||
* **Styled components**: prefix with `Styled` (`StyledTitle`)
|
||||
* **المتغيرات**: camelCase، وصفية (`email` وليس `value`، `fieldMetadata` وليس `fm`)
|
||||
* **الثوابت**: SCREAMING_SNAKE_CASE
|
||||
* **الأنواع/الفئات**: PascalCase
|
||||
* **الملفات/المجلدات**: kebab-case (`.component.tsx`, `.service.ts`, `.entity.ts`)
|
||||
* **معالجات الأحداث**: `handleClick` (وليس `onClick` لدالة المعالج)
|
||||
* **خصائص المكوّن**: ابدأ باسم المكوّن (`ButtonProps`)
|
||||
* **مكوّنات Styled**: ابدأ بـ `Styled` (`StyledTitle`)
|
||||
|
||||
## التنسيق
|
||||
|
||||
Use [Linaria](https://github.com/callstack/linaria) styled components. Use theme values — avoid hardcoded `px`, `rem`, or colors.
|
||||
استخدم مكوّنات [Linaria](https://github.com/callstack/linaria) المنسقة. استخدم قيم السمة — وتجنّب القيم المضمّنة صراحة مثل `px` و`rem` أو الألوان.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -142,7 +142,7 @@ const StyledButton = styled.button`
|
|||
|
||||
## استيرادات
|
||||
|
||||
Use aliases instead of relative paths:
|
||||
استخدم الأسماء المستعارة بدل المسارات النسبية:
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -153,7 +153,7 @@ import { Foo } from '~/testing/decorators/Foo';
|
|||
import { Bar } from '@/modules/bar/components/Bar';
|
||||
```
|
||||
|
||||
## Folder Structure
|
||||
## هيكلية المجلدات
|
||||
|
||||
```
|
||||
front
|
||||
|
|
@ -171,6 +171,6 @@ front
|
|||
└── ui/ # Reusable UI components (display, input, feedback, ...)
|
||||
```
|
||||
|
||||
* Modules can import from other modules, but `ui/` should stay dependency-free
|
||||
* Use `internal/` subfolders for module-private code
|
||||
* Components under 300 lines, services under 500 lines
|
||||
* يمكن للوحدات الاستيراد من وحدات أخرى، لكن يجب أن يبقى `ui/` خاليًا من التبعيات
|
||||
* استخدم المجلدات الفرعية `internal/` للشيفرة الخاصة بالوحدة
|
||||
* المكوّنات أقل من 300 سطر، والخدمات أقل من 500 سطر
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
---
|
||||
title: OAuth
|
||||
icon: المفتاح
|
||||
description: Authorization code flow with PKCE and client credentials for server-to-server access.
|
||||
description: تدفق رمز التفويض مع PKCE وبيانات اعتماد العميل للوصول من خادم إلى خادم.
|
||||
---
|
||||
|
||||
Twenty implements OAuth 2.0 with authorization code + PKCE for user-facing apps and client credentials for server-to-server access. Clients are registered dynamically via [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — no manual setup in a dashboard.
|
||||
تُطبِّق Twenty بروتوكول OAuth 2.0 باستخدام رمز التفويض + PKCE للتطبيقات المواجهة للمستخدم، وبيانات اعتماد العميل للوصول من خادم إلى خادم. يُجرى تسجيل العملاء ديناميكيًا عبر [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — دون إعداد يدوي في لوحة التحكم.
|
||||
|
||||
## When to Use OAuth
|
||||
## متى تستخدم OAuth
|
||||
|
||||
| السيناريو | Auth Method |
|
||||
| --------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| Internal scripts, automation | [API Key](/l/ar/developers/extend/api#authentication) |
|
||||
| External app acting on behalf of a user | **OAuth — Authorization Code** |
|
||||
| Server-to-server, no user context | **OAuth — Client Credentials** |
|
||||
| Twenty App with UI extensions | [Apps](/l/ar/developers/extend/apps/getting-started) (OAuth is handled automatically) |
|
||||
| السيناريو | طريقة المصادقة |
|
||||
| -------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| البرامج النصية الداخلية، والأتمتة | [مفتاح API](/l/ar/developers/extend/api#authentication) |
|
||||
| تطبيق خارجي يعمل نيابةً عن مستخدم | **OAuth — رمز التفويض** |
|
||||
| من خادم إلى خادم، دون سياق مستخدم | **OAuth — بيانات اعتماد العميل** |
|
||||
| تطبيق Twenty مع امتدادات واجهة المستخدم (UI) | [التطبيقات](/l/ar/developers/extend/apps/getting-started) (يتم التعامل مع OAuth تلقائيًا) |
|
||||
|
||||
## Register a Client
|
||||
## تسجيل عميل
|
||||
|
||||
Twenty supports **dynamic client registration** per [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). No manual setup needed — register programmatically:
|
||||
تدعم Twenty **التسجيل الديناميكي للعملاء** وفقًا لـ[RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). لا حاجة إلى إعداد يدوي — سجّل برمجيًا:
|
||||
|
||||
```bash
|
||||
POST /oauth/register
|
||||
|
|
@ -31,7 +31,7 @@ Content-Type: application/json
|
|||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**الاستجابة:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -43,23 +43,23 @@ Content-Type: application/json
|
|||
```
|
||||
|
||||
<Warning>
|
||||
Store the `client_secret` securely — it cannot be retrieved later.
|
||||
احفظ `client_secret` بأمان — لا يمكن استرجاعه لاحقًا.
|
||||
</Warning>
|
||||
|
||||
## النطاقات
|
||||
|
||||
| Scope | الوصول |
|
||||
| --------- | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `profile` | Read the authenticated user's profile information |
|
||||
| النطاق | الوصول |
|
||||
| --------- | -------------------------------------------------------------- |
|
||||
| `api` | إمكانية قراءة/كتابة كاملة لواجهات برمجة تطبيقات Core وMetadata |
|
||||
| `profile` | قراءة معلومات ملف تعريف المستخدم المُصادَق عليه |
|
||||
|
||||
Request scopes as a space-separated string: `scope=api profile`
|
||||
اطلب النطاقات كسلسلة مفصولة بمسافات: `scope=api profile`
|
||||
|
||||
## Authorization Code Flow
|
||||
## تدفق رمز التفويض
|
||||
|
||||
Use this flow when your app acts on behalf of a Twenty user.
|
||||
استخدم هذا التدفق عندما يعمل تطبيقك نيابةً عن مستخدم Twenty.
|
||||
|
||||
### 1. Redirect the user to authorize
|
||||
### 1. أعد توجيه المستخدم للتفويض
|
||||
|
||||
```
|
||||
GET /oauth/authorize?
|
||||
|
|
@ -72,29 +72,29 @@ GET /oauth/authorize?
|
|||
code_challenge_method=S256
|
||||
```
|
||||
|
||||
| المعلمة | مطلوب | الوصف |
|
||||
| ----------------------- | -------- | ------------------------------------------------------------ |
|
||||
| `client_id` | نعم | Your registered client ID |
|
||||
| `response_type` | نعم | Must be `code` |
|
||||
| `redirect_uri` | نعم | Must match a registered redirect URI |
|
||||
| `scope` | لا | Space-separated scopes (defaults to `api`) |
|
||||
| `الحالة` | مُوصى به | Random string to prevent CSRF attacks |
|
||||
| `code_challenge` | مُوصى به | PKCE challenge (SHA-256 hash of verifier, base64url-encoded) |
|
||||
| `code_challenge_method` | مُوصى به | Must be `S256` when using PKCE |
|
||||
| المعلمة | مطلوب | الوصف |
|
||||
| ----------------------- | -------- | -------------------------------------------------------- |
|
||||
| `client_id` | نعم | معرّف العميل المسجّل الخاص بك |
|
||||
| `response_type` | نعم | يجب أن يكون `code` |
|
||||
| `redirect_uri` | نعم | يجب أن يطابق عنوان URI لإعادة التوجيه المسجّل |
|
||||
| `scope` | لا | نطاقات مفصولة بمسافات (القيمة الافتراضية هي `api`) |
|
||||
| `state` | مُوصى به | سلسلة عشوائية لمنع هجمات CSRF |
|
||||
| `code_challenge` | مُوصى به | تحدّي PKCE (تجزئة SHA-256 لـ verifier، بترميز base64url) |
|
||||
| `code_challenge_method` | مُوصى به | يجب أن تكون `S256` عند استخدام PKCE |
|
||||
|
||||
The user sees a consent screen and approves or denies access.
|
||||
يرى المستخدم شاشة موافقة ويوافق على الوصول أو يرفضه.
|
||||
|
||||
### ٢. Handle the callback
|
||||
### ٢. معالجة الاستدعاء المرتجع
|
||||
|
||||
After authorization, Twenty redirects back to your `redirect_uri`:
|
||||
بعد التفويض، تعيد Twenty التوجيه إلى `redirect_uri` الخاص بك:
|
||||
|
||||
```
|
||||
https://myapp.com/callback?code=AUTH_CODE&state=random_state_value
|
||||
```
|
||||
|
||||
Verify that `state` matches what you sent.
|
||||
تحقّق من أن قيمة `state` تطابق ما أرسلته.
|
||||
|
||||
### ٣. Exchange the code for tokens
|
||||
### ٣. استبدِل الرمز بالرموز
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -108,7 +108,7 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
code_verifier=YOUR_PKCE_VERIFIER
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**الاستجابة:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -119,14 +119,14 @@ code_verifier=YOUR_PKCE_VERIFIER
|
|||
}
|
||||
```
|
||||
|
||||
### 4. Use the access token
|
||||
### 4. استخدم رمز الوصول
|
||||
|
||||
```bash
|
||||
GET /rest/companies
|
||||
Authorization: Bearer ACCESS_TOKEN
|
||||
```
|
||||
|
||||
### 5. Refresh when expired
|
||||
### 5. حدِّث عند انتهاء الصلاحية
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -138,9 +138,9 @@ client_id=YOUR_CLIENT_ID&
|
|||
client_secret=YOUR_CLIENT_SECRET
|
||||
```
|
||||
|
||||
## Client Credentials Flow
|
||||
## تدفق بيانات اعتماد العميل
|
||||
|
||||
For server-to-server integrations with no user interaction:
|
||||
لعمليات التكامل من خادم إلى خادم دون تفاعل مستخدم:
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -152,38 +152,38 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
scope=api
|
||||
```
|
||||
|
||||
The returned token has workspace-level access, not tied to any specific user.
|
||||
الرمز المُعاد يمتلك وصولًا على مستوى مساحة العمل، وغير مرتبط بأي مستخدم محدّد.
|
||||
|
||||
## Server Discovery
|
||||
## اكتشاف الخادم
|
||||
|
||||
Twenty publishes its OAuth configuration at a standard discovery endpoint:
|
||||
تنشر Twenty إعدادات OAuth الخاصة بها عند نقطة اكتشاف قياسية:
|
||||
|
||||
```
|
||||
GET /.well-known/oauth-authorization-server
|
||||
```
|
||||
|
||||
This returns all endpoints, supported grant types, scopes, and capabilities — useful for building generic OAuth clients.
|
||||
يعيد هذا جميع نقاط النهاية وأنواع المنح المدعومة والنطاقات والقدرات — وهو مفيد لبناء عملاء OAuth عامّين.
|
||||
|
||||
## API Endpoints Summary
|
||||
## ملخص نقاط نهاية API
|
||||
|
||||
| نقطة النهاية | الغرض |
|
||||
| ----------------------------------------- | --------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Server metadata discovery |
|
||||
| `/oauth/register` | Dynamic client registration |
|
||||
| `/oauth/authorize` | User authorization |
|
||||
| `/oauth/token` | Token exchange and refresh |
|
||||
| نقطة النهاية | الغرض |
|
||||
| ----------------------------------------- | -------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | اكتشاف بيانات تعريف الخادم |
|
||||
| `/oauth/register` | التسجيل الديناميكي للعميل |
|
||||
| `/oauth/authorize` | تفويض المستخدم |
|
||||
| `/oauth/token` | مبادلة الرموز وتحديثها |
|
||||
|
||||
| البيئة | عنوان URL الأساسي |
|
||||
| --------------------- | ------------------------ |
|
||||
| **السحابة** | `https://api.twenty.com` |
|
||||
| **الاستضافة الذاتية** | `https://{your-domain}` |
|
||||
|
||||
## OAuth vs API Keys
|
||||
## OAuth مقابل مفاتيح API
|
||||
|
||||
| | مفاتيح واجهة برمجة التطبيقات | OAuth |
|
||||
| ------------------ | ---------------------------- | -------------------------------------- |
|
||||
| **الإعداد** | Generate in Settings | Register a client, implement flow |
|
||||
| **User context** | None (workspace-level) | Specific user's permissions |
|
||||
| **الأفضل لـ** | Scripts, internal tools | External apps, multi-user integrations |
|
||||
| **Token rotation** | يدوي | Automatic via refresh tokens |
|
||||
| **Scoped access** | Full API access | Granular via scopes |
|
||||
| | مفاتيح واجهة برمجة التطبيقات | OAuth |
|
||||
| ------------------------ | -------------------------------- | ------------------------------------------ |
|
||||
| **الإعداد** | إنشاء من الإعدادات | تسجيل عميل، وتنفيذ التدفق |
|
||||
| **سياق المستخدم** | لا يوجد (على مستوى مساحة العمل) | أذونات مستخدم محدّد |
|
||||
| **الأفضل لـ** | البرامج النصية، الأدوات الداخلية | تطبيقات خارجية، وتكاملات متعددة المستخدمين |
|
||||
| **تدوير الرموز** | يدوي | تلقائي عبر رموز التحديث |
|
||||
| **وصول محدود بالنطاقات** | وصول كامل إلى API | تفصيلي عبر النطاقات |
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: خطافات الويب
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: احصل على إشعار عند تغيّر السجلات — سيتم إرسال طلب HTTP POST إلى endpoint الخاص بك عند كل عملية إنشاء أو تحديث أو حذف.
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
يقوم Twenty بإرسال طلب HTTP POST إلى URL الخاص بك كلما تم إنشاء سجل أو تحديثه أو حذفه. جميع أنواع الكائنات مشمولة، بما في ذلك الكائنات المخصصة.
|
||||
|
||||
## إنشاء خطاف ويب
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export const MyComponent = () => {
|
|||
<Tab title="المحددات">
|
||||
|
||||
|
||||
| المحددات | النوع | الوصف |
|
||||
| الخصائص | النوع | الوصف |
|
||||
| ------------------ | ----------------------- | ---------------------------------------------------------------------- |
|
||||
| linkToEntity | نص | الرابط إلى الكيان |
|
||||
| معرف الكيان | نص | المعرف الفريد للكيان |
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ export const MyComponent = () => {
|
|||
<Tab title="المحددات">
|
||||
|
||||
|
||||
| المحددات | النوع | الوصف |
|
||||
| -------- | ----------------- | ------------------------ |
|
||||
| محرر | `BlockNoteEditor` | مثيل أو تكوين محرر الكتل |
|
||||
| الخصائص | النوع | الوصف |
|
||||
| ------- | ----------------- | ------------------------ |
|
||||
| محرر | `BlockNoteEditor` | مثيل أو تكوين محرر الكتل |
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export const MyComponent = () => {
|
|||
<Tab title="المحددات">
|
||||
|
||||
|
||||
| المحددات | النوع | الوصف |
|
||||
| الخصائص | النوع | الوصف |
|
||||
| ----------------------- | ----------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| معطل | قيمة منطقية | يقوم بتعطيل منتقى الأيقونات إذا تم تعيينه إلى `true` |
|
||||
| عند التغيير | دالة | الدالة الارتجاعية التي تُفعل عندما يختار المستخدم أيقونة. يستقبل كائنًا يحتوي على الخصائص `iconKey` و `Icon` |
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export const MyComponent = () => {
|
|||
<Tab title="المحددات">
|
||||
|
||||
|
||||
| المحددات | النوع | الوصف |
|
||||
| الخصائص | النوع | الوصف |
|
||||
| ------------ | ----------- | --------------------------------------------------------------------------------- |
|
||||
| صورة | نص | 3946482746 45352F31 274435483129 27442544432A3148464A |
|
||||
| onUpload | دالة | الدالة التي تُستدعى عند قيام المستخدم بتحميل صورة جديدة. تستقبل كائن `File` كوسيط |
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export const MyComponent = () => {
|
|||
<Tab title="المحددات">
|
||||
|
||||
|
||||
| المحددات | النوع | الوصف |
|
||||
| الخصائص | النوع | الوصف |
|
||||
| ----------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| اسم الفئة | نص | فئة CSS اختيارية للتنسيق الإضافي |
|
||||
| معطل | قيمة منطقية | عند ضبطها على `true`، يتم تعطيل تفاعل المستخدم مع المكون |
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export const MyComponent = () => {
|
|||
<Tab title="المحددات">
|
||||
|
||||
|
||||
| المحددات | النوع | الوصف |
|
||||
| الخصائص | النوع | الوصف |
|
||||
| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| اسم الفئة | نص | اسم فئة اختياري لتنسيقات إضافية |
|
||||
| روابط | مصفوفة | مصفوفة من الكائنات، يمثّل كلٌّ منها رابطًا في مسار التنقّل. كل كائن يحتوي على خاصية `children` (محتوى النص للرابط) وخاصية `href` اختيارية (رابط URL للتنقل إليه عند النقر على الرابط) |
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export const MyComponent = () => {
|
|||
<Tab title="المحددات">
|
||||
|
||||
|
||||
| المحددات | النوع | الوصف |
|
||||
| الخصائص | النوع | الوصف |
|
||||
| ------------- | ----- | ----------------------------------------------------------------- |
|
||||
| الخطوة النشطة | رقم | مؤشر للخطوة النشطة حاليًا. هذا يحدد أي خطوة يجب إبرازها بشكل مرئي |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
---
|
||||
title: Stylová příručka
|
||||
icon: paintbrush
|
||||
description: Code conventions and best practices for contributing to Twenty.
|
||||
icon: paintbrush},{
|
||||
description: Konvence kódu a osvědčené postupy pro přispívání do Twenty.
|
||||
---
|
||||
|
||||
## React
|
||||
|
||||
### Functional components only
|
||||
### Pouze funkcionální komponenty
|
||||
|
||||
Always use TSX functional components with named exports.
|
||||
Vždy používejte funkcionální komponenty TSX s pojmenovanými exporty.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -25,7 +25,7 @@ export function MyComponent() {
|
|||
|
||||
### Vlastnosti
|
||||
|
||||
Create a type named `{ComponentName}Props`. Use destructuring. Don't use `React.FC`.
|
||||
Vytvořte typ s názvem `{ComponentName}Props`. Používejte destrukturování. Nepoužívejte `React.FC`.
|
||||
|
||||
```tsx
|
||||
type MyComponentProps = {
|
||||
|
|
@ -35,7 +35,7 @@ type MyComponentProps = {
|
|||
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
|
||||
```
|
||||
|
||||
### No single-variable prop spreading
|
||||
### Žádné rozprostření jediné proměnné do props
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -47,7 +47,7 @@ const MyComponent = ({ prop1, prop2 }: MyComponentProps) => <Other {...{ prop1,
|
|||
|
||||
## Správa stavu
|
||||
|
||||
### Jotai atoms for global state
|
||||
### Atomy Jotai pro globální stav
|
||||
|
||||
```tsx
|
||||
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
|
||||
|
|
@ -59,16 +59,16 @@ export const myAtomState = createAtomState<string>({
|
|||
});
|
||||
```
|
||||
|
||||
* Prefer atoms over prop drilling
|
||||
* Don't use `useRef` for state — use `useState` or atoms
|
||||
* Use atom families and selectors for lists
|
||||
* Upřednostňujte atomy před prop drillingem
|
||||
* Nepoužívejte `useRef` pro stav — použijte `useState` nebo atomy
|
||||
* Používejte rodiny atomů a selektory pro seznamy
|
||||
|
||||
### Avoid unnecessary re-renders
|
||||
### Vyhněte se zbytečnému opakovanému vykreslování
|
||||
|
||||
* Extract `useEffect` and data fetching into sibling sidecar components
|
||||
* Prefer event handlers (`handleClick`, `handleChange`) over `useEffect`
|
||||
* Don't use `React.memo()` — fix the root cause instead
|
||||
* Limit `useCallback` / `useMemo` usage
|
||||
* Vytáhněte `useEffect` a načítání dat do sourozeneckých sidecar komponent
|
||||
* Upřednostňujte obslužné funkce událostí (`handleClick`, `handleChange`) před `useEffect`
|
||||
* Nepoužívejte `React.memo()` — místo toho opravte kořenovou příčinu
|
||||
* Omezte používání `useCallback` / `useMemo`
|
||||
|
||||
```tsx
|
||||
// ❌ Bad — useEffect in the same component causes re-renders
|
||||
|
|
@ -94,11 +94,11 @@ export const Page = () => {
|
|||
|
||||
## TypeScript
|
||||
|
||||
* **`type` over `interface`** — more flexible, easier to compose
|
||||
* **String literals over enums** — except for GraphQL codegen enums and internal library APIs
|
||||
* **No `any`** — strict TypeScript enforced
|
||||
* **No type imports** — use regular imports (enforced by Oxlint `typescript/consistent-type-imports`)
|
||||
* **Use [Zod](https://github.com/colinhacks/zod)** for runtime validation of untyped objects
|
||||
* **`type` místo `interface`** — flexibilnější, lépe kombinovatelný
|
||||
* **Řetězcové literály místo výčtů** — s výjimkou enumů GraphQL codegenu a interních API knihoven
|
||||
* **Žádné `any`** — vynucený přísný TypeScript
|
||||
* **Žádné type imports** — používejte běžné importy (vynuceno nástrojem Oxlint `typescript/consistent-type-imports`)
|
||||
* **Používejte [Zod](https://github.com/colinhacks/zod)** pro runtime validaci netypovaných objektů
|
||||
|
||||
## JavaScript
|
||||
|
||||
|
|
@ -112,17 +112,17 @@ onClick?.();
|
|||
|
||||
## Pojmenovávání
|
||||
|
||||
* **Variables**: camelCase, descriptive (`email` not `value`, `fieldMetadata` not `fm`)
|
||||
* **Constants**: SCREAMING_SNAKE_CASE
|
||||
* **Types/Classes**: PascalCase
|
||||
* **Files/directories**: kebab-case (`.component.tsx`, `.service.ts`, `.entity.ts`)
|
||||
* **Event handlers**: `handleClick` (not `onClick` for the handler function)
|
||||
* **Component props**: prefix with component name (`ButtonProps`)
|
||||
* **Styled components**: prefix with `Styled` (`StyledTitle`)
|
||||
* **Proměnné**: camelCase, popisné (`email` nikoli `value`, `fieldMetadata` nikoli `fm`)
|
||||
* **Konstanty**: SCREAMING_SNAKE_CASE
|
||||
* **Typy/Třídy**: PascalCase
|
||||
* **Soubory/adresáře**: kebab-case (`.component.tsx`, `.service.ts`, `.entity.ts`)
|
||||
* **Obslužné funkce událostí**: `handleClick` (nikoli `onClick` pro obslužnou funkci)
|
||||
* **Vlastnosti komponenty (props)**: předponu tvoří název komponenty (`ButtonProps`)
|
||||
* **Stylované komponenty**: předpona `Styled` (`StyledTitle`)
|
||||
|
||||
## Styling
|
||||
|
||||
Use [Linaria](https://github.com/callstack/linaria) styled components. Use theme values — avoid hardcoded `px`, `rem`, or colors.
|
||||
Používejte stylované komponenty [Linaria](https://github.com/callstack/linaria). Používejte hodnoty z tématu — vyhněte se napevno zadaným `px`, `rem` nebo barvám.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -142,7 +142,7 @@ const StyledButton = styled.button`
|
|||
|
||||
## Importy
|
||||
|
||||
Use aliases instead of relative paths:
|
||||
Používejte aliasy místo relativních cest:
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -153,7 +153,7 @@ import { Foo } from '~/testing/decorators/Foo';
|
|||
import { Bar } from '@/modules/bar/components/Bar';
|
||||
```
|
||||
|
||||
## Folder Structure
|
||||
## Struktura složek
|
||||
|
||||
```
|
||||
front
|
||||
|
|
@ -171,6 +171,6 @@ front
|
|||
└── ui/ # Reusable UI components (display, input, feedback, ...)
|
||||
```
|
||||
|
||||
* Modules can import from other modules, but `ui/` should stay dependency-free
|
||||
* Use `internal/` subfolders for module-private code
|
||||
* Components under 300 lines, services under 500 lines
|
||||
* Moduly mohou importovat z jiných modulů, ale `ui/` by mělo zůstat bez závislostí
|
||||
* Používejte podadresáře `internal/` pro kód soukromý pro modul
|
||||
* Komponenty do 300 řádků, služby do 500 řádků
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
---
|
||||
title: OAuth
|
||||
icon: klíč
|
||||
description: Authorization code flow with PKCE and client credentials for server-to-server access.
|
||||
description: Tok s autorizačním kódem s PKCE a přihlašovacími údaji klienta pro přístup server-to-server.
|
||||
---
|
||||
|
||||
Twenty implements OAuth 2.0 with authorization code + PKCE for user-facing apps and client credentials for server-to-server access. Clients are registered dynamically via [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — no manual setup in a dashboard.
|
||||
Twenty implementuje OAuth 2.0 s autorizačním kódem + PKCE pro aplikace pro uživatele a přihlašovací údaje klienta pro přístup server-to-server. Klienti se registrují dynamicky přes [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — žádné ruční nastavení v dashboardu.
|
||||
|
||||
## When to Use OAuth
|
||||
## Kdy použít OAuth
|
||||
|
||||
| Scénář | Auth Method |
|
||||
| --------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| Internal scripts, automation | [API Key](/l/cs/developers/extend/api#authentication) |
|
||||
| External app acting on behalf of a user | **OAuth — Authorization Code** |
|
||||
| Server-to-server, no user context | **OAuth — Client Credentials** |
|
||||
| Twenty App with UI extensions | [Apps](/l/cs/developers/extend/apps/getting-started) (OAuth is handled automatically) |
|
||||
| Scénář | Metoda ověřování |
|
||||
| ---------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| Interní skripty, automatizace | [Klíč API](/l/cs/developers/extend/api#authentication) |
|
||||
| Externí aplikace jednající jménem uživatele | **OAuth — autorizační kód** |
|
||||
| Server-to-server, bez uživatelského kontextu | **OAuth — přihlašovací údaje klienta** |
|
||||
| Aplikace Twenty s rozšířeními uživatelského rozhraní | [Aplikace](/l/cs/developers/extend/apps/getting-started) (OAuth je řešen automaticky) |
|
||||
|
||||
## Register a Client
|
||||
## Registrace klienta
|
||||
|
||||
Twenty supports **dynamic client registration** per [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). No manual setup needed — register programmatically:
|
||||
Twenty podporuje **dynamickou registraci klienta** podle [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). Není potřeba žádné ruční nastavení — registrujte programově:
|
||||
|
||||
```bash
|
||||
POST /oauth/register
|
||||
|
|
@ -31,7 +31,7 @@ Content-Type: application/json
|
|||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Odpověď:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -43,23 +43,23 @@ Content-Type: application/json
|
|||
```
|
||||
|
||||
<Warning>
|
||||
Store the `client_secret` securely — it cannot be retrieved later.
|
||||
Uložte `client_secret` bezpečně — později jej nelze získat zpět.
|
||||
</Warning>
|
||||
|
||||
## Oprávnění
|
||||
|
||||
| Scope | Přístup |
|
||||
| -------- | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `profil` | Read the authenticated user's profile information |
|
||||
| Oprávnění | Přístup |
|
||||
| --------- | ----------------------------------------------------- |
|
||||
| `api` | Úplný přístup pro čtení i zápis k API Core a Metadata |
|
||||
| `profile` | Čtení informací o profilu ověřeného uživatele |
|
||||
|
||||
Request scopes as a space-separated string: `scope=api profile`
|
||||
Vyžádejte oprávnění jako řetězec oddělený mezerami: `scope=api profile`
|
||||
|
||||
## Authorization Code Flow
|
||||
## Tok s autorizačním kódem
|
||||
|
||||
Use this flow when your app acts on behalf of a Twenty user.
|
||||
Tento tok použijte, když vaše aplikace jedná jménem uživatele Twenty.
|
||||
|
||||
### 1. Redirect the user to authorize
|
||||
### 1. Přesměrujte uživatele k autorizaci
|
||||
|
||||
```
|
||||
GET /oauth/authorize?
|
||||
|
|
@ -72,29 +72,29 @@ GET /oauth/authorize?
|
|||
code_challenge_method=S256
|
||||
```
|
||||
|
||||
| Parametr | Povinné | Popis |
|
||||
| ----------------------- | ---------- | ------------------------------------------------------------ |
|
||||
| `client_id` | Ano | Your registered client ID |
|
||||
| `response_type` | Ano | Must be `code` |
|
||||
| `redirect_uri` | Ano | Must match a registered redirect URI |
|
||||
| `scope` | Ne | Space-separated scopes (defaults to `api`) |
|
||||
| `stav` | Doporučeno | Random string to prevent CSRF attacks |
|
||||
| `code_challenge` | Doporučeno | PKCE challenge (SHA-256 hash of verifier, base64url-encoded) |
|
||||
| `code_challenge_method` | Doporučeno | Must be `S256` when using PKCE |
|
||||
| Parametr | Povinné | Popis |
|
||||
| ----------------------- | ---------- | -------------------------------------------------------------- |
|
||||
| `client_id` | Ano | Vaše registrované ID klienta |
|
||||
| `response_type` | Ano | Musí být `code` |
|
||||
| `redirect_uri` | Ano | Musí odpovídat registrované adrese URI pro přesměrování |
|
||||
| `scope` | Ne | Oprávnění oddělená mezerami (výchozí je `api`) |
|
||||
| `state` | Doporučeno | Náhodný řetězec k prevenci útoků CSRF |
|
||||
| `code_challenge` | Doporučeno | Výzva PKCE (hash SHA-256 z verifieru, kódovaný jako base64url) |
|
||||
| `code_challenge_method` | Doporučeno | Při použití PKCE musí být `S256` |
|
||||
|
||||
The user sees a consent screen and approves or denies access.
|
||||
Uživatel uvidí souhlasovou obrazovku a přístup schválí nebo zamítne.
|
||||
|
||||
### 2. Handle the callback
|
||||
### 2. Zpracujte callback
|
||||
|
||||
After authorization, Twenty redirects back to your `redirect_uri`:
|
||||
Po autorizaci Twenty přesměruje zpět na vaše `redirect_uri`:
|
||||
|
||||
```
|
||||
https://myapp.com/callback?code=AUTH_CODE&state=random_state_value
|
||||
```
|
||||
|
||||
Verify that `state` matches what you sent.
|
||||
Ověřte, že `state` odpovídá tomu, co jste poslali.
|
||||
|
||||
### 3. Exchange the code for tokens
|
||||
### 3. Vyměňte kód za tokeny
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -108,7 +108,7 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
code_verifier=YOUR_PKCE_VERIFIER
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Odpověď:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -119,14 +119,14 @@ code_verifier=YOUR_PKCE_VERIFIER
|
|||
}
|
||||
```
|
||||
|
||||
### 4. Use the access token
|
||||
### 4. Použijte přístupový token
|
||||
|
||||
```bash
|
||||
GET /rest/companies
|
||||
Authorization: Bearer ACCESS_TOKEN
|
||||
```
|
||||
|
||||
### 5. Refresh when expired
|
||||
### 5. Obnovte po vypršení platnosti
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -138,9 +138,9 @@ client_id=YOUR_CLIENT_ID&
|
|||
client_secret=YOUR_CLIENT_SECRET
|
||||
```
|
||||
|
||||
## Client Credentials Flow
|
||||
## Tok s přihlašovacími údaji klienta
|
||||
|
||||
For server-to-server integrations with no user interaction:
|
||||
Pro integrace server-to-server bez interakce uživatele:
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -152,38 +152,38 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
scope=api
|
||||
```
|
||||
|
||||
The returned token has workspace-level access, not tied to any specific user.
|
||||
Vrácený token má přístup na úrovni pracovního prostoru, není vázán na žádného konkrétního uživatele.
|
||||
|
||||
## Server Discovery
|
||||
## Zjišťování serveru
|
||||
|
||||
Twenty publishes its OAuth configuration at a standard discovery endpoint:
|
||||
Twenty zveřejňuje svou konfiguraci OAuth na standardním koncovém bodu pro zjišťování:
|
||||
|
||||
```
|
||||
GET /.well-known/oauth-authorization-server
|
||||
```
|
||||
|
||||
This returns all endpoints, supported grant types, scopes, and capabilities — useful for building generic OAuth clients.
|
||||
Vrací všechny koncové body, podporované typy grantů, oprávnění a možnosti — užitečné pro tvorbu obecných klientů OAuth.
|
||||
|
||||
## API Endpoints Summary
|
||||
## Přehled koncových bodů API
|
||||
|
||||
| Koncový bod | Účel |
|
||||
| ----------------------------------------- | --------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Server metadata discovery |
|
||||
| `/oauth/register` | Dynamic client registration |
|
||||
| `/oauth/authorize` | User authorization |
|
||||
| `/oauth/token` | Token exchange and refresh |
|
||||
| Koncový bod | Účel |
|
||||
| ----------------------------------------- | ---------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Zjišťování metadat serveru |
|
||||
| `/oauth/register` | Dynamická registrace klienta |
|
||||
| `/oauth/authorize` | Autorizace uživatele |
|
||||
| `/oauth/token` | Výměna a obnovení tokenu |
|
||||
|
||||
| Prostředí | Základní URL |
|
||||
| ------------------- | ------------------------ |
|
||||
| **Cloud** | `https://api.twenty.com` |
|
||||
| **Vlastní hosting** | `https://{your-domain}` |
|
||||
|
||||
## OAuth vs API Keys
|
||||
## OAuth vs klíče API
|
||||
|
||||
| | API Klíče | OAuth |
|
||||
| ------------------ | ----------------------- | -------------------------------------- |
|
||||
| **Nastavení** | Generate in Settings | Register a client, implement flow |
|
||||
| **User context** | None (workspace-level) | Specific user's permissions |
|
||||
| **Vhodné pro** | Scripts, internal tools | External apps, multi-user integrations |
|
||||
| **Token rotation** | Ruční | Automatic via refresh tokens |
|
||||
| **Scoped access** | Full API access | Granular via scopes |
|
||||
| | API Klíče | OAuth |
|
||||
| --------------------------- | ------------------------------------- | ------------------------------------------- |
|
||||
| **Nastavení** | Generovat v Nastavení | Zaregistrovat klienta, implementovat tok |
|
||||
| **Uživatelský kontext** | Žádný (na úrovni pracovního prostoru) | Oprávnění konkrétního uživatele |
|
||||
| **Vhodné pro** | Skripty, interní nástroje | Externí aplikace, víceuživatelské integrace |
|
||||
| **Rotace tokenů** | Ruční | Automaticky prostřednictvím refresh tokenů |
|
||||
| **Přístup podle oprávnění** | Plný přístup k API | Jemně odstupňovaný pomocí oprávnění |
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: Webhooky
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: Dostávejte upozornění při změnách záznamů — HTTP POST na váš koncový bod při každém vytvoření, aktualizaci nebo smazání.
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
Twenty odešle HTTP POST na vaši adresu URL pokaždé, když je záznam vytvořen, aktualizován nebo smazán. Všechny typy objektů jsou podporovány, včetně vlastních objektů.
|
||||
|
||||
## Vytvořit Webhook
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Řešení potíží
|
||||
icon: wrench
|
||||
icon: klíč
|
||||
---
|
||||
|
||||
## Řešení potíží
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: Záznamové stránky},{
|
||||
title: Stránky záznamů
|
||||
description: Přizpůsobte rozvržení jednotlivých stránek detailu záznamu pomocí karet a widgetů.
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
---
|
||||
title: Styleguide
|
||||
icon: paintbrush
|
||||
description: Code conventions and best practices for contributing to Twenty.
|
||||
description: Code-Konventionen und bewährte Verfahren für Beiträge zu Twenty.
|
||||
---
|
||||
|
||||
## React
|
||||
|
||||
### Functional components only
|
||||
### Ausschließlich funktionale Komponenten
|
||||
|
||||
Always use TSX functional components with named exports.
|
||||
Verwenden Sie immer TSX-Funktionskomponenten mit benannten Exporten.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -25,7 +25,7 @@ export function MyComponent() {
|
|||
|
||||
### Props
|
||||
|
||||
Create a type named `{ComponentName}Props`. Use destructuring. Don't use `React.FC`.
|
||||
Erstellen Sie einen Typ namens `{ComponentName}Props`. Verwenden Sie Destrukturierung. Verwenden Sie `React.FC` nicht.
|
||||
|
||||
```tsx
|
||||
type MyComponentProps = {
|
||||
|
|
@ -35,7 +35,7 @@ type MyComponentProps = {
|
|||
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
|
||||
```
|
||||
|
||||
### No single-variable prop spreading
|
||||
### Kein Prop-Spreading mit einer einzelnen Variablen
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -47,7 +47,7 @@ const MyComponent = ({ prop1, prop2 }: MyComponentProps) => <Other {...{ prop1,
|
|||
|
||||
## Zustandsverwaltung
|
||||
|
||||
### Jotai atoms for global state
|
||||
### Jotai-Atome für globalen Zustand
|
||||
|
||||
```tsx
|
||||
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
|
||||
|
|
@ -59,16 +59,16 @@ export const myAtomState = createAtomState<string>({
|
|||
});
|
||||
```
|
||||
|
||||
* Prefer atoms over prop drilling
|
||||
* Don't use `useRef` for state — use `useState` or atoms
|
||||
* Use atom families and selectors for lists
|
||||
* Bevorzugen Sie Atome gegenüber Prop-Drilling
|
||||
* Verwenden Sie `useRef` nicht für den Zustand — verwenden Sie `useState` oder Atome
|
||||
* Verwenden Sie Atomfamilien und Selektoren für Listen
|
||||
|
||||
### Avoid unnecessary re-renders
|
||||
### Vermeiden Sie unnötige Re-Renders
|
||||
|
||||
* Extract `useEffect` and data fetching into sibling sidecar components
|
||||
* Prefer event handlers (`handleClick`, `handleChange`) over `useEffect`
|
||||
* Don't use `React.memo()` — fix the root cause instead
|
||||
* Limit `useCallback` / `useMemo` usage
|
||||
* Lagern Sie `useEffect` und das Daten-Fetching in gleichrangige Sidecar-Komponenten aus
|
||||
* Bevorzugen Sie Event-Handler (`handleClick`, `handleChange`) gegenüber `useEffect`
|
||||
* Verwenden Sie `React.memo()` nicht — beheben Sie stattdessen die Grundursache
|
||||
* Beschränken Sie die Nutzung von `useCallback`/`useMemo`
|
||||
|
||||
```tsx
|
||||
// ❌ Bad — useEffect in the same component causes re-renders
|
||||
|
|
@ -94,11 +94,11 @@ export const Page = () => {
|
|||
|
||||
## TypeScript
|
||||
|
||||
* **`type` over `interface`** — more flexible, easier to compose
|
||||
* **String literals over enums** — except for GraphQL codegen enums and internal library APIs
|
||||
* **No `any`** — strict TypeScript enforced
|
||||
* **No type imports** — use regular imports (enforced by Oxlint `typescript/consistent-type-imports`)
|
||||
* **Use [Zod](https://github.com/colinhacks/zod)** for runtime validation of untyped objects
|
||||
* **`type` statt `interface`** — flexibler, leichter zu kombinieren
|
||||
* **String-Literale statt Enums** — außer für GraphQL-Codegen-Enums und interne Bibliotheks-APIs
|
||||
* **Kein `any`** — striktes TypeScript wird durchgesetzt
|
||||
* **Keine Type-Imports** — verwenden Sie reguläre Imports (erzwungen durch Oxlint `typescript/consistent-type-imports`)
|
||||
* **Verwenden Sie [Zod](https://github.com/colinhacks/zod)** für die Laufzeitvalidierung ungetypter Objekte
|
||||
|
||||
## JavaScript
|
||||
|
||||
|
|
@ -112,17 +112,17 @@ onClick?.();
|
|||
|
||||
## Namensgebung
|
||||
|
||||
* **Variables**: camelCase, descriptive (`email` not `value`, `fieldMetadata` not `fm`)
|
||||
* **Constants**: SCREAMING_SNAKE_CASE
|
||||
* **Types/Classes**: PascalCase
|
||||
* **Files/directories**: kebab-case (`.component.tsx`, `.service.ts`, `.entity.ts`)
|
||||
* **Event handlers**: `handleClick` (not `onClick` for the handler function)
|
||||
* **Component props**: prefix with component name (`ButtonProps`)
|
||||
* **Styled components**: prefix with `Styled` (`StyledTitle`)
|
||||
* **Variablen**: camelCase, aussagekräftig (`email` statt `value`, `fieldMetadata` statt `fm`)
|
||||
* **Konstanten**: SCREAMING_SNAKE_CASE
|
||||
* **Typen/Klassen**: PascalCase
|
||||
* **Dateien/Verzeichnisse**: kebab-case (`.component.tsx`, `.service.ts`, `.entity.ts`)
|
||||
* **Event-Handler**: `handleClick` (nicht `onClick` für die Handler-Funktion)
|
||||
* **Komponenten-Props**: mit dem Komponentennamen präfixieren (`ButtonProps`)
|
||||
* **Styled Components**: mit `Styled` präfixieren (`StyledTitle`)
|
||||
|
||||
## Styling
|
||||
|
||||
Use [Linaria](https://github.com/callstack/linaria) styled components. Use theme values — avoid hardcoded `px`, `rem`, or colors.
|
||||
Verwenden Sie [Linaria](https://github.com/callstack/linaria) Styled Components. Verwenden Sie Theme-Werte — vermeiden Sie hartkodierte `px`, `rem` oder Farben.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -142,7 +142,7 @@ const StyledButton = styled.button`
|
|||
|
||||
## Importe
|
||||
|
||||
Use aliases instead of relative paths:
|
||||
Verwenden Sie Aliase statt relativer Pfade:
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
|
|
@ -153,7 +153,7 @@ import { Foo } from '~/testing/decorators/Foo';
|
|||
import { Bar } from '@/modules/bar/components/Bar';
|
||||
```
|
||||
|
||||
## Folder Structure
|
||||
## Ordnerstruktur
|
||||
|
||||
```
|
||||
front
|
||||
|
|
@ -171,6 +171,6 @@ front
|
|||
└── ui/ # Reusable UI components (display, input, feedback, ...)
|
||||
```
|
||||
|
||||
* Modules can import from other modules, but `ui/` should stay dependency-free
|
||||
* Use `internal/` subfolders for module-private code
|
||||
* Components under 300 lines, services under 500 lines
|
||||
* Module können aus anderen Modulen importieren, aber `ui/` sollte abhängigkeitsfrei bleiben
|
||||
* Verwenden Sie `internal/`-Unterordner für modulinternen Code
|
||||
* Komponenten unter 300 Zeilen, Services unter 500 Zeilen
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
---
|
||||
title: OAuth
|
||||
icon: schlüssel
|
||||
description: Authorization code flow with PKCE and client credentials for server-to-server access.
|
||||
description: Autorisierungscode-Flow mit PKCE und Client-Anmeldedaten für Server-zu-Server-Zugriff.
|
||||
---
|
||||
|
||||
Twenty implements OAuth 2.0 with authorization code + PKCE for user-facing apps and client credentials for server-to-server access. Clients are registered dynamically via [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — no manual setup in a dashboard.
|
||||
Twenty implementiert OAuth 2.0 mit Autorisierungscode + PKCE für benutzerorientierte Apps und Client-Anmeldedaten für Server-zu-Server-Zugriff. Clients werden dynamisch über [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) registriert — keine manuelle Einrichtung in einem Dashboard.
|
||||
|
||||
## When to Use OAuth
|
||||
## Wann Sie OAuth verwenden sollten
|
||||
|
||||
| Szenario | Auth Method |
|
||||
| --------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| Internal scripts, automation | [API Key](/l/de/developers/extend/api#authentication) |
|
||||
| External app acting on behalf of a user | **OAuth — Authorization Code** |
|
||||
| Server-to-server, no user context | **OAuth — Client Credentials** |
|
||||
| Twenty App with UI extensions | [Apps](/l/de/developers/extend/apps/getting-started) (OAuth is handled automatically) |
|
||||
| Szenario | Authentifizierungsmethode |
|
||||
| ------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| Interne Skripte, Automatisierung | [API-Schlüssel](/l/de/developers/extend/api#authentication) |
|
||||
| Externe App, die im Namen eines Benutzers handelt | **OAuth — Autorisierungscode** |
|
||||
| Server-zu-Server, kein Benutzerkontext | **OAuth — Client-Anmeldedaten** |
|
||||
| Twenty-App mit UI-Erweiterungen | [Apps](/l/de/developers/extend/apps/getting-started) (OAuth wird automatisch gehandhabt) |
|
||||
|
||||
## Register a Client
|
||||
## Einen Client registrieren
|
||||
|
||||
Twenty supports **dynamic client registration** per [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). No manual setup needed — register programmatically:
|
||||
Twenty unterstützt die **dynamische Client-Registrierung** gemäß [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). Keine manuelle Einrichtung erforderlich — registrieren Sie den Client programmgesteuert:
|
||||
|
||||
```bash
|
||||
POST /oauth/register
|
||||
|
|
@ -31,7 +31,7 @@ Content-Type: application/json
|
|||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Antwort:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -43,23 +43,23 @@ Content-Type: application/json
|
|||
```
|
||||
|
||||
<Warning>
|
||||
Store the `client_secret` securely — it cannot be retrieved later.
|
||||
Speichern Sie das `client_secret` sicher — es kann später nicht mehr abgerufen werden.
|
||||
</Warning>
|
||||
|
||||
## Geltungsbereiche
|
||||
|
||||
| Scope | Zugriff |
|
||||
| -------- | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `profil` | Read the authenticated user's profile information |
|
||||
| Geltungsbereich | Zugriff |
|
||||
| --------------- | ----------------------------------------------------------- |
|
||||
| `api` | Voller Lese-/Schreibzugriff auf die Core- und Metadata-APIs |
|
||||
| `profile` | Profilinformationen des authentifizierten Benutzers lesen |
|
||||
|
||||
Request scopes as a space-separated string: `scope=api profile`
|
||||
Fordern Sie Geltungsbereiche als durch Leerzeichen getrennte Zeichenfolge an: `scope=api profile`
|
||||
|
||||
## Authorization Code Flow
|
||||
## Autorisierungscode-Flow
|
||||
|
||||
Use this flow when your app acts on behalf of a Twenty user.
|
||||
Verwenden Sie diesen Flow, wenn Ihre App im Namen eines Twenty-Benutzers handelt.
|
||||
|
||||
### 1. Redirect the user to authorize
|
||||
### 1. Leiten Sie den Benutzer zur Autorisierung weiter
|
||||
|
||||
```
|
||||
GET /oauth/authorize?
|
||||
|
|
@ -72,29 +72,29 @@ GET /oauth/authorize?
|
|||
code_challenge_method=S256
|
||||
```
|
||||
|
||||
| Parameter | Erforderlich | Beschreibung |
|
||||
| ----------------------- | ------------ | ------------------------------------------------------------ |
|
||||
| `client_id` | Ja | Your registered client ID |
|
||||
| `response_type` | Ja | Must be `code` |
|
||||
| `redirect_uri` | Ja | Must match a registered redirect URI |
|
||||
| `scope` | Nein | Space-separated scopes (defaults to `api`) |
|
||||
| `zustand` | Empfohlen | Random string to prevent CSRF attacks |
|
||||
| `code_challenge` | Empfohlen | PKCE challenge (SHA-256 hash of verifier, base64url-encoded) |
|
||||
| `code_challenge_method` | Empfohlen | Must be `S256` when using PKCE |
|
||||
| Parameter | Erforderlich | Beschreibung |
|
||||
| ----------------------- | ------------ | -------------------------------------------------------------- |
|
||||
| `client_id` | Ja | Ihre registrierte Client-ID |
|
||||
| `response_type` | Ja | Muss `code` sein |
|
||||
| `redirect_uri` | Ja | Muss einer registrierten Redirect-URI entsprechen |
|
||||
| `scope` | Nein | Durch Leerzeichen getrennte Geltungsbereiche (Standard: `api`) |
|
||||
| `state` | Empfohlen | Zufällige Zeichenfolge zur Verhinderung von CSRF-Angriffen |
|
||||
| `code_challenge` | Empfohlen | PKCE-Challenge (SHA-256-Hash des Verifiers, base64url-codiert) |
|
||||
| `code_challenge_method` | Empfohlen | Muss bei Verwendung von PKCE `S256` sein |
|
||||
|
||||
The user sees a consent screen and approves or denies access.
|
||||
Der Benutzer sieht einen Zustimmungsbildschirm und stimmt dem Zugriff zu oder lehnt ihn ab.
|
||||
|
||||
### 2. Handle the callback
|
||||
### 2. Den Callback verarbeiten
|
||||
|
||||
After authorization, Twenty redirects back to your `redirect_uri`:
|
||||
Nach der Autorisierung leitet Twenty zurück zu Ihrer `redirect_uri` weiter:
|
||||
|
||||
```
|
||||
https://myapp.com/callback?code=AUTH_CODE&state=random_state_value
|
||||
```
|
||||
|
||||
Verify that `state` matches what you sent.
|
||||
Überprüfen Sie, dass `state` mit dem übereinstimmt, was Sie gesendet haben.
|
||||
|
||||
### 3. Exchange the code for tokens
|
||||
### 3. Tauschen Sie den Code gegen Token aus
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -108,7 +108,7 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
code_verifier=YOUR_PKCE_VERIFIER
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Antwort:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -119,14 +119,14 @@ code_verifier=YOUR_PKCE_VERIFIER
|
|||
}
|
||||
```
|
||||
|
||||
### 4. Use the access token
|
||||
### 4. Verwenden Sie das Zugriffstoken
|
||||
|
||||
```bash
|
||||
GET /rest/companies
|
||||
Authorization: Bearer ACCESS_TOKEN
|
||||
```
|
||||
|
||||
### 5. Refresh when expired
|
||||
### 5. Aktualisieren, wenn abgelaufen
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -138,9 +138,9 @@ client_id=YOUR_CLIENT_ID&
|
|||
client_secret=YOUR_CLIENT_SECRET
|
||||
```
|
||||
|
||||
## Client Credentials Flow
|
||||
## Client-Anmeldedaten-Flow
|
||||
|
||||
For server-to-server integrations with no user interaction:
|
||||
Für Server-zu-Server-Integrationen ohne Benutzerinteraktion:
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -152,38 +152,38 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
scope=api
|
||||
```
|
||||
|
||||
The returned token has workspace-level access, not tied to any specific user.
|
||||
Das zurückgegebene Token hat Zugriff auf Arbeitsbereichsebene und ist an keinen bestimmten Benutzer gebunden.
|
||||
|
||||
## Server Discovery
|
||||
## Server-Ermittlung
|
||||
|
||||
Twenty publishes its OAuth configuration at a standard discovery endpoint:
|
||||
Twenty veröffentlicht seine OAuth-Konfiguration an einem standardisierten Discovery-Endpunkt:
|
||||
|
||||
```
|
||||
GET /.well-known/oauth-authorization-server
|
||||
```
|
||||
|
||||
This returns all endpoints, supported grant types, scopes, and capabilities — useful for building generic OAuth clients.
|
||||
Dies liefert alle Endpunkte, unterstützte Grant-Typen, Geltungsbereiche und Fähigkeiten — nützlich, um generische OAuth-Clients zu erstellen.
|
||||
|
||||
## API Endpoints Summary
|
||||
## Zusammenfassung der API-Endpunkte
|
||||
|
||||
| Endpunkt | Zweck |
|
||||
| ----------------------------------------- | --------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Server metadata discovery |
|
||||
| `/oauth/register` | Dynamic client registration |
|
||||
| `/oauth/authorize` | User authorization |
|
||||
| `/oauth/token` | Token exchange and refresh |
|
||||
| Endpunkt | Zweck |
|
||||
| ----------------------------------------- | ----------------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Ermittlung von Servermetadaten |
|
||||
| `/oauth/register` | Dynamische Client-Registrierung |
|
||||
| `/oauth/authorize` | Benutzerautorisierung |
|
||||
| `/oauth/token` | Token-Austausch und -Aktualisierung |
|
||||
|
||||
| Umgebung | Basis-URL |
|
||||
| ----------------- | ------------------------ |
|
||||
| **Cloud** | `https://api.twenty.com` |
|
||||
| **Selbsthosting** | `https://{your-domain}` |
|
||||
|
||||
## OAuth vs API Keys
|
||||
## OAuth vs. API-Schlüssel
|
||||
|
||||
| | API-Schlüssel | OAuth |
|
||||
| -------------------------- | ----------------------- | -------------------------------------- |
|
||||
| **Einrichtung** | Generate in Settings | Register a client, implement flow |
|
||||
| **User context** | None (workspace-level) | Specific user's permissions |
|
||||
| **Am besten geeignet für** | Scripts, internal tools | External apps, multi-user integrations |
|
||||
| **Token rotation** | Manuell | Automatic via refresh tokens |
|
||||
| **Scoped access** | Full API access | Granular via scopes |
|
||||
| | API-Schlüssel | OAuth |
|
||||
| ------------------------------------- | ------------------------------- | ----------------------------------------- |
|
||||
| **Einrichtung** | In den Einstellungen generieren | Client registrieren, Flow implementieren |
|
||||
| **Benutzerkontext** | Keiner (Arbeitsbereichsebene) | Berechtigungen eines bestimmten Benutzers |
|
||||
| **Am besten geeignet für** | Skripte, interne Tools | Externe Apps, Multi-User-Integrationen |
|
||||
| **Token-Rotation** | Manuell | Automatisch über Refresh-Tokens |
|
||||
| **Geltungsbereichsbasierter Zugriff** | Voller API-Zugriff | Granular über Geltungsbereiche |
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: Webhooks
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: Lassen Sie sich benachrichtigen, wenn sich Datensätze ändern — HTTP POST an Ihren Endpunkt bei jeder Erstellung, Aktualisierung oder Löschung.
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
Twenty sendet einen HTTP POST an Ihre URL, wenn ein Datensatz erstellt, aktualisiert oder gelöscht wird. Alle Objekttypen sind abgedeckt, einschließlich benutzerdefinierter Objekte.
|
||||
|
||||
## Webhook erstellen
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Fehlerbehebung
|
||||
icon: wrench
|
||||
icon: Schraubenschlüssel
|
||||
---
|
||||
|
||||
## Fehlerbehebung
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ export const MyComponent = () => {
|
|||
<Tab title=""Eigenschaften"">
|
||||
|
||||
|
||||
| "Eigenschaften" | Typ | Beschreibung |
|
||||
| --------------- | ----------------- | ------------------------------------------- |
|
||||
| Editor | `BlockNoteEditor` | Instanz oder Konfiguration des Blockeditors |
|
||||
| Props | Typ | Beschreibung |
|
||||
| ------ | ----------------- | ------------------------------------------- |
|
||||
| Editor | `BlockNoteEditor` | Instanz oder Konfiguration des Blockeditors |
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ export const MyComponent = () => {
|
|||
<Tab title=""Eigenschaften"">
|
||||
|
||||
|
||||
| "Eigenschaften" | Typ | Beschreibung |
|
||||
| --------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Klassenname | Zeichenkette | Optionaler Klassenname für zusätzliche Stilierung |
|
||||
| Links | array | Ein Array von Objekten, die jeweils einen Breadcrumb-Link darstellen. Jedes Objekt hat eine `children`-Eigenschaft (den textlichen Inhalt des Links) und eine optionale `href`-Eigenschaft (die URL, zu der navigiert wird, wenn der Link angeklickt wird) |
|
||||
| Props | Typ | Beschreibung |
|
||||
| ----------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Klassenname | Zeichenkette | Optionaler Klassenname für zusätzliche Stilierung |
|
||||
| Links | array | Ein Array von Objekten, die jeweils einen Breadcrumb-Link darstellen. Jedes Objekt hat eine `children`-Eigenschaft (den textlichen Inhalt des Links) und eine optionale `href`-Eigenschaft (die URL, zu der navigiert wird, wenn der Link angeklickt wird) |
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ title: Navigation
|
|||
description: Passen Sie die linke Seitenleiste an die Arbeitsweise Ihres Teams an.
|
||||
---
|
||||
|
||||
Die linke Seitenleiste ist Ihre wichtigste Möglichkeit, sich in Twenty zu bewegen. Sie ist vollständig anpassbar — Sie können sie neu organisieren, damit sie zu Ihrem Workflow passt, ohne eine Einstellungsseite zu öffnen.
|
||||
Die linke Seitenleiste ist Ihre wichtigste Möglichkeit, in Twenty zu navigieren. Sie ist vollständig anpassbar — Sie können sie neu organisieren, damit sie zu Ihrem Workflow passt, ohne eine Einstellungsseite zu öffnen.
|
||||
|
||||
## Einträge neu anordnen
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ Objekte, die Sie nicht verwenden, können aus der Seitenleiste ausgeblendet werd
|
|||
|
||||
## Favoriten
|
||||
|
||||
Heften Sie Ansichten, Datensätze oder Suchvorgänge im Bereich Favoriten oben in der Seitenleiste an, um mit einem Klick darauf zuzugreifen. Favoriten sind persönlich — jeder Nutzer verwaltet seine eigenen.
|
||||
Heften Sie Ansichten, Datensätze oder Suchvorgänge im Bereich Favoriten oben in der Seitenleiste an, um mit einem Klick darauf zuzugreifen. Favoriten sind persönlich — jeder Benutzer verwaltet seine eigenen.
|
||||
|
||||
## Benutzerdefinierte Links
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ const StyledButton = styled.button`
|
|||
`;
|
||||
```
|
||||
|
||||
## Importa
|
||||
## Importazioni
|
||||
|
||||
Use aliases instead of relative paths:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
---
|
||||
title: OAuth
|
||||
icon: chiave
|
||||
description: Authorization code flow with PKCE and client credentials for server-to-server access.
|
||||
description: Flusso del codice di autorizzazione con PKCE e credenziali client per l'accesso da server a server.
|
||||
---
|
||||
|
||||
Twenty implements OAuth 2.0 with authorization code + PKCE for user-facing apps and client credentials for server-to-server access. Clients are registered dynamically via [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — no manual setup in a dashboard.
|
||||
Twenty implementa OAuth 2.0 con codice di autorizzazione + PKCE per le app rivolte agli utenti e credenziali client per l'accesso da server a server. I client vengono registrati dinamicamente tramite [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — nessuna configurazione manuale in una dashboard.
|
||||
|
||||
## When to Use OAuth
|
||||
## Quando utilizzare OAuth
|
||||
|
||||
| Scenario | Auth Method |
|
||||
| --------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| Internal scripts, automation | [API Key](/l/it/developers/extend/api#authentication) |
|
||||
| External app acting on behalf of a user | **OAuth — Authorization Code** |
|
||||
| Server-to-server, no user context | **OAuth — Client Credentials** |
|
||||
| Twenty App with UI extensions | [Apps](/l/it/developers/extend/apps/getting-started) (OAuth is handled automatically) |
|
||||
| Scenario | Metodo di autenticazione |
|
||||
| ------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| Script interni, automazioni | [Chiave API](/l/it/developers/extend/api#authentication) |
|
||||
| App esterna che agisce per conto di un utente | **OAuth — Codice di autorizzazione** |
|
||||
| Da server a server, nessun contesto utente | **OAuth — Credenziali client** |
|
||||
| App Twenty con estensioni dell'interfaccia utente | [App](/l/it/developers/extend/apps/getting-started) (OAuth è gestito automaticamente) |
|
||||
|
||||
## Register a Client
|
||||
## Registrare un client
|
||||
|
||||
Twenty supports **dynamic client registration** per [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). No manual setup needed — register programmatically:
|
||||
Twenty supporta la **registrazione dinamica dei client** secondo [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). Non è necessaria alcuna configurazione manuale — registra a livello di codice:
|
||||
|
||||
```bash
|
||||
POST /oauth/register
|
||||
|
|
@ -31,7 +31,7 @@ Content-Type: application/json
|
|||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Risposta:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -43,23 +43,23 @@ Content-Type: application/json
|
|||
```
|
||||
|
||||
<Warning>
|
||||
Store the `client_secret` securely — it cannot be retrieved later.
|
||||
Conserva `client_secret` in modo sicuro — non potrà essere recuperato in seguito.
|
||||
</Warning>
|
||||
|
||||
## Ambiti
|
||||
|
||||
| Scope | Accesso |
|
||||
| --------- | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `profilo` | Read the authenticated user's profile information |
|
||||
| Ambito | Accesso |
|
||||
| --------- | -------------------------------------------------------------- |
|
||||
| `api` | Accesso completo in lettura/scrittura alle API Core e Metadata |
|
||||
| `profilo` | Legge le informazioni del profilo dell'utente autenticato |
|
||||
|
||||
Request scopes as a space-separated string: `scope=api profile`
|
||||
Richiedi gli ambiti come stringa separata da spazi: `scope=api profile`
|
||||
|
||||
## Authorization Code Flow
|
||||
## Flusso con codice di autorizzazione
|
||||
|
||||
Use this flow when your app acts on behalf of a Twenty user.
|
||||
Usa questo flusso quando la tua app agisce per conto di un utente Twenty.
|
||||
|
||||
### 1. Redirect the user to authorize
|
||||
### 1. Reindirizza l'utente per autorizzare
|
||||
|
||||
```
|
||||
GET /oauth/authorize?
|
||||
|
|
@ -72,29 +72,29 @@ GET /oauth/authorize?
|
|||
code_challenge_method=S256
|
||||
```
|
||||
|
||||
| Parametro | Obbligatorio | Descrizione |
|
||||
| ----------------------- | ------------ | ------------------------------------------------------------ |
|
||||
| `client_id` | Sì | Your registered client ID |
|
||||
| `response_type` | Sì | Must be `code` |
|
||||
| `redirect_uri` | Sì | Must match a registered redirect URI |
|
||||
| `scope` | No | Space-separated scopes (defaults to `api`) |
|
||||
| `stato` | Consigliato | Random string to prevent CSRF attacks |
|
||||
| `code_challenge` | Consigliato | PKCE challenge (SHA-256 hash of verifier, base64url-encoded) |
|
||||
| `code_challenge_method` | Consigliato | Must be `S256` when using PKCE |
|
||||
| Parametro | Obbligatorio | Descrizione |
|
||||
| ----------------------- | ------------ | ------------------------------------------------------------------- |
|
||||
| `client_id` | Sì | ID client registrato |
|
||||
| `response_type` | Sì | Deve essere `code` |
|
||||
| `redirect_uri` | Sì | Deve corrispondere a un URI di reindirizzamento registrato |
|
||||
| `scope` | No | Ambiti separati da spazi (predefinito `api`) |
|
||||
| `stato` | Consigliato | Stringa casuale per prevenire attacchi CSRF |
|
||||
| `code_challenge` | Consigliato | Challenge PKCE (hash SHA-256 del verifier, codificato in base64url) |
|
||||
| `code_challenge_method` | Consigliato | Deve essere `S256` quando si usa PKCE |
|
||||
|
||||
The user sees a consent screen and approves or denies access.
|
||||
L'utente vede una schermata di consenso e approva o nega l'accesso.
|
||||
|
||||
### 2. Handle the callback
|
||||
### 2. Gestisci la callback
|
||||
|
||||
After authorization, Twenty redirects back to your `redirect_uri`:
|
||||
Dopo l'autorizzazione, Twenty reindirizza al tuo `redirect_uri`:
|
||||
|
||||
```
|
||||
https://myapp.com/callback?code=AUTH_CODE&state=random_state_value
|
||||
```
|
||||
|
||||
Verify that `state` matches what you sent.
|
||||
Verifica che `state` corrisponda a quanto inviato.
|
||||
|
||||
### 3. Exchange the code for tokens
|
||||
### 3. Scambia il codice con i token
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -108,7 +108,7 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
code_verifier=YOUR_PKCE_VERIFIER
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Risposta:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -119,14 +119,14 @@ code_verifier=YOUR_PKCE_VERIFIER
|
|||
}
|
||||
```
|
||||
|
||||
### 4. Use the access token
|
||||
### 4. Usa il token di accesso
|
||||
|
||||
```bash
|
||||
GET /rest/companies
|
||||
Authorization: Bearer ACCESS_TOKEN
|
||||
```
|
||||
|
||||
### 5. Refresh when expired
|
||||
### 5. Aggiorna alla scadenza
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -138,9 +138,9 @@ client_id=YOUR_CLIENT_ID&
|
|||
client_secret=YOUR_CLIENT_SECRET
|
||||
```
|
||||
|
||||
## Client Credentials Flow
|
||||
## Flusso delle credenziali del client
|
||||
|
||||
For server-to-server integrations with no user interaction:
|
||||
Per integrazioni da server a server senza interazione dell'utente:
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -152,38 +152,38 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
scope=api
|
||||
```
|
||||
|
||||
The returned token has workspace-level access, not tied to any specific user.
|
||||
Il token restituito ha accesso a livello di spazio di lavoro, non legato a un utente specifico.
|
||||
|
||||
## Server Discovery
|
||||
## Scoperta del server
|
||||
|
||||
Twenty publishes its OAuth configuration at a standard discovery endpoint:
|
||||
Twenty pubblica la propria configurazione OAuth in un endpoint di discovery standard:
|
||||
|
||||
```
|
||||
GET /.well-known/oauth-authorization-server
|
||||
```
|
||||
|
||||
This returns all endpoints, supported grant types, scopes, and capabilities — useful for building generic OAuth clients.
|
||||
Questo restituisce tutti gli endpoint, i tipi di grant supportati, gli ambiti e le funzionalità — utile per creare client OAuth generici.
|
||||
|
||||
## API Endpoints Summary
|
||||
## Riepilogo degli endpoint API
|
||||
|
||||
| Endpoint | Scopo |
|
||||
| ----------------------------------------- | --------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Server metadata discovery |
|
||||
| `/oauth/register` | Dynamic client registration |
|
||||
| `/oauth/authorize` | User authorization |
|
||||
| `/oauth/token` | Token exchange and refresh |
|
||||
| Endpoint | Scopo |
|
||||
| ----------------------------------------- | -------------------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Individuazione dei metadati del server |
|
||||
| `/oauth/register` | Registrazione dinamica dei client |
|
||||
| `/oauth/authorize` | Autorizzazione utente |
|
||||
| `/oauth/token` | Scambio e aggiornamento dei token |
|
||||
|
||||
| Ambiente | URL di base |
|
||||
| ----------------- | ------------------------ |
|
||||
| **Cloud** | `https://api.twenty.com` |
|
||||
| **Auto-ospitato** | `https://{your-domain}` |
|
||||
|
||||
## OAuth vs API Keys
|
||||
## OAuth vs Chiavi API
|
||||
|
||||
| | API Keys | OAuth |
|
||||
| ------------------ | ----------------------- | -------------------------------------- |
|
||||
| **Impostazione** | Generate in Settings | Register a client, implement flow |
|
||||
| **User context** | None (workspace-level) | Specific user's permissions |
|
||||
| **Ideale per** | Scripts, internal tools | External apps, multi-user integrations |
|
||||
| **Token rotation** | Manuale | Automatic via refresh tokens |
|
||||
| **Scoped access** | Full API access | Granular via scopes |
|
||||
| | API Keys | OAuth |
|
||||
| ----------------------- | --------------------------------------- | ---------------------------------------- |
|
||||
| **Impostazione** | Genera nelle Impostazioni | Registra un client, implementa il flusso |
|
||||
| **Contesto utente** | Nessuno (a livello di spazio di lavoro) | Autorizzazioni dell'utente specifico |
|
||||
| **Ideale per** | Script, strumenti interni | App esterne, integrazioni multiutente |
|
||||
| **Rotazione dei token** | Manuale | Automatica tramite token di refresh |
|
||||
| **Accesso con ambiti** | Accesso completo alle API | Granulare tramite ambiti |
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: Webhooks
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: Ricevi una notifica quando i record cambiano — HTTP POST al tuo endpoint a ogni creazione, aggiornamento o eliminazione.
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
Twenty invia un HTTP POST al tuo URL ogni volta che un record viene creato, aggiornato o eliminato. Tutti i tipi di oggetto sono supportati, inclusi gli oggetti personalizzati.
|
||||
|
||||
## Crea un Webhook
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ export const MyComponent = () => {
|
|||
<Tab title="Props">
|
||||
|
||||
|
||||
| Props | Tipo | Descrizione |
|
||||
| ------ | ----------------- | ---------------------------------------------------- |
|
||||
| editor | `BlockNoteEditor` | L'istanza o la configurazione dell'editor di blocchi |
|
||||
| Proprietà | Tipo | Descrizione |
|
||||
| --------- | ----------------- | ---------------------------------------------------- |
|
||||
| editor | `BlockNoteEditor` | L'istanza o la configurazione dell'editor di blocchi |
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ const value = process.env.MY_VALUE ?? 'default';
|
|||
onClick?.();
|
||||
```
|
||||
|
||||
## Nomeação
|
||||
## Nomenclatura
|
||||
|
||||
* **Variables**: camelCase, descriptive (`email` not `value`, `fieldMetadata` not `fm`)
|
||||
* **Constants**: SCREAMING_SNAKE_CASE
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: Webhooks
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: Receba notificações quando os registros mudarem — HTTP POST para o seu endpoint a cada criação, atualização ou exclusão.
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
Twenty envia um HTTP POST para sua URL sempre que um registro é criado, atualizado ou excluído. Todos os tipos de objeto estão cobertos, incluindo objetos personalizados.
|
||||
|
||||
## Criar Webhook
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ const value = process.env.MY_VALUE ?? 'default';
|
|||
onClick?.();
|
||||
```
|
||||
|
||||
## Называние
|
||||
## Именование
|
||||
|
||||
* **Variables**: camelCase, descriptive (`email` not `value`, `fieldMetadata` not `fm`)
|
||||
* **Constants**: SCREAMING_SNAKE_CASE
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: CLI & Testing
|
||||
description: CLI commands, testing setup, public assets, npm packages, remotes, and CI configuration.
|
||||
title: CLI и тестирование
|
||||
description: Команды CLI, настройка тестирования, публичные ресурсы, пакеты npm, удалённые репозитории и конфигурация CI.
|
||||
icon: terminal
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ Store the `client_secret` securely — it cannot be retrieved later.
|
|||
| Scope | Доступ |
|
||||
| --------- | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `профиль` | Read the authenticated user's profile information |
|
||||
| `profile` | Read the authenticated user's profile information |
|
||||
|
||||
Request scopes as a space-separated string: `scope=api profile`
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ GET /oauth/authorize?
|
|||
| `response_type` | Да | Must be `code` |
|
||||
| `redirect_uri` | Да | Must match a registered redirect URI |
|
||||
| `scope` | Нет | Space-separated scopes (defaults to `api`) |
|
||||
| `состояние` | Рекомендуется | Random string to prevent CSRF attacks |
|
||||
| `state` | Рекомендуется | Random string to prevent CSRF attacks |
|
||||
| `code_challenge` | Рекомендуется | PKCE challenge (SHA-256 hash of verifier, base64url-encoded) |
|
||||
| `code_challenge_method` | Рекомендуется | Must be `S256` when using PKCE |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: Вебхуки
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: Получайте уведомления при изменении записей — HTTP POST на вашу конечную точку при каждом создании, обновлении или удалении.
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
Twenty отправляет запрос HTTP POST на ваш URL каждый раз, когда запись создаётся, обновляется или удаляется. Поддерживаются все типы объектов, включая пользовательские объекты.
|
||||
|
||||
## Создать вебхук
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: CLI & Testing
|
||||
description: CLI commands, testing setup, public assets, npm packages, remotes, and CI configuration.
|
||||
title: CLI ve Testler
|
||||
description: CLI komutları, test kurulumu, genel varlıklar, npm paketleri, uzaklar ve CI yapılandırması.
|
||||
icon: terminal
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@ Store the `client_secret` securely — it cannot be retrieved later.
|
|||
|
||||
## Kapsamlar
|
||||
|
||||
| Scope | Erişim |
|
||||
| -------- | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `profil` | Read the authenticated user's profile information |
|
||||
| Scope | Erişim |
|
||||
| --------- | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `profile` | Read the authenticated user's profile information |
|
||||
|
||||
Request scopes as a space-separated string: `scope=api profile`
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ GET /oauth/authorize?
|
|||
| `response_type` | Evet | Must be `code` |
|
||||
| `redirect_uri` | Evet | Must match a registered redirect URI |
|
||||
| `scope` | Hayır | Space-separated scopes (defaults to `api`) |
|
||||
| `durum` | Önerilen | Random string to prevent CSRF attacks |
|
||||
| `state` | Önerilen | Random string to prevent CSRF attacks |
|
||||
| `code_challenge` | Önerilen | PKCE challenge (SHA-256 hash of verifier, base64url-encoded) |
|
||||
| `code_challenge_method` | Önerilen | Must be `S256` when using PKCE |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: Webhook'lar
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: Kayıtlar değiştiğinde bildirim alın — her oluşturma, güncelleme veya silme işleminde uç noktanıza HTTP POST gönderilir.
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
Bir kayıt oluşturulduğunda, güncellendiğinde veya silindiğinde Twenty URL'inize bir HTTP POST gönderir. Özel nesneler dahil tüm nesne türleri kapsanır.
|
||||
|
||||
## Webhook oluştur
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Sorun Giderme
|
||||
icon: wrench
|
||||
icon: anahtar
|
||||
---
|
||||
|
||||
## Sorun Giderme
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: İkonlar
|
||||
icon: i̇konlar
|
||||
icon: ikonlar
|
||||
---
|
||||
|
||||
<Frame>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
---
|
||||
title: OAuth
|
||||
icon: 键
|
||||
description: Authorization code flow with PKCE and client credentials for server-to-server access.
|
||||
description: 采用 PKCE 的授权码流程和用于服务器到服务器访问的客户端凭证。
|
||||
---
|
||||
|
||||
Twenty implements OAuth 2.0 with authorization code + PKCE for user-facing apps and client credentials for server-to-server access. Clients are registered dynamically via [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) — no manual setup in a dashboard.
|
||||
Twenty 对面向用户的应用采用授权码 + PKCE 实现 OAuth 2.0,对服务器到服务器访问采用客户端凭证。 客户端通过 [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) 动态注册——无需在仪表板中手动设置。
|
||||
|
||||
## When to Use OAuth
|
||||
## 何时使用 OAuth
|
||||
|
||||
| 场景 | Auth Method |
|
||||
| --------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| Internal scripts, automation | [API Key](/l/zh/developers/extend/api#authentication) |
|
||||
| External app acting on behalf of a user | **OAuth — Authorization Code** |
|
||||
| Server-to-server, no user context | **OAuth — Client Credentials** |
|
||||
| Twenty App with UI extensions | [Apps](/l/zh/developers/extend/apps/getting-started) (OAuth is handled automatically) |
|
||||
| 场景 | 认证方式 |
|
||||
| ------------------- | ----------------------------------------------------------- |
|
||||
| 内部脚本、自动化 | [API 密钥](/l/zh/developers/extend/api#authentication) |
|
||||
| 代表用户执行操作的外部应用 | **OAuth — 授权码** |
|
||||
| 服务器到服务器,无用户上下文 | **OAuth — 客户端凭证** |
|
||||
| 带有 UI 扩展的 Twenty 应用 | [应用](/l/zh/developers/extend/apps/getting-started) (OAuth 将自动处理) |
|
||||
|
||||
## Register a Client
|
||||
## 注册客户端
|
||||
|
||||
Twenty supports **dynamic client registration** per [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). No manual setup needed — register programmatically:
|
||||
根据 [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591),Twenty 支持**动态客户端注册**。 无需手动设置——以编程方式注册:
|
||||
|
||||
```bash
|
||||
POST /oauth/register
|
||||
|
|
@ -31,7 +31,7 @@ Content-Type: application/json
|
|||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -43,23 +43,23 @@ Content-Type: application/json
|
|||
```
|
||||
|
||||
<Warning>
|
||||
Store the `client_secret` securely — it cannot be retrieved later.
|
||||
安全存储 `client_secret`——之后无法再检索。
|
||||
</Warning>
|
||||
|
||||
## 范围
|
||||
|
||||
| Scope | 访问 |
|
||||
| ------ | ---------------------------------------------------- |
|
||||
| `api` | Full read/write access to the Core and Metadata APIs |
|
||||
| `个人资料` | Read the authenticated user's profile information |
|
||||
| 范围 | 访问 |
|
||||
| ------ | ------------------------------ |
|
||||
| `api` | 对 Core 和 Metadata API 的完全读/写访问 |
|
||||
| `个人资料` | 读取已认证用户的个人资料信息 |
|
||||
|
||||
Request scopes as a space-separated string: `scope=api profile`
|
||||
以空格分隔的字符串请求范围:`scope=api profile`
|
||||
|
||||
## Authorization Code Flow
|
||||
## 授权码流程
|
||||
|
||||
Use this flow when your app acts on behalf of a Twenty user.
|
||||
当你的应用代表某个 Twenty 用户执行操作时,请使用此流程。
|
||||
|
||||
### 1. Redirect the user to authorize
|
||||
### 1. 重定向用户以进行授权
|
||||
|
||||
```
|
||||
GET /oauth/authorize?
|
||||
|
|
@ -72,29 +72,29 @@ GET /oauth/authorize?
|
|||
code_challenge_method=S256
|
||||
```
|
||||
|
||||
| 参数 | 必填 | 描述 |
|
||||
| ----------------------- | -- | ------------------------------------------------------------ |
|
||||
| `client_id` | 是 | Your registered client ID |
|
||||
| `response_type` | 是 | Must be `code` |
|
||||
| `redirect_uri` | 是 | Must match a registered redirect URI |
|
||||
| `scope` | 否 | Space-separated scopes (defaults to `api`) |
|
||||
| `状态` | 推荐 | Random string to prevent CSRF attacks |
|
||||
| `code_challenge` | 推荐 | PKCE challenge (SHA-256 hash of verifier, base64url-encoded) |
|
||||
| `code_challenge_method` | 推荐 | Must be `S256` when using PKCE |
|
||||
| 参数 | 必填 | 描述 |
|
||||
| ----------------------- | -- | ------------------------------------- |
|
||||
| `client_id` | 是 | 你已注册的客户端 ID |
|
||||
| `response_type` | 是 | 必须为 `code` |
|
||||
| `redirect_uri` | 是 | 必须与已注册的重定向 URI 匹配 |
|
||||
| `scope` | 否 | 以空格分隔的范围(默认为 `api`) |
|
||||
| `状态` | 推荐 | 用于防止 CSRF 攻击的随机字符串 |
|
||||
| `code_challenge` | 推荐 | PKCE 质询(验证器的 SHA-256 哈希,base64url 编码) |
|
||||
| `code_challenge_method` | 推荐 | 使用 PKCE 时必须为 `S256` |
|
||||
|
||||
The user sees a consent screen and approves or denies access.
|
||||
用户将看到授权同意界面,并同意或拒绝访问。
|
||||
|
||||
### 2. Handle the callback
|
||||
### 2. 处理回调
|
||||
|
||||
After authorization, Twenty redirects back to your `redirect_uri`:
|
||||
授权后,Twenty 会重定向回你的 `redirect_uri`:
|
||||
|
||||
```
|
||||
https://myapp.com/callback?code=AUTH_CODE&state=random_state_value
|
||||
```
|
||||
|
||||
Verify that `state` matches what you sent.
|
||||
验证 `state` 与你发送的值一致。
|
||||
|
||||
### 3. Exchange the code for tokens
|
||||
### 3. 将授权码交换为令牌
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -108,7 +108,7 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
code_verifier=YOUR_PKCE_VERIFIER
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -119,14 +119,14 @@ code_verifier=YOUR_PKCE_VERIFIER
|
|||
}
|
||||
```
|
||||
|
||||
### 4. Use the access token
|
||||
### 4. 使用访问令牌
|
||||
|
||||
```bash
|
||||
GET /rest/companies
|
||||
Authorization: Bearer ACCESS_TOKEN
|
||||
```
|
||||
|
||||
### 5. Refresh when expired
|
||||
### 5. 过期时刷新
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -138,9 +138,9 @@ client_id=YOUR_CLIENT_ID&
|
|||
client_secret=YOUR_CLIENT_SECRET
|
||||
```
|
||||
|
||||
## Client Credentials Flow
|
||||
## 客户端凭证流程
|
||||
|
||||
For server-to-server integrations with no user interaction:
|
||||
适用于无用户交互的服务器到服务器集成:
|
||||
|
||||
```bash
|
||||
POST /oauth/token
|
||||
|
|
@ -152,38 +152,38 @@ client_secret=YOUR_CLIENT_SECRET&
|
|||
scope=api
|
||||
```
|
||||
|
||||
The returned token has workspace-level access, not tied to any specific user.
|
||||
返回的令牌具有工作区级访问权限,不绑定到任何特定用户。
|
||||
|
||||
## Server Discovery
|
||||
## 服务器发现
|
||||
|
||||
Twenty publishes its OAuth configuration at a standard discovery endpoint:
|
||||
Twenty 在标准发现端点发布其 OAuth 配置:
|
||||
|
||||
```
|
||||
GET /.well-known/oauth-authorization-server
|
||||
```
|
||||
|
||||
This returns all endpoints, supported grant types, scopes, and capabilities — useful for building generic OAuth clients.
|
||||
这将返回所有端点、支持的授权类型、范围和功能——有助于构建通用的 OAuth 客户端。
|
||||
|
||||
## API Endpoints Summary
|
||||
## API 端点概览
|
||||
|
||||
| 端点 | 目的 |
|
||||
| ----------------------------------------- | --------------------------- |
|
||||
| `/.well-known/oauth-authorization-server` | Server metadata discovery |
|
||||
| `/oauth/register` | Dynamic client registration |
|
||||
| `/oauth/authorize` | User authorization |
|
||||
| `/oauth/token` | Token exchange and refresh |
|
||||
| 端点 | 目的 |
|
||||
| ----------------------------------------- | -------- |
|
||||
| `/.well-known/oauth-authorization-server` | 服务器元数据发现 |
|
||||
| `/oauth/register` | 动态客户端注册 |
|
||||
| `/oauth/authorize` | 用户授权 |
|
||||
| `/oauth/token` | 令牌交换与刷新 |
|
||||
|
||||
| 环境 | 基础 URL |
|
||||
| ------- | ------------------------ |
|
||||
| **云端** | `https://api.twenty.com` |
|
||||
| **自托管** | `https://{your-domain}` |
|
||||
|
||||
## OAuth vs API Keys
|
||||
## OAuth 与 API 密钥对比
|
||||
|
||||
| | API 密钥 | OAuth |
|
||||
| ------------------ | ----------------------- | -------------------------------------- |
|
||||
| **Setup** | Generate in Settings | Register a client, implement flow |
|
||||
| **User context** | None (workspace-level) | Specific user's permissions |
|
||||
| **Best for** | Scripts, internal tools | External apps, multi-user integrations |
|
||||
| **Token rotation** | 手动 | Automatic via refresh tokens |
|
||||
| **Scoped access** | Full API access | Granular via scopes |
|
||||
| | API 密钥 | OAuth |
|
||||
| ----------- | ---------- | ----------- |
|
||||
| **设置** | 在设置中生成 | 注册客户端并实现流程 |
|
||||
| **用户上下文** | 无(工作区级) | 特定用户的权限 |
|
||||
| **最适合** | 脚本、内部工具 | 外部应用、多用户集成 |
|
||||
| **令牌轮换** | 手动 | 通过刷新令牌自动完成 |
|
||||
| **范围限定的访问** | 完整的 API 访问 | 通过范围实现细粒度控制 |
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
title: Webhooks
|
||||
icon: satellite-dish
|
||||
description: Get notified when records change — HTTP POST to your endpoint on every create, update, or delete.
|
||||
description: 当记录更改时收到通知 — 在每次创建、更新或删除时向您的端点发送 HTTP POST。
|
||||
---
|
||||
|
||||
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
|
||||
|
||||
Twenty sends an HTTP POST to your URL whenever a record is created, updated, or deleted. All object types are covered, including custom objects.
|
||||
每当记录被创建、更新或删除时,Twenty 会向您的 URL 发送 HTTP POST。 涵盖所有对象类型,包括自定义对象。
|
||||
|
||||
## 创建 Webhook
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue