Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
24 changes: 24 additions & 0 deletions lib/Organizations.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,28 @@ public function listOrganizationRoles($organizationId)

return [$roles];
}

/**
* Get feature flags for an organization.
*
* @param string $organizationId WorkOS organization ID to fetch feature flags for
*
* @throws Exception\WorkOSException
*
* @return array Feature flags for the organization
*/
public function getFeatureFlags($organizationId)
{
$featureFlagsPath = "organizations/{$organizationId}/feature-flags";

$response = Client::request(
Client::METHOD_GET,
$featureFlagsPath,
null,
null,
true
);

return $response;
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Returns raw response array instead of structured objects like other methods. Consider whether feature flags should have their own Resource class for consistency.

}
}
27 changes: 27 additions & 0 deletions lib/Resource/VaultObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace WorkOS\Resource;

/**
* Class VaultObject.
*/
class VaultObject extends BaseWorkOSResource
{
public const RESOURCE_TYPE = "vault_object";

public const RESOURCE_ATTRIBUTES = [
"id",
"name",
"updatedAt",
"value",
"metadata"
];

public const RESPONSE_TO_RESOURCE_KEY = [
"id" => "id",
"name" => "name",
"updated_at" => "updatedAt",
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Extra whitespace after updatedAt", - consider removing trailing spaces for consistency

Suggested change
"updated_at" => "updatedAt",
"updated_at" => "updatedAt",

"value" => "value",
"metadata" => "metadata"
];
}
78 changes: 78 additions & 0 deletions lib/Vault.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace WorkOS;

/**
* Class Vault.
*
* This class facilitates the use of WorkOS Vault operations.
*/
class Vault
{
public const DEFAULT_PAGE_SIZE = 10;

/**
* Get a Vault Object.
*
* @param string $vaultObjectId The unique identifier for the vault object.
*
* @throws Exception\WorkOSException
*
* @return Resource\VaultObject
*/
public function getVaultObject($vaultObjectId)
{
$vaultObjectPath = "vault/v1/kv/{$vaultObjectId}";

$response = Client::request(Client::METHOD_GET, $vaultObjectPath, null, null, true);

return Resource\VaultObject::constructFromResponse($response);
}

/**
* List Vault Objects.
*
* @param int $limit Maximum number of records to return
* @param null|string $before Vault Object ID to look before
* @param null|string $after Vault Object ID to look after
* @param Resource\Order $order The Order in which to paginate records
*
* @return array{?string, ?string, Resource\VaultObject[]} An array containing the Vault Object ID to use as before and after cursor, and an array of VaultObject instances
*
* @throws Exception\WorkOSException
*/
public function listVaultObjects(
$limit = self::DEFAULT_PAGE_SIZE,
$before = null,
$after = null,
$order = null
) {
$vaultObjectsPath = "vault/v1/kv";
$params = [
"limit" => $limit,
"before" => $before,
"after" => $after,
"order" => $order
];

$response = Client::request(
Client::METHOD_GET,
$vaultObjectsPath,
null,
$params,
true
);

$vaultObjects = [];
list($before, $after) = Util\Request::parsePaginationArgs($response);
foreach ($response["data"] as $responseData) {
\array_push($vaultObjects, Resource\VaultObject::constructFromResponse($responseData));
}

return [$before, $after, $vaultObjects];
}




}
64 changes: 64 additions & 0 deletions tests/WorkOS/OrganizationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ class OrganizationsTest extends TestCase
setUp as protected traitSetUp;
}

/**
* @var Organizations
*/
protected $organizations;

protected function setUp(): void
{
$this->traitSetUp();
Expand Down Expand Up @@ -190,6 +195,25 @@ public function testListOrganizationRoles()
$this->assertSame($role, $roles[0]->toArray());
}

public function testGetFeatureFlags()
{
$featureFlagsPath = "organizations/org_01EHQMYV6MBK39QC5PZXHY59C3/feature-flags";

$result = $this->featureFlagsResponseFixture();

$this->mockRequest(
Client::METHOD_GET,
$featureFlagsPath,
null,
null,
true,
$result
);

$response = $this->organizations->getFeatureFlags("org_01EHQMYV6MBK39QC5PZXHY59C3");
$this->assertSame(json_decode($result, true), $response);
}

// Fixtures

