Skip to content

Conversation

@bradenkeith
Copy link
Contributor

@bradenkeith bradenkeith commented Mar 11, 2025

Description

This PR adds webhook response functionality to handle user registration and authentication actions. The implementation includes:

  • Support for both "Allow" and "Deny" verdicts in webhook responses
  • Support for "user_registration_action_response" and "authentication_action_response"
  • Error message handling for denied verdicts
  • JSON serialization support
  • Validation for:
    • Response types
    • Verdict values
    • Required error messages for deny verdicts

The changes improve webhook response handling by providing a structured way to respond to webhook events.

Example code in a Laravel app:

Route::post('work-os/user-registration-action', function (Request $request) {
    $webhook = (new Webhook)->constructEvent(
        $request->headers->get('WorkOS-Signature'),
        $request->getContent(),
        config('services.workos.webhook_secret'),
        180
    );
    
    //...

    $response = WebhookResponse::create(
        WebhookResponse::USER_REGISTRATION_ACTION,
        config('services.workos.webhook_secret'),
        WebhookResponse::VERDICT_ALLOW,
    );

    return response()->json($response->toArray(), 200, ['Content-Type' => 'application/json']);
});

This also allows the package to calculate the signature on the user's behalf.

Before this PR, this would have been the user's code for the same thing. 👎

Route::post('work-os/user-registration-action', function (Request $request) {
    $webhook = (new Webhook)->constructEvent(
        $request->headers->get('WorkOS-Signature'),
        $request->getContent(),
        config('services.workos.webhook_secret'),
        180
    );
    
    //...

    // Create response payload
    $responsePayload = [
        'timestamp' => time() * 1000, // Convert to milliseconds to match JS Date.now()
        'verdict' => 'Allow',
    ];
    // Create the signed response
    $timestamp = $responsePayload['timestamp'];
    $payloadString = json_encode($responsePayload);
    $signedPayload = $timestamp.'.'.$payloadString;
    $signature = hash_hmac('sha256', $signedPayload, config('services.workos.webhook_secret'), false);

    $response = [
        'object' => 'user_registration_action_response',
        'payload' => $responsePayload,
        'signature' => $signature,
    ];

    return response()->json($response, 200, ['Content-Type' => 'application/json']);
});

Documentation

Does this require changes to the WorkOS Docs? E.g. the API Reference or code snippets need updates.

[] Yes

@bradenkeith bradenkeith requested a review from a team as a code owner March 11, 2025 18:03
@bradenkeith bradenkeith requested a review from nicknisi March 11, 2025 18:03
Copy link
Member

@nicknisi nicknisi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution and tests. This provides a simpler DX for working with webhooks!

@nicknisi nicknisi merged commit bd3e4fb into workos:main Mar 21, 2025
5 checks passed
@bradenkeith bradenkeith deleted the webhook-improvements branch March 24, 2025 20:03
bradenkeith added a commit to bradenkeith/workos-php that referenced this pull request Mar 28, 2025
* Add WebhookResponse class for handling webhook actions and responses

* Refactor WebhookResponse create method and improve validation

* Resolve linting error

---------

Co-authored-by: Braden Keith <bkeith@romegadigital.com>
nicknisi pushed a commit that referenced this pull request Apr 2, 2025
* Improve Webhook and BaseWorkOSResource PHPDoc types

* Enhance Webhook class with improved code style and PHPDoc annotations

* Add accessToken and refreshToken to AuthenticationResponse class

* Update AuthenticationResponse class to include organizationId as nullable, and add accessToken, refreshToken, and impersonator properties

* Enhance OrganizationMembership class with additional PHPDoc properties for improved type documentation

* Add metadata and external id (#268)

And allow to be passed when creating or updating a user or organization.

* Add email standard attribute to DirectoryUser and mark deprecated standard attributes (#261)

* Add function to get organization by external id (#270)

And fix typo in getOrganization docstring

* Add support for creating, getting and updating users with external_id property (#267)

Co-authored-by: Eric Roberts <ericroberts@gmail.com>

* Bump to version 4.22.0. (#269)

* Structured responses to webhook events (#265)

* Add WebhookResponse class for handling webhook actions and responses

* Refactor WebhookResponse create method and improve validation

* Resolve linting error

---------

Co-authored-by: Braden Keith <bkeith@romegadigital.com>

* Update deprecation notices in DirectoryUser class to include version information and improve clarity

* Update deprecation notices in Organizations class to include version information and improve formatting

* Update doc blocks for deprecation notices

* Update tests to expect Role Slug

---------

Co-authored-by: Braden Keith <bkeith@romegadigital.com>
Co-authored-by: Eric Roberts <ericroberts@gmail.com>
Co-authored-by: Matt Dzwonczyk <9063128+mattgd@users.noreply.github.com>
Co-authored-by: Pepe <pgarciag93@gmail.com>
bradenkeith added a commit to bradenkeith/workos-php that referenced this pull request Apr 3, 2025
* Improve Webhook and BaseWorkOSResource PHPDoc types

* Enhance Webhook class with improved code style and PHPDoc annotations

* Add accessToken and refreshToken to AuthenticationResponse class

* Update AuthenticationResponse class to include organizationId as nullable, and add accessToken, refreshToken, and impersonator properties

* Enhance OrganizationMembership class with additional PHPDoc properties for improved type documentation

* Add metadata and external id (workos#268)

And allow to be passed when creating or updating a user or organization.

* Add email standard attribute to DirectoryUser and mark deprecated standard attributes (workos#261)

* Add function to get organization by external id (workos#270)

And fix typo in getOrganization docstring

* Add support for creating, getting and updating users with external_id property (workos#267)

Co-authored-by: Eric Roberts <ericroberts@gmail.com>

* Bump to version 4.22.0. (workos#269)

* Structured responses to webhook events (workos#265)

* Add WebhookResponse class for handling webhook actions and responses

* Refactor WebhookResponse create method and improve validation

* Resolve linting error

---------

Co-authored-by: Braden Keith <bkeith@romegadigital.com>

* Update deprecation notices in DirectoryUser class to include version information and improve clarity

* Update deprecation notices in Organizations class to include version information and improve formatting

* Update doc blocks for deprecation notices

* Update tests to expect Role Slug

---------

Co-authored-by: Braden Keith <bkeith@romegadigital.com>
Co-authored-by: Eric Roberts <ericroberts@gmail.com>
Co-authored-by: Matt Dzwonczyk <9063128+mattgd@users.noreply.github.com>
Co-authored-by: Pepe <pgarciag93@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants