trypost/config/trypost.php
Paulo Castellano 770266d36b refactor: centralize media size limits in config + drop Document type
Three things in one move:

1. Centralize per-type size caps in config/trypost.php under media.max_size_mb.
   The MediaType enum now reads from there:

       MediaType::Image->maxSizeInMb()    // 10  (env: MEDIA_IMAGE_MAX_SIZE_MB)
       MediaType::Video->maxSizeInMb()    // 1024 (env: MEDIA_VIDEO_MAX_SIZE_MB)

   Plus convenience helpers maxSizeInBytes() and maxSizeInKb() so callers
   don't have to multiply themselves. StoreAssetRequest now uses
   MediaType::Video->maxSizeInKb() in its 'max:' rule and mimes derived
   from MediaType::{Image,Video}->allowedMimeTypes(). storeChunked
   validation moved to the new StoreChunkedAssetRequest FormRequest
   (also reads from the enum). MediaAttacher uses
   MediaType::Video->maxSizeInBytes() as the streaming-abort threshold
   and enforces the per-type cap after MIME resolution.

2. Drop MediaType::Document. We never accepted PDFs anywhere — the
   StoreAssetRequest mimes list excluded them, the storeChunked
   extension regex excluded them, MediaAttacher excluded them. The only
   places that referenced Document were:
     - Platform::allowedMediaTypes for LinkedIn/LinkedInPage (declared
       but unreachable)
     - HasMedia::getMediaType fallback when MIME wasn't image/video/*
   Both now cleaned up. HasMedia::getMediaType throws
   InvalidArgumentException for unsupported MIMEs instead of silently
   returning a fake 'document' type. Platform::LinkedIn now matches
   every other social platform: [Image, Video].

3. Add MediaType::fromMime($mime): ?self — replaces the inline mime →
   type loop that MediaAttacher used to roll. Returns null for
   unsupported MIMEs (caller decides how to react).

Tests:
- MediaTypeTest rewritten for the new shape (no Document, config-driven
  sizes, fromMime + size-helper coverage).
- PlatformTest no longer asserts Document on LinkedIn.
- HasMediaTest replaces the 'detects document type' case with one that
  asserts the throw on unsupported MIMEs. The 'add media from path'
  test now uses real PNG bytes from the fixture.
- AssetControllerTest chunked tests use real PNG bytes and assert 422
  (FormRequest unprocessable) for malformed Content-Range headers,
  matching the new validation layer.
2026-05-04 14:54:47 -03:00

115 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Self-Hosted Mode
|--------------------------------------------------------------------------
|
| When enabled, the application runs in self-hosted mode which skips
| payment/subscription requirements during onboarding.
|
*/
'self_hosted' => env('SELF_HOSTED', true),
/*
|--------------------------------------------------------------------------
| Media Size Limits
|--------------------------------------------------------------------------
|
| Per-type size caps in megabytes. Single source of truth — direct
| uploads (StoreAssetRequest, AssetController::storeChunked), URL
| fetches (MediaAttacher), and the MediaType enum all read from here.
|
*/
'media' => [
'max_size_mb' => [
'image' => (int) env('MEDIA_IMAGE_MAX_SIZE_MB', 10),
'video' => (int) env('MEDIA_VIDEO_MAX_SIZE_MB', 1024),
],
],
/*
|--------------------------------------------------------------------------
| Google Authentication
|--------------------------------------------------------------------------
|
| Enable or disable "Login with Google" on the login and register pages.
| Disable this if you don't have Google OAuth credentials configured.
|
*/
'google_auth_enabled' => env('GOOGLE_AUTH_ENABLED', false),
/*
|--------------------------------------------------------------------------
| Social Platforms
|--------------------------------------------------------------------------
|
| Configure which social platforms are enabled in the application.
| Set to false to temporarily disable a platform (e.g., when credentials
| are revoked, expired, or pending approval).
|
*/
'platforms' => [
'linkedin' => [
'enabled' => env('LINKEDIN_ENABLED', true),
'api' => env('LINKEDIN_API', 'https://api.linkedin.com'),
],
'linkedin-page' => [
'enabled' => env('LINKEDIN_PAGE_ENABLED', true),
'api' => env('LINKEDIN_PAGE_API', 'https://api.linkedin.com'),
],
'x' => [
'enabled' => env('X_ENABLED', true),
'api' => env('X_API', 'https://api.x.com/2'),
],
'tiktok' => [
'enabled' => env('TIKTOK_ENABLED', true),
'api' => env('TIKTOK_API', 'https://open.tiktokapis.com/v2'),
],
'youtube' => [
'enabled' => env('YOUTUBE_ENABLED', true),
'data_api' => env('YOUTUBE_DATA_API', 'https://www.googleapis.com/youtube/v3'),
'analytics_api' => env('YOUTUBE_ANALYTICS_API', 'https://youtubeanalytics.googleapis.com/v2'),
],
'facebook' => [
'enabled' => env('FACEBOOK_ENABLED', true),
'graph_api' => env('FACEBOOK_GRAPH_API', 'https://graph.facebook.com/v25.0'),
],
'instagram' => [
'enabled' => env('INSTAGRAM_ENABLED', true),
'graph_api' => env('INSTAGRAM_GRAPH_API', 'https://graph.instagram.com/v25.0'),
// graph.instagram.com (no version) is the auth/refresh host.
'auth_api' => env('INSTAGRAM_AUTH_API', 'https://graph.instagram.com'),
],
'instagram-facebook' => [
'enabled' => env('INSTAGRAM_FACEBOOK_ENABLED', true),
'graph_api' => env('INSTAGRAM_FACEBOOK_GRAPH_API', 'https://graph.facebook.com/v25.0'),
],
'threads' => [
'enabled' => env('THREADS_ENABLED', true),
'graph_api' => env('THREADS_GRAPH_API', 'https://graph.threads.net/v1.0'),
// graph.threads.net (no version) is the auth/refresh host.
'auth_api' => env('THREADS_AUTH_API', 'https://graph.threads.net'),
],
'pinterest' => [
'enabled' => env('PINTEREST_ENABLED', true),
'api' => env('PINTEREST_API', 'https://api.pinterest.com/v5'),
],
'bluesky' => [
'enabled' => env('BLUESKY_ENABLED', true),
'public_appview' => env('BLUESKY_PUBLIC_APPVIEW', 'https://public.api.bsky.app'),
],
'mastodon' => [
'enabled' => env('MASTODON_ENABLED', true),
],
],
];