private function createOrganizationResponseFixture()
Expand Down Expand Up @@ -342,4 +366,44 @@ private function roleFixture()
"updated_at" => "2024-01-01T00:00:00.000Z"
];
}

private function featureFlagsResponseFixture()
{
return json_encode([
"object" => "list",
"data" => [
[
"object" => "feature_flag",
"id" => "flag_01K2QR5YSWRB8J7GGAG05Y24HQ",
"slug" => "flag3",
"name" => "Flag3",
"description" => "",
"created_at" => "2025-08-15T20:54:13.561Z",
"updated_at" => "2025-08-15T20:54:13.561Z"
],
[
"object" => "feature_flag",
"id" => "flag_01K2QR5HGK2HQVFDZ4T60GWGVD",
"slug" => "flag2",
"name" => "Flag2",
"description" => "",
"created_at" => "2025-08-15T20:53:59.952Z",
"updated_at" => "2025-08-15T20:53:59.952Z"
],
[
"object" => "feature_flag",
"id" => "flag_01K2QKSH38RF4P9FV917PE24R3",
"slug" => "flag1",
"name" => "Flag1",
"description" => "",
"created_at" => "2025-08-15T19:37:32.005Z",
"updated_at" => "2025-08-15T19:37:32.005Z"
],
],
"list_metadata" => [
"before" => "",
"after" => ""
]
]);
}
}
139 changes: 139 additions & 0 deletions tests/WorkOS/VaultTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php

namespace WorkOS;

use PHPUnit\Framework\TestCase;

class VaultTest extends TestCase
{
use TestHelper {
setUp as protected traitSetUp;
}

/**
* @var Vault
*/
protected $vault;

protected function setUp(): void
{
$this->traitSetUp();

$this->withApiKey();
$this->vault = new Vault();
}

public function testGetVaultObject()
{
$vaultObjectPath = "vault/v1/kv/vault_obj_01EHQMYV6MBK39QC5PZXHY59C3";

$result = $this->vaultObjectResponseFixture();

$this->mockRequest(
Client::METHOD_GET,
$vaultObjectPath,
null,
null,
true,
$result
);

$vaultObject = $this->vaultObjectFixture();

$response = $this->vault->getVaultObject("vault_obj_01EHQMYV6MBK39QC5PZXHY59C3");
$this->assertSame($vaultObject, $response->toArray());
}

public function testListVaultObjects()
{
$vaultObjectsPath = "vault/v1/kv";

$result = $this->vaultObjectsResponseFixture();

$params = [
"limit" => 10,
"before" => null,
"after" => null,
"order" => null
];

$this->mockRequest(
Client::METHOD_GET,
$vaultObjectsPath,
null,
$params,
true,
$result
);

$vaultObjects = $this->vaultObjectsFixture();

list($before, $after, $response) = $this->vault->listVaultObjects();
$this->assertSame($vaultObjects, $response[0]->toArray());
Comment on lines +71 to +72
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Inconsistent test logic - comparing single fixture object against first item in array. Should either compare arrays or single objects consistently.

}







// Fixtures

private function vaultObjectResponseFixture()
{
return json_encode([
"id" => "vault_obj_01EHQMYV6MBK39QC5PZXHY59C3",
"name" => "Test Vault Object",
"updated_at" => "2024-01-01T00:00:00.000Z",
"value" => null,
"metadata" => []
]);
}

private function vaultObjectFixture()
{
return [
"id" => "vault_obj_01EHQMYV6MBK39QC5PZXHY59C3",
"name" => "Test Vault Object",
"updatedAt" => "2024-01-01T00:00:00.000Z",
"value" => null,
"metadata" => []
];
}

private function vaultObjectsResponseFixture()
{
return json_encode([
"object" => "list",
"data" => [
[
"id" => "vault_obj_01EHQMYV6MBK39QC5PZXHY59C3",
"name" => "Test Vault Object",
"updated_at" => "2024-01-01T00:00:00.000Z",
"value" => null,
"metadata" => []
]
],
"list_metadata" => [
"before" => null,
"after" => null
]
]);
}

private function vaultObjectsFixture()
{
return [
"id" => "vault_obj_01EHQMYV6MBK39QC5PZXHY59C3",
"name" => "Test Vault Object",
"updatedAt" => "2024-01-01T00:00:00.000Z",
"value" => null,
"metadata" => []
];
}




}