> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# مصادقة OIDC

<Info>
  طُوّرت هذه الميزة بواسطة [yu-i-i/overleaf-cep](https://github.com/yu-i-i/overleaf-cep). نقدّم هنا بعض المستندات لمساعدتك في الإعداد.
</Info>

### الإعداد

داخليًا، تستخدم وحدة OIDC في Overleaf مكتبة [passport-openidconnect](https://github.com/jaredhanson/passport-openidconnect). إذا واجهت مشكلات في إعداد OpenID Connect، فمن المفيد قراءة ملف README الخاص بـ `passport-openidconnect` لتكوين فكرة عن الإعدادات التي تتوقعها.

متغير البيئة `EXTERNAL_AUTH` مطلوب لتفعيل وحدة مصادقة OIDC. يحدد هذا المتغير طرق المصادقة الخارجية المفعّلة. قيمة هذا المتغير عبارة عن قائمة. إذا تضمنت القائمة `oidc`، فسيتم تفعيل مصادقة OIDC.

على سبيل المثال: `EXTERNAL_AUTH=ldap oidc`

عند استخدام طريقة مصادقة OIDC، تتم إعادة توجيه المستخدم إلى موقع المصادقة الخاص بمزوّد الهوية (IdP). إذا نجح مزوّد الهوية في مصادقة المستخدم، يتم البحث في قاعدة بيانات مستخدمي Overleaf عن سجل يحتوي على حقل `thirdPartyIdentifiers` بالبنية التالية:

```text theme={null}
thirdPartyIdentifiers: [
  {
    externalUserId: "...",
    externalData: null,
    providerId: "..."
  }
]
```

يجب أن يطابق `externalUserId` معرّف المستخدم في الملف الشخصي الذي يعيده خادم مزوّد الهوية (راجع متغير البيئة `OVERLEAF_OIDC_USER_ID_FIELD`)، ويجب أن يطابق `providerId` معرّف مزوّد OIDC (راجع `OVERLEAF_OIDC_PROVIDER_ID`).

إذا لم يُعثر على سجل مطابق، يتم البحث في قاعدة البيانات عن مستخدم يطابق عنوان بريده الإلكتروني الأساسي البريد الإلكتروني الموجود في الملف الشخصي للمستخدم لدى مزوّد الهوية:

* إذا عُثر على مثل هذا المستخدم، يتم تحديث الحقل `thirdPartyIdentifiers`.
* إذا لم يُعثر على مستخدم مطابق ولم يكن إنشاء الحسابات الفوري (JIT) معطّلًا، يتم إنشاء مستخدم جديد بعنوان البريد الإلكتروني و`thirdPartyIdentifiers` من الملف الشخصي لدى مزوّد الهوية.

في كلتا الحالتين، يُقال إن المستخدم "مرتبط" بمستخدم OIDC الخارجي. يمكن فك ارتباط المستخدم بمزوّد OIDC من صفحة `/user/settings`.

#### العثور على القيم باستخدام مستند الاكتشاف

ينشر كل مزوّد OpenID (OP) مستند اكتشاف (discovery document) على العنوان `<issuer>/.well-known/openid-configuration`. انسخ القيم منه بدلًا من كتابتها يدويًا؛ فحرف واحد خاطئ يكفي لتعطيل تسجيل الدخول.

<Steps>
  <Step title="اعثر على عنوان URL للاكتشاف">
    يعرضه مزوّد OP على صفحة العميل (المزوّد) الذي أنشأته لـ Overleaf. في Authentik، افتح **Applications > Providers**، واختر المزوّد وابحث عن **OpenID Configuration URL** و**OpenID Configuration Issuer**:

    <Frame caption="Authentik: عنوان URL للاكتشاف والـ issuer الخاص بالمزوّد (نسخة اختبارية)">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-provider.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=e3cb5603d959665472b53e39b58b2775" alt="" width="1280" height="633" data-path="images/on-premises/oidc-authentik-provider.png" />
    </Frame>

    يبدو عنوان URL عادةً كما يلي:

    * Keycloak: `https://keycloak.example.com/realms/<realm>/.well-known/openid-configuration`
    * Authentik: `https://authentik.example.com/application/o/<application-slug>/.well-known/openid-configuration`
  </Step>

  <Step title="اقرأ القيم">
    افتح عنوان URL في المتصفح، أو شغّل على خادم Overleaf:

    ```shell theme={null}
    curl -s https://authentik.example.com/application/o/overleaf/.well-known/openid-configuration \
      | jq '{issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, end_session_endpoint}'
    ```

    تبدو استجابة Authentik كما يلي:

    ```json theme={null}
    {
      "issuer": "https://authentik.example.com/application/o/overleaf/",
      "authorization_endpoint": "https://authentik.example.com/application/o/authorize/",
      "token_endpoint": "https://authentik.example.com/application/o/token/",
      "userinfo_endpoint": "https://authentik.example.com/application/o/userinfo/",
      "end_session_endpoint": "https://authentik.example.com/application/o/overleaf/end-session/"
    }
    ```

    يعرض Authentik هذه العناوين أيضًا في أسفل صفحة المزوّد:

    <Frame caption="Authentik: نقاط النهاية الخاصة بالمزوّد (نسخة اختبارية)">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-endpoints.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=55d130cbbbf27fd11aebafa1ab3f090c" alt="" width="1280" height="633" data-path="images/on-premises/oidc-authentik-endpoints.png" />
    </Frame>
  </Step>

  <Step title="انسخها إلى `variables.env`">
    | الحقل في مستند الاكتشاف | متغير البيئة |
    | - | - |
    | `issuer` | `OVERLEAF_OIDC_ISSUER` |
    | `authorization_endpoint` | `OVERLEAF_OIDC_AUTHORIZATION_URL` |
    | `token_endpoint` | `OVERLEAF_OIDC_TOKEN_URL` |
    | `userinfo_endpoint` | `OVERLEAF_OIDC_USER_INFO_URL` |
    | `end_session_endpoint` | `OVERLEAF_OIDC_LOGOUT_URL` |

    ```dotenv theme={null}
    OVERLEAF_OIDC_ISSUER=https://authentik.example.com/application/o/overleaf/
    OVERLEAF_OIDC_AUTHORIZATION_URL=https://authentik.example.com/application/o/authorize/
    OVERLEAF_OIDC_TOKEN_URL=https://authentik.example.com/application/o/token/
    OVERLEAF_OIDC_USER_INFO_URL=https://authentik.example.com/application/o/userinfo/
    OVERLEAF_OIDC_LOGOUT_URL=https://authentik.example.com/application/o/overleaf/end-session/
    ```
  </Step>

  <Step title="تحقّق من أن Overleaf يستطيع الوصول إلى مزوّد OP">
    يستدعي Overleaf نقطتي النهاية token وuserinfo من داخل الحاوية الخاصة به، لذا يجب أن يكون مزوّد OP قابلًا للوصول من هناك، وليس من متصفحك فقط:

    ```shell theme={null}
    docker exec sharelatex curl -sS -o /dev/null -w "%{http_code}\n" \
      https://authentik.example.com/application/o/overleaf/.well-known/openid-configuration
    ```

    يجب أن يطبع `200`.
  </Step>
</Steps>

<Warning>
  انسخ `issuer` بدقة، بما في ذلك الشرطة المائلة في النهاية. يقارنه Overleaf حرفًا بحرف مع الـ issuer الموجود في رمز ID token؛ وأي اختلاف يؤدي إلى فشل كل تسجيل دخول عبر OIDC مع الرسالة:

  `{"message":{"message":"ID token not issued by expected OpenID provider."}}`

  في Authentik، ينتمي الـ issuer إلى التطبيق (`.../application/o/<application-slug>/`). وهو ليس عنوان خادم Authentik، على الرغم من أن عناوين authorize وtoken وuserinfo مشتركة بين جميع التطبيقات.
</Warning>

#### متغيرات البيئة

يمكن العثور على قيم المتغيرات الخمسة المطلوبة التالية باستخدام نقطة النهاية `.well-known/openid-configuration` الخاصة بمزوّد OpenID لديك (OP)، انظر أعلاه.

* `OVERLEAF_OIDC_ISSUER` <strong>(مطلوب)</strong>
* `OVERLEAF_OIDC_AUTHORIZATION_URL` <strong>(مطلوب)</strong>
* `OVERLEAF_OIDC_TOKEN_URL` <strong>(مطلوب)</strong>
* `OVERLEAF_OIDC_USER_INFO_URL` <strong>(مطلوب)</strong>
* `OVERLEAF_OIDC_LOGOUT_URL` <strong>(مطلوب)</strong>

سيوفّر مسؤول مزوّد OpenID لديك قيم المتغيرين المطلوبين التاليين

* `OVERLEAF_OIDC_CLIENT_ID` <strong>(مطلوب)</strong>
* `OVERLEAF_OIDC_CLIENT_SECRET` <strong>(مطلوب)</strong>
* `OVERLEAF_OIDC_SCOPE`
  * الافتراضي: `openid profile email`
* `OVERLEAF_OIDC_PROVIDER_ID`
  * معرّف اختياري لمزوّد OpenID، والقيمة الافتراضية هي `oidc`.
* `OVERLEAF_OIDC_PROVIDER_NAME`
  * اسم مزوّد OpenID، ويُستخدم في قسم `Linked Accounts` في صفحة `/user/settings`، والقيمة الافتراضية هي `OIDC Provider`.
* `OVERLEAF_OIDC_IDENTITY_SERVICE_NAME`
  * الاسم المعروض لخدمة الهوية، ويُستخدم في صفحة تسجيل الدخول (الافتراضي: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
* `OVERLEAF_OIDC_PROVIDER_DESCRIPTION`
  * وصف مزوّد OpenID، ويُستخدم في قسم `Linked Accounts` (الافتراضي: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
* `OVERLEAF_OIDC_PROVIDER_INFO_LINK`
  * رابط URL لـ `Learn more` في وصف مزوّد OpenID، والافتراضي: لا يوجد رابط `Learn more` في الوصف.
* `OVERLEAF_OIDC_PROVIDER_HIDE_NOT_LINKED`
  * عدم إظهار مزوّد OpenID في صفحة `/user/settings` إذا لم يكن حساب المستخدم مرتبطًا به، والافتراضي `false`.
* `OVERLEAF_OIDC_USER_ID_FIELD`
  * ستستخدم Overleaf قيمة هذه السمة كمعرّف المستخدم الخارجي، والقيمة الافتراضية هي `id`. من القيم المعقولة الأخرى الممكنة `email` و`username` (المقابلة لمطالبة OIDC ‏`preferred_username`).
* `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS`
  * يقيّد إنشاء الحسابات الفوري (JIT) للمستخدمين الذين يصادقون عبر OIDC. إذا عُيّن إلى قائمة أسماء نطاقات مفصولة بفواصل، فلن يُنشأ حساب جديد إلا إذا تطابق نطاق عنوان البريد الإلكتروني للمستخدم مع أحد النطاقات المدرجة. إذا لم يتطابق النطاق، فيجب على المسؤول إنشاء حساب المستخدم يدويًا باستخدام عنوان البريد الإلكتروني لمستخدم OIDC، إما بكلمة مرور عشوائية قوية أو، وهو الأفضل، بدون الحقل `hashedPassword` على الإطلاق. يمكن أن تتضمن أسماء النطاقات حرف بدل `*.` في بدايتها لمطابقة النطاقات الفرعية.
    * مثال: للسماح بإنشاء الحسابات الفوري للمستخدمين ذوي عناوين بريد إلكتروني مثل `name@example.com` و`name@math.example.com`:\
      `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS=example.com, *.example.com`
    * مثال: لتعطيل إنشاء الحسابات الفوري تمامًا:\
      `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS=`
* `OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN`
  * إذا عُيّن إلى `true`، يتم تحديث الحقلين `first_name` و`last_name` للمستخدم عند تسجيل الدخول، ويتم تعطيل نموذج بيانات المستخدم في صفحة `/user/settings`.
* `OVERLEAF_OIDC_IS_ADMIN_FIELD` و`OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`
  * عند تعيين متغيري البيئة كليهما، تقوم عملية تسجيل الدخول بتحديث `user.isAdmin = true` إذا كان الملف الشخصي الذي يعيده مزوّد OpenID يحتوي على السمة المحددة في `OVERLEAF_OIDC_IS_ADMIN_FIELD` وكانت قيمتها إما تطابق `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE` أو مصفوفة تحتوي على `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE` (على سبيل المثال المطالبة `groups`)، وإلا فسيتم تعيين `user.isAdmin` إلى `false`. إذا كانت قيمة `OVERLEAF_OIDC_IS_ADMIN_FIELD` هي `email`، فستُستخدم قيمة السمة `emails[0].value` للتحقق من المطابقة.

رابط إعادة التوجيه الخاص بمزوّد OpenID لديك هو `https://my-overleaf-instance.com/oidc/login/callback`.

<Accordion title="نموذج لملف variables.env">
  ```dotenv title="variables.env" wrap theme={null}
  OVERLEAF_APP_NAME="Our Overleaf Instance"

  ENABLED_LINKED_FILE_TYPES=project_file,project_output_file,url

  # Enables Thumbnail generation using ImageMagick
  ENABLE_CONVERSIONS=true

  # Disables email confirmation requirement
  EMAIL_CONFIRMATION_DISABLED=true

  ## Nginx
  # NGINX_WORKER_PROCESSES=4
  # NGINX_WORKER_CONNECTIONS=768

  ## Set for TLS via nginx-proxy
  # OVERLEAF_BEHIND_PROXY=true
  # OVERLEAF_SECURE_COOKIE=true

  OVERLEAF_SITE_URL=http://my-overleaf-instance.com
  OVERLEAF_NAV_TITLE=Our Overleaf Instance
  # OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
  OVERLEAF_ADMIN_EMAIL=support@example.com

  OVERLEAF_LEFT_FOOTER=[{"text": "Contact your support team", "url": "mailto:support@example.com"}]
  OVERLEAF_RIGHT_FOOTER=[{"text":"Hello, I am on the Right", "url":"https://github.com/yu-i-i/overleaf-cep"}]

  OVERLEAF_EMAIL_FROM_ADDRESS=team@example.com
  OVERLEAF_EMAIL_SMTP_HOST=smtp.example.com
  OVERLEAF_EMAIL_SMTP_PORT=587
  OVERLEAF_EMAIL_SMTP_SECURE=false
  # OVERLEAF_EMAIL_SMTP_USER=
  # OVERLEAF_EMAIL_SMTP_PASS=
  # OVERLEAF_EMAIL_SMTP_NAME=
  OVERLEAF_EMAIL_SMTP_LOGGER=false
  OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH=true
  OVERLEAF_EMAIL_SMTP_IGNORE_TLS=false
  OVERLEAF_CUSTOM_EMAIL_FOOTER=This system is run by department x

  OVERLEAF_PROXY_LEARN=true
  NAV_HIDE_POWERED_BY=true

  #################
  ## OIDC for CE ##
  #################

  EXTERNAL_AUTH=oidc

  OVERLEAF_OIDC_PROVIDER_ID=oidc
  OVERLEAF_OIDC_ISSUER=https://keycloak.provider.com/realms/example
  OVERLEAF_OIDC_AUTHORIZATION_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/auth
  OVERLEAF_OIDC_TOKEN_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/token
  OVERLEAF_OIDC_USER_INFO_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/userinfo
  OVERLEAF_OIDC_LOGOUT_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/logout
  OVERLEAF_OIDC_CLIENT_ID=Overleaf-OIDC
  OVERLEAF_OIDC_CLIENT_SECRET=DoNotUseThisATGgaAcTgCcATgGATTACAagGtTCaGcGTAG
  OVERLEAF_OIDC_IDENTITY_SERVICE_NAME='Log in with Keycloak OIDC Provider'
  OVERLEAF_OIDC_PROVIDER_NAME=OIDC Keycloak Provider
  OVERLEAF_OIDC_PROVIDER_INFO_LINK=https://openid.net
  OVERLEAF_OIDC_IS_ADMIN_FIELD=email
  OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=overleaf.admin@example.com
  OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN=false
  ```
</Accordion>

## دليل خطوة بخطوة: goauthentik

يشرح هذا الدليل إعدادًا تم اختباره مع [goauthentik](https://goauthentik.io/). استبدل `https://overleaf.example.com` بقيمة `OVERLEAF_SITE_URL` الخاصة بك، و`https://authentik.example.com` بعنوان Authentik الخاص بك.

<Steps>
  <Step title="أنشئ المزوّد">
    في Authentik، افتح **Applications > Providers**، وانقر على **New Provider**، واختر **OAuth2/OpenID Provider** ثم انقر على **Next**.

    * **Client Type**: `Confidential`.
    * **Redirect URIs** (ضمن **Protocol settings**): أضف `https://overleaf.example.com/oidc/login/callback` مع وضع المطابقة `Strict`.
    * انسخ **Client ID** و**Client Secret** الآن، إلى `OVERLEAF_OIDC_CLIENT_ID` و`OVERLEAF_OIDC_CLIENT_SECRET`.

    <Frame caption="Authentik: Client ID وClient Secret لمزوّد جديد">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-create.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=f127a92eaf3063714e9af515fe97c263" alt="" width="1120" height="808" data-path="images/on-premises/oidc-authentik-create.png" />
    </Frame>

    <Warning>
      يعرض Authentik سرّ العميل (client secret) فقط أثناء إنشاء المزوّد. لاحقًا لا يوفّر نموذج التعديل إلا **Modify**، الذي يستبدل السرّ بسرّ جديد.
    </Warning>
  </Step>

  <Step title="أنشئ التطبيق">
    افتح **Applications > Applications**، وأنشئ تطبيقًا جديدًا، وامنحه اسمًا وslug، على سبيل المثال `overleaf`، ثم اختر المزوّد. يصبح الـ slug جزءًا من الـ issuer: `https://authentik.example.com/application/o/overleaf/`.
  </Step>

  <Step title="انسخ عناوين URL">
    اتبع قسم [العثور على القيم باستخدام مستند الاكتشاف](#العثور-على-القيم-باستخدام-مستند-الاكتشاف) أعلاه لملء عناوين URL الخمسة.
  </Step>

  <Step title="ربط المسؤولين (اختياري)">
    يرسل Authentik مجموعات المستخدم في المطالبة (claim) `groups`، وهي مصفوفة. لجعل أعضاء مجموعة Authentik `Admins` مسؤولين في Overleaf:

    ```dotenv theme={null}
    OVERLEAF_OIDC_IS_ADMIN_FIELD=groups
    OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=Admins
    ```

    <Warning>
      يتم تحديث علامة المسؤول عند كل تسجيل دخول عبر OIDC. إذا كان الحقل أو القيمة خاطئًا، فسيفقد كل مسؤول يسجّل الدخول عبر OIDC صلاحيات المسؤول، بما في ذلك المسؤول الذي أُنشئ في launchpad. اختبر الربط أولًا بحساب مسؤول ثانٍ.
    </Warning>
  </Step>
</Steps>

<Accordion title="ملف variables.env مُختبَر لـ goauthentik">
  ```dotenv title="variables.env" wrap theme={null}
  EXTERNAL_AUTH=oidc
  OVERLEAF_OIDC_PROVIDER_ID=authentik
  OVERLEAF_OIDC_IDENTITY_SERVICE_NAME=Log in with Authentik
  OVERLEAF_OIDC_ISSUER=https://authentik.example.com/application/o/overleaf/
  OVERLEAF_OIDC_AUTHORIZATION_URL=https://authentik.example.com/application/o/authorize/
  OVERLEAF_OIDC_TOKEN_URL=https://authentik.example.com/application/o/token/
  OVERLEAF_OIDC_USER_INFO_URL=https://authentik.example.com/application/o/userinfo/
  OVERLEAF_OIDC_LOGOUT_URL=https://authentik.example.com/application/o/overleaf/end-session/
  OVERLEAF_OIDC_CLIENT_ID=<Client ID>
  OVERLEAF_OIDC_CLIENT_SECRET=<Client Secret>
  OVERLEAF_OIDC_USER_ID_FIELD=username
  OVERLEAF_OIDC_IS_ADMIN_FIELD=groups
  OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=Admins
  OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN=true
  ```
</Accordion>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.