@ -128,7 +128,7 @@ Microsoft provider 额外使用 `tenant`(默认值为 `common`),Feishu pro
]
]
```
```
`webClientId` 是 Apple Services ID,供浏览器授权使用;它必须注册对应的 HTTPS Return URL。`nativeClientId` 是签名 App 的 Bundle ID,供 iOS/macOS 原生 Sign in with Apple 使用;它必须与安装包的 Bundle ID 一致。至少配置一组完整凭据:`webClientId` 与 `webClientSecret` 启用浏览器授权,`nativeClientId` 与 `nativeClientSecret` 启用原生授权。仅使用一种模式时可以省略另一组。两个 `clientSecret` 都是服务端凭据,使用 Apple Developer Team、Key ID、私钥和对应 client ID 生成,禁止写入客户端或提交到仓库。
`webClientId` 是 Apple Services ID,供浏览器授权使用;它必须注册对应的 HTTPS Return URL。`nativeClientId` 是签名 App 的 Bundle ID,供 iOS 和 Mac App Store 构建的原生 Sign in with Apple 使用;它必须与安装包的 Bundle ID 一致。macOS Developer ID 构建使用浏览器授权流程,因为 Developer ID profile 不携带受限制的原生 Apple entitlement。至少配置一组完整凭据:`webClientId` 与 `webClientSecret` 启用浏览器授权,`nativeClientId` 与 `nativeClientSecret` 启用原生授权。仅使用一种模式时可以省略另一组。两个 `clientSecret` 都是服务端凭据,使用 Apple Developer Team、Key ID、私钥和对应 client ID 生成,禁止写入客户端或提交到仓库。
官方 SyncTV 构建使用 `org.synctv.app`。自托管服务器通常没有官方 Apple Developer Team 的 App ID 私钥和 client secret,因此自托管发行应创建自己的 Apple Developer Team、Bundle ID 和 Sign in with Apple 配置,使用自己的 Bundle ID 重新签名客户端,并将它配置为 `nativeClientId`。
官方 SyncTV 构建使用 `org.synctv.app`。自托管服务器通常没有官方 Apple Developer Team 的 App ID 私钥和 client secret,因此自托管发行应创建自己的 Apple Developer Team、Bundle ID 和 Sign in with Apple 配置,使用自己的 Bundle ID 重新签名客户端,并将它配置为 `nativeClientId`。
@ -158,7 +158,7 @@ Apple 官方配置入口:[Web Sign in with Apple](https://developer.apple.com/
原生授权请求省略 `redirectUrl`,并传入 `native=true`。Apple provider 通过 `supportedModes` 声明原生能力;iOS/macOS 通过系统 Sign in with Apple 返回 authorization code,客户端随后把 code 和 state 交给 SyncTV 服务端交换。服务端会拒绝 provider 未声明的模式。
原生授权请求省略 `redirectUrl`,并传入 `native=true`。Apple provider 通过 `supportedModes` 声明原生能力;iOS 和 Mac App Store 构建通过系统 Sign in with Apple 返回 authorization code,客户端随后把 code 和 state 交给 SyncTV 服务端交换。macOS Developer ID 构建使用浏览器授权流程。服务端会拒绝 provider 未声明的模式。
Apple 原生登录不使用 `/.well-known/apple-app-site-association`。该文件属于 Apple Universal Links、浏览器 OAuth 回调关联和 Passkey 关联。
Apple 原生登录不使用 `/.well-known/apple-app-site-association`。该文件属于 Apple Universal Links、浏览器 OAuth 回调关联和 Passkey 关联。
@ -128,7 +128,7 @@ The Microsoft provider also accepts `tenant` (default `common`). The Feishu prov
]
]
```
```
`webClientId` is an Apple Services ID for browser authorization and must have the HTTPS Return URL registered. `nativeClientId` is the signed app's Bundle ID for native Sign in with Apple on iOS and macOS; it must match the installed app's Bundle ID. Configure at least one complete pair: `webClientId` plus `webClientSecret` enables browser authorization, while `nativeClientId` plus `nativeClientSecret` enables native authorization. The unused pair can be omitted for a single-mode deployment. Both `clientSecret` values are server credentials generated with the Apple Developer Team, Key ID, private key, and corresponding client ID. Keep them on the server and out of the client or repository.
`webClientId` is an Apple Services ID for browser authorization and must have the HTTPS Return URL registered. `nativeClientId` is the signed app's Bundle ID for native Sign in with Apple on iOS and Mac App Store builds; it must match the installed app's Bundle ID. macOS Developer ID builds use browser authorization because Developer ID profiles do not carry the restricted native Apple entitlement. Configure at least one complete pair: `webClientId` plus `webClientSecret` enables browser authorization, while `nativeClientId` plus `nativeClientSecret` enables native authorization. The unused pair can be omitted for a single-mode deployment. Both `clientSecret` values are server credentials generated with the Apple Developer Team, Key ID, private key, and corresponding client ID. Keep them on the server and out of the client or repository.
The official SyncTV build uses `org.synctv.app`. A self-hosted operator normally does not have the official Apple Developer Team's App ID private key and client secret. A self-hosted Apple distribution should create its own Apple Developer Team, Bundle ID, and Sign in with Apple configuration, sign a client with that Bundle ID, and configure the same value as `nativeClientId`.
The official SyncTV build uses `org.synctv.app`. A self-hosted operator normally does not have the official Apple Developer Team's App ID private key and client secret. A self-hosted Apple distribution should create its own Apple Developer Team, Bundle ID, and Sign in with Apple configuration, sign a client with that Bundle ID, and configure the same value as `nativeClientId`.
@ -158,7 +158,7 @@ Apple configuration links: [Web Sign in with Apple](https://developer.apple.com/
Browser authorization requests pass `redirectUrl`; the server validates HTTPS callbacks against `oauth2.allowedRedirectUrls`, while loopback callbacks are handled separately. Register the same callback URL with the third-party provider.
Browser authorization requests pass `redirectUrl`; the server validates HTTPS callbacks against `oauth2.allowedRedirectUrls`, while loopback callbacks are handled separately. Register the same callback URL with the third-party provider.
Native authorization requests omit `redirectUrl` and pass `native=true`. The Apple provider advertises native support through `supportedModes`; iOS and macOS use Apple's system Sign in with Apple flow and return an authorization code to the client, which exchanges it with the SyncTV server. The server rejects modes that the provider has not advertised.
Native authorization requests omit `redirectUrl` and pass `native=true`. The Apple provider advertises native support through `supportedModes`; iOS and Mac App Store builds use Apple's system Sign in with Apple flow and return an authorization code to the client, which exchanges it with the SyncTV server. macOS Developer ID builds use browser authorization. The server rejects modes that the provider has not advertised.
Native Apple login does not use `/.well-known/apple-app-site-association`. That document is used for Apple Universal Links, browser OAuth callback association, and passkey association.
Native Apple login does not use `/.well-known/apple-app-site-association`. That document is used for Apple Universal Links, browser OAuth callback association, and passkey association.
@ -226,9 +226,9 @@ Then call login with `email` and `email_token`. Do not mix email-login tokens wi
OAuth2/OIDC is frontend-driven:
OAuth2/OIDC is frontend-driven:
<Steps>
<Steps>
1. Call `GET /api/oauth2/providers` to discover provider instances, `signupEnabled`, `signupNeedReview`, and `supportedModes`. iOS/macOS prefers an Apple instance supporting both `browser` and `native`; other platforms use `browser`, and unsupported instances stay hidden.
1. Call `GET /api/oauth2/providers` to discover provider instances, `signupEnabled`, `signupNeedReview`, and `supportedModes`. iOS and Mac App Store builds prefer an Apple instance supporting both `browser` and `native`; macOS Developer ID, Windows, Linux, and other platforms use `browser`, and unsupported instances stay hidden.
2. For browser authorization, call `GET /api/oauth2/{provider}/authorize?redirectUrl=<callback>` to get the provider authorization URL and state; `authorizationUrl` is present in this response. For native Apple authorization, call `GET /api/oauth2/{provider}/authorize?native=true` and omit `redirectUrl`; native responses omit `authorizationUrl` and the client uses Apple's system Sign in with Apple flow directly.
2. For browser authorization, call `GET /api/oauth2/{provider}/authorize?redirectUrl=<callback>` to get the provider authorization URL and state; `authorizationUrl` is present in this response. For native Apple authorization, call `GET /api/oauth2/{provider}/authorize?native=true` and omit `redirectUrl`; native responses omit `authorizationUrl` and the client uses Apple's system Sign in with Apple flow directly.
3. Browser authorization redirects the user to the provider, which returns `code` and `state` to the client callback. Native Apple authorization uses Sign in with Apple on iOS/macOS and returns `code` and `state` through the platform API. Use the `nonce` returned by the native authorize response as the server-side nonce input: hash it with SHA-256 and set the Apple request nonce to the lowercase hexadecimal digest. Preserve the returned `state` and send it with the code during exchange.
3. Browser authorization redirects the user to the provider, which returns `code` and `state` to the client callback. Native Apple authorization uses Sign in with Apple on iOS and Mac App Store builds and returns `code` and `state` through the platform API. Use the `nonce` returned by the native authorize response as the server-side nonce input: hash it with SHA-256 and set the Apple request nonce to the lowercase hexadecimal digest. Preserve the returned `state` and send it with the code during exchange.
4. Call `POST /api/oauth2/{provider}/exchange`.
4. Call `POST /api/oauth2/{provider}/exchange`.
5. If the response has `registrationReviewRequired=true`, show pending-review state and keep `registrationReviewId`; do not treat it as logged in.
5. If the response has `registrationReviewRequired=true`, show pending-review state and keep `registrationReviewId`; do not treat it as logged in.
6. If the response contains tokens, store the SyncTV access and refresh tokens.
6. If the response contains tokens, store the SyncTV access and refresh tokens.
Apple browser authorization uses a Services ID and accepts only registered HTTPS Return URLs. Clients pass a request-level `redirectUrl`; the server validates it against `oauth2.allowedRedirectUrls`. macOS and iOS clients receive this HTTPS callback through `ASWebAuthenticationSession`.
Apple browser authorization uses a Services ID and accepts only registered HTTPS Return URLs. Clients pass a request-level `redirectUrl`; the server validates it against `oauth2.allowedRedirectUrls`. macOS and iOS clients receive this HTTPS callback through `ASWebAuthenticationSession`.
Apple native authorization uses `native=true` and omits `redirectUrl`; iOS and macOS receive an authorization code from Sign in with Apple. The Apple provider advertises native support through `supportedModes` in `/api/oauth2/providers`. Configure at least one complete credential pair: `webClientId` with `webClientSecret` enables browser authorization, and `nativeClientId` with `nativeClientSecret` enables native authorization. `nativeClientId` must match the signed app's Bundle ID. The official client uses `org.synctv.app`; a self-hosted distribution normally needs its own Apple Developer Team, Bundle ID, signing, and matching `nativeClientSecret`. See [Email and OAuth2](../../configuration/email-oauth2/).
Apple native authorization uses `native=true` and omits `redirectUrl`; iOS and Mac App Store builds receive an authorization code from Sign in with Apple. macOS Developer ID builds use browser authorization because Developer ID profiles do not carry the restricted native Apple entitlement. The Apple provider advertises native support through `supportedModes` in `/api/oauth2/providers`. Configure at least one complete credential pair: `webClientId` with `webClientSecret` enables browser authorization, and `nativeClientId` with `nativeClientSecret` enables native authorization. `nativeClientId` must match the signed app's Bundle ID. The official client uses `org.synctv.app`; a self-hosted distribution normally needs its own Apple Developer Team, Bundle ID, signing, and matching `nativeClientSecret`. See [Email and OAuth2](../../configuration/email-oauth2/).
Native Apple OAuth does not depend on `/.well-known/apple-app-site-association`. That document serves Universal Links, browser OAuth callback association, and passkeys.
Native Apple OAuth does not depend on `/.well-known/apple-app-site-association`. That document serves Universal Links, browser OAuth callback association, and passkeys.
Apple 原生授权使用 `native=true`,省略 `redirectUrl`,由 iOS/macOS 的 Sign in with Apple 返回 authorization code。Apple provider 通过 `/api/oauth2/providers` 的 `supportedModes` 声明原生能力。至少配置一组完整凭据:`webClientId` 与 `webClientSecret` 启用浏览器授权,`nativeClientId` 与 `nativeClientSecret` 启用原生授权。`nativeClientId` 必须匹配签名 App 的 Bundle ID。官方客户端使用 `org.synctv.app`;自托管发行通常需要自有 Apple Developer Team、Bundle ID、签名和对应的 `nativeClientSecret`,详见 [邮件与 OAuth2](../../configuration/email-oauth2/)。
Apple 原生授权使用 `native=true`,省略 `redirectUrl`,由 iOS 和 Mac App Store 构建的 Sign in with Apple 返回 authorization code。macOS Developer ID 构建使用 Apple 浏览器授权流程,因为 Developer ID profile 不携带受限制的原生 Apple entitlement。Apple provider 通过 `/api/oauth2/providers` 的 `supportedModes` 声明原生能力。至少配置一组完整凭据:`webClientId` 与 `webClientSecret` 启用浏览器授权,`nativeClientId` 与 `nativeClientSecret` 启用原生授权。`nativeClientId` 必须匹配签名 App 的 Bundle ID。官方客户端使用 `org.synctv.app`;自托管发行通常需要自有 Apple Developer Team、Bundle ID、签名和对应的 `nativeClientSecret`,详见 [邮件与 OAuth2](../../configuration/email-oauth2/)。
原生 Apple OAuth 不依赖 `/.well-known/apple-app-site-association`。该文件用于 Universal Links、浏览器 OAuth 回调关联和 Passkey。
原生 Apple OAuth 不依赖 `/.well-known/apple-app-site-association`。该文件用于 Universal Links、浏览器 OAuth 回调关联和 Passkey。