Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Canva Extension Helper Laravel Package

cedricziel/canva-extension-helper

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require cedricziel/canva-extension-helper
    
  2. Basic Controller Structure (for a Publish extension):

    use Canva\HttpHelper;
    use Canva\Publish\UploadRequest;
    use Canva\Request as CanvaRequest;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class PublishController {
        private string $canvaSecret;
    
        public function __construct(string $canvaSecret) {
            $this->canvaSecret = $canvaSecret;
        }
    
        public function upload(Request $request): Response {
            $timestamp = $request->headers->get(CanvaRequest::HEADER_TIMESTAMP);
            if (!HttpHelper::verifyTimestamp($timestamp, time())) {
                throw new \RuntimeException('Invalid timestamp');
            }
    
            $signature = HttpHelper::calculatePostSignature(
                $timestamp,
                '/publish/resources/upload',
                $request->getContent(),
                $this->canvaSecret
            );
    
            if (!in_array($signature, explode(',', $request->headers->get(CanvaRequest::HEADER_SIGNATURES)))) {
                throw new \RuntimeException('Invalid signature');
            }
    
            $uploadRequest = $request->getContent();
            // Process $uploadRequest (e.g., deserialize with Symfony Serializer)
            return new Response('Success');
        }
    }
    
  3. First Use Case:

    • Handle a /publish/resources/upload request by validating Canva’s signature and timestamp.
    • Deserialize the request body into UploadRequest using Symfony’s SerializerInterface.
    • Process uploaded assets (e.g., store files, validate formats).

Implementation Patterns

Workflows

  1. Request Validation Middleware: Use Canva\Middleware\PostHMACMiddleware and Canva\MiddlewareTimestampMiddleware for automatic validation:

    $app->mount('/canva', $app->make(CanvaMiddleware::class));
    
  2. Serialization: Configure Symfony’s SerializerInterface to handle Canva\Publish\* request/response classes:

    $serializer = new Serializer([
        new ObjectNormalizer(null, null, null, new PropertyInfoExtractor(
            [],
            [new PhpDocExtractor(), new ReflectionExtractor()]
        )),
    ], [new JsonEncoder()]);
    
  3. Extension Types:

    • Publish: Handle UploadRequest, GetResourceRequest, etc.
    • Design: Use Canva\Design\* classes for design-specific logic.
    • Custom: Extend existing models or create new ones implementing Canva\RequestInterface.
  4. Error Handling: Return Canva\ErrorResponse with standardized error codes (e.g., Error::CODE_INVALID_REQUEST).

Integration Tips

  • Routing: Map Canva endpoints to Laravel routes with middleware:
    Route::post('/canva/publish/upload', [PublishController::class, 'upload'])
         ->middleware([CanvaMiddleware::class]);
    
  • Testing: Mock CanvaRequest and HttpHelper for unit tests:
    $request = new Request([], [], [], [], [], [
        'HTTP_X_CANVA_TIMESTAMP' => time(),
        'HTTP_X_CANVA_SIGNATURES' => 'valid_signature',
    ]);
    
  • Logging: Log validation failures for debugging:
    if (!$timestampValid) {
        \Log::warning('Canva timestamp skew detected', ['local' => time(), 'remote' => $timestamp]);
    }
    

Gotchas and Tips

Pitfalls

  1. Timestamp Skew:

    • Canva rejects requests if the timestamp skew exceeds 300 seconds (default leniency).
    • Fix: Adjust HttpHelper::verifyTimestamp() leniency if your server clock drifts:
      HttpHelper::verifyTimestamp($remoteTs, time(), 600); // 10-minute window
      
  2. Signature Mismatches:

    • Common Causes:
      • Incorrect $canvaSecret (verify in services.yaml/config/services.php).
      • Missing or malformed X-Canva-Signatures header.
      • Request body modified after signature calculation.
    • Debug: Log the calculated vs. received signatures:
      $calculated = HttpHelper::calculatePostSignature(...);
      \Log::debug('Signature mismatch', ['calculated' => $calculated, 'received' => $receivedSignatures]);
      
  3. Serialization Issues:

    • Problem: UploadRequest fails to deserialize if assets array is malformed.
    • Fix: Use a custom normalizer or validate the payload first:
      $data = json_decode($request->getContent(), true);
      if (empty($data['assets'])) {
          throw new \InvalidArgumentException('Missing assets');
      }
      
  4. Middleware Order:

    • Critical: Place PostHMACMiddleware after TimestampMiddleware to avoid signature checks on invalid timestamps.

Tips

  1. Reuse Models: Extend Canva\RequestInterface for custom requests:

    class MyCustomRequest implements RequestInterface {
        private string $customField;
        // ...
    }
    
  2. Performance:

    • Cache deserialized requests if processing is expensive:
      $cacheKey = md5($request->getContent());
      $requestData = Cache::remember($cacheKey, 300, fn() => $serializer->deserialize(...));
      
  3. Testing:

    • Use Canva\HttpHelper directly to generate test signatures:
      $testSignature = HttpHelper::calculatePostSignature(time(), '/test', '{}', 'secret');
      
    • Mock HttpClientInterface for upload/download tests.
  4. Configuration:

    • Store $canvaSecret in Laravel’s .env:
      CANVA_SECRET=your_secret_here
      
    • Bind it in AppServiceProvider:
      $this->app->bind(PublishController::class, fn() => new PublishController(config('services.canva.secret')));
      
  5. Extensions Beyond Publish:

    • For Design extensions, use Canva\Design\* classes (e.g., DesignRequest).
    • For Custom extensions, replicate the pattern: define request/response DTOs and validate signatures.
  6. Deprecation:

    • The package is unmaintained (last release: 2021). Fork or wrap it in a Laravel-specific layer for long-term use.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle