Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
* [#416](https://github.com/workos/workos-php/pull/416) fix(generated): regenerate from spec

**Features**
* **[user_management](https://workos.com/docs/reference/authkit/user)**:
* Added model `UserRoleAssignmentSource`
* Added `source` to `UserRoleAssignment`
* Added enum `UserRoleAssignmentSourceType`
* Added parameter `UserManagementAuthentication.authorize.max_age`
* Added endpoint `GET /user_management/cors_origins`
* Added endpoint `GET /user_management/redirect_uris`

**Fixes**
* Restore mistakenly removed CreateMagicAuth logic from previous release
2 changes: 1 addition & 1 deletion .last-synced-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4b4e0618779460dbebc1cf5e0f02197c21796d1f
23faa38318d596e581656934ed72c4a18476d742
1 change: 0 additions & 1 deletion .oagen-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"version": 2,
"language": "php",
"generatedAt": "2026-07-02T17:29:52.899Z",
"files": [
"lib/Resource/ActionAuthenticationDenied.php",
"lib/Resource/ActionAuthenticationDeniedData.php",
Expand Down
32 changes: 32 additions & 0 deletions lib/Resource/MagicAuthSendMagicAuthCodeAndReturnResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@
use JsonSerializableTrait;

public function __construct(
/** Distinguishes the Magic Auth object. */
public string $object,
/** The unique ID of the Magic Auth code. */
public string $id,
/** The unique ID of the user. */
public string $userId,
/** The email address of the user. */
public string $email,
/** The timestamp when the Magic Auth code expires. */
public \DateTimeImmutable $expiresAt,
/** An ISO 8601 timestamp. */
public \DateTimeImmutable $createdAt,
/** An ISO 8601 timestamp. */
public \DateTimeImmutable $updatedAt,
/** The code used to verify the Magic Auth code. */
public string $code,
/** The ID of the Radar authentication attempt created for this request when Radar is enabled. Pass this value to the authenticate endpoint to associate the subsequent authentication with this Radar attempt. */
public ?string $radarAuthAttemptId = null,
) {
Expand All @@ -19,13 +35,29 @@ public function __construct(
public static function fromArray(array $data): self
{
return new self(
object: $data['object'] ?? 'magic_auth',
id: $data['id'],
userId: $data['user_id'],
email: $data['email'],
expiresAt: new \DateTimeImmutable($data['expires_at']),
createdAt: new \DateTimeImmutable($data['created_at']),
updatedAt: new \DateTimeImmutable($data['updated_at']),
code: $data['code'],
radarAuthAttemptId: $data['radar_auth_attempt_id'] ?? null,
);
}

public function toArray(): array
{
return [
'object' => $this->object,
'id' => $this->id,
'user_id' => $this->userId,
'email' => $this->email,
'expires_at' => $this->expiresAt->format(\DateTimeInterface::RFC3339_EXTENDED),
'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED),
'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED),
'code' => $this->code,
'radar_auth_attempt_id' => $this->radarAuthAttemptId,
];
}
Expand Down
59 changes: 59 additions & 0 deletions lib/Resource/UserCreateResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,37 @@
use JsonSerializableTrait;

public function __construct(
/** Distinguishes the user object. */
public string $object,
/** The unique ID of the user. */
public string $id,
/** The first name of the user. */
public ?string $firstName,
/** The last name of the user. */
public ?string $lastName,
/** A URL reference to an image representing the user. */
public ?string $profilePictureUrl,
/** The email address of the user. */
public string $email,
/** Whether the user's email has been verified. */
public bool $emailVerified,
/** The external ID of the user. */
public ?string $externalId,
/** The timestamp when the user last signed in. */
public ?\DateTimeImmutable $lastSignInAt,
/** An ISO 8601 timestamp. */
public \DateTimeImmutable $createdAt,
/** An ISO 8601 timestamp. */
public \DateTimeImmutable $updatedAt,
/** The user's full name. */
public ?string $name = null,
/**
* Object containing metadata key/value pairs associated with the user.
* @var array<string, string>|null
*/
public ?array $metadata = null,
/** The user's preferred locale. */
public ?string $locale = null,
/** The ID of the Radar authentication attempt created for this request when Radar is enabled. Pass this value to the authenticate endpoint to associate the subsequent authentication with this Radar attempt. */
public ?string $radarAuthAttemptId = null,
) {
Expand All @@ -19,13 +50,41 @@ public function __construct(
public static function fromArray(array $data): self
{
return new self(
object: $data['object'] ?? 'user',
id: $data['id'],
firstName: $data['first_name'] ?? null,
lastName: $data['last_name'] ?? null,
profilePictureUrl: $data['profile_picture_url'] ?? null,
email: $data['email'],
emailVerified: $data['email_verified'],
externalId: $data['external_id'] ?? null,
lastSignInAt: isset($data['last_sign_in_at']) ? new \DateTimeImmutable($data['last_sign_in_at']) : null,
createdAt: new \DateTimeImmutable($data['created_at']),
updatedAt: new \DateTimeImmutable($data['updated_at']),
name: $data['name'] ?? null,
metadata: $data['metadata'] ?? null,
locale: $data['locale'] ?? null,
radarAuthAttemptId: $data['radar_auth_attempt_id'] ?? null,
);
}

public function toArray(): array
{
return [
'object' => $this->object,
'id' => $this->id,
'first_name' => $this->firstName,
'last_name' => $this->lastName,
'profile_picture_url' => $this->profilePictureUrl,
'email' => $this->email,
'email_verified' => $this->emailVerified,
'external_id' => $this->externalId,
'last_sign_in_at' => $this->lastSignInAt?->format(\DateTimeInterface::RFC3339_EXTENDED),
'created_at' => $this->createdAt->format(\DateTimeInterface::RFC3339_EXTENDED),
'updated_at' => $this->updatedAt->format(\DateTimeInterface::RFC3339_EXTENDED),
'name' => $this->name,
'metadata' => $this->metadata,
'locale' => $this->locale,
'radar_auth_attempt_id' => $this->radarAuthAttemptId,
];
}
Expand Down
95 changes: 95 additions & 0 deletions lib/Service/UserManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public function getJwks(
* @param string|null $ipAddress
* @param string|null $deviceId
* @param string|null $userAgent
* @param string|null $signalsId
* @param string|null $radarAuthAttemptId
* @return \WorkOS\Resource\AuthenticateResponse
* @throws \WorkOS\Exception\WorkOSException
*/
Expand All @@ -76,6 +78,8 @@ public function authenticateWithPassword(
?string $ipAddress = null,
?string $deviceId = null,
?string $userAgent = null,
?string $signalsId = null,
?string $radarAuthAttemptId = null,
?\WorkOS\RequestOptions $options = null,
): \WorkOS\Resource\AuthenticateResponse {
$body = array_filter([
Expand All @@ -86,6 +90,8 @@ public function authenticateWithPassword(
'ip_address' => $ipAddress,
'device_id' => $deviceId,
'user_agent' => $userAgent,
'signals_id' => $signalsId,
'radar_auth_attempt_id' => $radarAuthAttemptId,
], fn ($v) => $v !== null);
$body['client_id'] = $this->client->requireClientId();
$body['client_secret'] = $this->client->requireApiKey();
Expand All @@ -106,6 +112,7 @@ public function authenticateWithPassword(
* @param string|null $ipAddress
* @param string|null $deviceId
* @param string|null $userAgent
* @param string|null $signalsId
* @return \WorkOS\Resource\AuthenticateResponse
* @throws \WorkOS\Exception\WorkOSException
*/
Expand All @@ -116,6 +123,7 @@ public function authenticateWithCode(
?string $ipAddress = null,
?string $deviceId = null,
?string $userAgent = null,
?string $signalsId = null,
?\WorkOS\RequestOptions $options = null,
): \WorkOS\Resource\AuthenticateResponse {
$body = array_filter([
Expand All @@ -126,6 +134,7 @@ public function authenticateWithCode(
'ip_address' => $ipAddress,
'device_id' => $deviceId,
'user_agent' => $userAgent,
'signals_id' => $signalsId,
], fn ($v) => $v !== null);
$body['client_id'] = $this->client->requireClientId();
$body['client_secret'] = $this->client->requireApiKey();
Expand Down Expand Up @@ -183,6 +192,7 @@ public function authenticateWithRefreshToken(
* @param string|null $ipAddress
* @param string|null $deviceId
* @param string|null $userAgent
* @param string|null $radarAuthAttemptId
* @return \WorkOS\Resource\AuthenticateResponse
* @throws \WorkOS\Exception\WorkOSException
*/
Expand All @@ -193,6 +203,7 @@ public function authenticateWithMagicAuth(
?string $ipAddress = null,
?string $deviceId = null,
?string $userAgent = null,
?string $radarAuthAttemptId = null,
?\WorkOS\RequestOptions $options = null,
): \WorkOS\Resource\AuthenticateResponse {
$body = array_filter([
Expand All @@ -203,6 +214,7 @@ public function authenticateWithMagicAuth(
'ip_address' => $ipAddress,
'device_id' => $deviceId,
'user_agent' => $userAgent,
'radar_auth_attempt_id' => $radarAuthAttemptId,
], fn ($v) => $v !== null);
$body['client_id'] = $this->client->requireClientId();
$body['client_secret'] = $this->client->requireApiKey();
Expand Down Expand Up @@ -363,6 +375,89 @@ public function authenticateWithDeviceCode(
return AuthenticateResponse::fromArray($response);
}

/**
* @param string $code
* @param string $radarChallengeId
* @param string $pendingAuthenticationToken
* @param string|null $ipAddress
* @param string|null $deviceId
* @param string|null $userAgent
* @return \WorkOS\Resource\AuthenticateResponse
* @throws \WorkOS\Exception\WorkOSException
*/
public function authenticateWithRadarEmailChallenge(
string $code,
string $radarChallengeId,
string $pendingAuthenticationToken,
?string $ipAddress = null,
?string $deviceId = null,
?string $userAgent = null,
?\WorkOS\RequestOptions $options = null,
): \WorkOS\Resource\AuthenticateResponse {
$body = array_filter([
'grant_type' => 'urn:workos:oauth:grant-type:radar-email-challenge:code',
'code' => $code,
'radar_challenge_id' => $radarChallengeId,
'pending_authentication_token' => $pendingAuthenticationToken,
'ip_address' => $ipAddress,
'device_id' => $deviceId,
'user_agent' => $userAgent,
], fn ($v) => $v !== null);
$body['client_id'] = $this->client->requireClientId();
$body['client_secret'] = $this->client->requireApiKey();

$response = $this->client->request(
method: 'POST',
path: 'user_management/authenticate',
body: $body,
options: $options,
);
return AuthenticateResponse::fromArray($response);
}

/**
* @param string $code
* @param string $verificationId
* @param string $phoneNumber
* @param string $pendingAuthenticationToken
* @param string|null $ipAddress
* @param string|null $deviceId
* @param string|null $userAgent
* @return \WorkOS\Resource\AuthenticateResponse
* @throws \WorkOS\Exception\WorkOSException
*/
public function authenticateWithRadarSmsChallenge(
string $code,
string $verificationId,
string $phoneNumber,
string $pendingAuthenticationToken,
?string $ipAddress = null,
?string $deviceId = null,
?string $userAgent = null,
?\WorkOS\RequestOptions $options = null,
): \WorkOS\Resource\AuthenticateResponse {
$body = array_filter([
'grant_type' => 'urn:workos:oauth:grant-type:radar-sms-challenge:code',
'code' => $code,
'verification_id' => $verificationId,
'phone_number' => $phoneNumber,
'pending_authentication_token' => $pendingAuthenticationToken,
'ip_address' => $ipAddress,
'device_id' => $deviceId,
'user_agent' => $userAgent,
], fn ($v) => $v !== null);
$body['client_id'] = $this->client->requireClientId();
$body['client_secret'] = $this->client->requireApiKey();

$response = $this->client->request(
method: 'POST',
path: 'user_management/authenticate',
body: $body,
options: $options,
);
return AuthenticateResponse::fromArray($response);
}

/**
* Get an authorization URL
*
Expand Down
4 changes: 2 additions & 2 deletions tests/Fixtures/authenticate_response.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"id": "user_01E4ZCR3C56J083X43JQXF3JK5",
"first_name": "Marcelina",
"last_name": "Davis",
"name": "Marcelina Davis",
"profile_picture_url": "https://workoscdn.com/images/v1/123abc",
"email": "marcelina.davis@example.com",
"email_verified": true,
Expand All @@ -14,8 +15,7 @@
"last_sign_in_at": "2025-06-25T19:07:33.155Z",
"locale": "en-US",
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z",
"name": "Marcelina Davis"
"updated_at": "2026-01-15T12:00:00.000Z"
},
"organization_id": "org_01H945H0YD4F97JN9MATX7BYAG",
"authkit_authorization_code": "authkit_authz_code_abc123",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"client_secret": "sk_test_....",
"grant_type": "authorization_code",
"code": "vBqZKaPpsnJlPfXiDqN7b6VTz",
"code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"invitation_token": "inv_tok_01HXYZ123456789ABCDEFGHIJ",
"ip_address": "203.0.113.42",
"device_id": "device_01HXYZ123456789ABCDEFGHIJ",
"user_agent": "Mozilla/5.0",
"code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"invitation_token": "inv_tok_01HXYZ123456789ABCDEFGHIJ",
"signals_id": "01JBS0GN92GC2RJQS4X9DBPQ2A"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"profile",
"email"
],
"oauth_resource": "https://api.example.com/resource",
"application": {
"object": "connect_application",
"id": "conn_app_01HXYZ123456789ABCDEFGHIJ",
Expand All @@ -18,9 +19,6 @@
"email"
],
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z",
"application_type": "m2m",
"organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT"
},
"oauth_resource": "https://api.example.com/resource"
"updated_at": "2026-01-15T12:00:00.000Z"
}
}
4 changes: 1 addition & 3 deletions tests/Fixtures/connect_application.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,5 @@
"email"
],
"created_at": "2026-01-15T12:00:00.000Z",
"updated_at": "2026-01-15T12:00:00.000Z",
"application_type": "m2m",
"organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT"
"updated_at": "2026-01-15T12:00:00.000Z"
}
Loading