diff --git a/app/Http/Controllers/Auth/TikTokController.php b/app/Http/Controllers/Auth/TikTokController.php index 88b678a57..213398169 100644 --- a/app/Http/Controllers/Auth/TikTokController.php +++ b/app/Http/Controllers/Auth/TikTokController.php @@ -20,14 +20,16 @@ class TikTokController extends SocialController protected SocialPlatform $platform = SocialPlatform::TikTok; - protected array $scopes = [ - 'user.info.basic', - 'user.info.profile', - 'user.info.stats', - 'video.publish', - 'video.upload', - 'video.list', - ]; + /** + * Requested scopes come from config so self-hosters whose TikTok app lacks + * a product (Display API is no longer offered to new apps, taking + * user.info.profile/stats and video.list with it) can trim the list via + * TIKTOK_SCOPES instead of hitting a "scope" error on the consent screen. + */ + private function scopes(): array + { + return (array) config('trypost.platforms.tiktok.scopes'); + } public function connect(Request $request): Response { @@ -37,7 +39,7 @@ public function connect(Request $request): Response $this->authorize('manageAccounts', $workspace); - return $this->redirectToProvider($request, $this->driver, $this->scopes); + return $this->redirectToProvider($request, $this->driver, $this->scopes()); } public function callback(Request $request): InertiaResponse @@ -46,7 +48,7 @@ public function callback(Request $request): InertiaResponse try { $socialUser = Socialite::driver($this->driver) - ->scopes($this->scopes) + ->scopes($this->scopes()) ->user(); // TikTok returns username via getNickname() when user.info.profile scope is included diff --git a/config/trypost.php b/config/trypost.php index f9d038e4d..ed7277686 100644 --- a/config/trypost.php +++ b/config/trypost.php @@ -175,6 +175,10 @@ 'tiktok' => [ 'enabled' => env('TIKTOK_ENABLED', true), 'api' => env('TIKTOK_API', 'https://open.tiktokapis.com/v2'), + // OAuth scopes to request. Trim when the TikTok app lacks a product + // (e.g. no Display API => drop user.info.profile, user.info.stats, + // video.list; analytics degrade gracefully, username stays empty). + 'scopes' => array_values(array_filter(array_map('trim', explode(',', (string) env('TIKTOK_SCOPES', 'user.info.basic,user.info.profile,user.info.stats,video.publish,video.upload,video.list'))))), ], 'youtube' => [ 'enabled' => env('YOUTUBE_ENABLED', true),