Skip to content

Commit eb759f8

Browse files
authored
feat: Improve support for custom domains with Management SDK (#554)
1 parent 0764d2e commit eb759f8

File tree

4 files changed

+91
-5
lines changed

4 files changed

+91
-5
lines changed

src/API/Management.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public function getHttpClient(
166166
// If no token was provided or available from cache, try to get one.
167167
if ($managementToken === null && $this->configuration->hasClientSecret()) {
168168
$authentication = $authentication ?? new Authentication($this->configuration);
169-
$response = $authentication->clientCredentials(['audience' => $this->configuration->formatDomain() . '/api/v2/']);
169+
$response = $authentication->clientCredentials(['audience' => $this->configuration->formatDomain(true) . '/api/v2/']);
170170

171171
if (HttpResponse::wasSuccessful($response)) {
172172
$response = HttpResponse::decodeContent($response);

src/Configuration/SdkConfiguration.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
* @method SdkConfiguration setClientId(?string $clientId = null)
3333
* @method SdkConfiguration setClientSecret(?string $clientSecret = null)
3434
* @method SdkConfiguration setDomain(?string $domain = null)
35+
* @method SdkConfiguration setCustomDomain(?string $customDomain = null)
3536
* @method SdkConfiguration setEventListenerProvider(?ListenerProviderInterface $eventListenerProvider = null)
3637
* @method SdkConfiguration setHttpClient(?ClientInterface $httpClient = null)
3738
* @method SdkConfiguration setHttpMaxRetries(int $httpMaxRetires = 3)
@@ -73,6 +74,7 @@
7374
* @method string|null getClientId(?\Throwable $exceptionIfNull = null)
7475
* @method string|null getClientSecret(?\Throwable $exceptionIfNull = null)
7576
* @method string|string getDomain(?\Throwable $exceptionIfNull = null)
77+
* @method string|string getCustomDomain(?\Throwable $exceptionIfNull = null)
7678
* @method ListenerProviderInterface|null getEventListenerProvider(?\Throwable $exceptionIfNull = null)
7779
* @method ClientInterface|null getHttpClient(?\Throwable $exceptionIfNull = null)
7880
* @method int getHttpMaxRetries()
@@ -114,6 +116,7 @@
114116
* @method bool hasClientId()
115117
* @method bool hasClientSecret()
116118
* @method bool hasDomain()
119+
* @method bool hasCustomDomain()
117120
* @method bool hasEventListenerProvider()
118121
* @method bool hasHttpClient()
119122
* @method bool hasHttpMaxRetries()
@@ -163,7 +166,8 @@ final class SdkConfiguration implements ConfigurableContract
163166
*
164167
* @param array<mixed>|null $configuration An key-value array matching this constructor's arguments. Overrides any other passed arguments with the same key name.
165168
* @param string|null $strategy Defaults to 'webapp'. Should be assigned either 'api', 'management', or 'webapp' to specify the type of application the SDK is being applied to. Determines what configuration options will be required at initialization.
166-
* @param string|null $domain Auth0 domain for your tenant.
169+
* @param string|null $domain Auth0 domain for your tenant, found in your Auth0 Application settings.
170+
* @param string|null $customDomain If you have configured Auth0 to use a custom domain, configure it here.
167171
* @param string|null $clientId Client ID, found in the Auth0 Application settings.
168172
* @param string|null $redirectUri Authentication callback URI, as defined in your Auth0 Application settings.
169173
* @param string|null $clientSecret Client Secret, found in the Auth0 Application settings.
@@ -209,6 +213,7 @@ public function __construct(
209213
?array $configuration = null,
210214
?string $strategy = 'webapp',
211215
?string $domain = null,
216+
?string $customDomain = null,
212217
?string $clientId = null,
213218
?string $redirectUri = null,
214219
?string $clientSecret = null,
@@ -257,12 +262,31 @@ public function __construct(
257262
$this->validateState();
258263
}
259264

265+
/**
266+
* Return the configured custom or tenant domain, formatted with protocol.
267+
*
268+
* @param bool $forceTenantDomain Force the return of the tenant domain even if a custom domain is configured.
269+
*/
270+
public function formatDomain(
271+
bool $forceTenantDomain = false
272+
): string {
273+
if ($this->hasCustomDomain() && ! $forceTenantDomain) {
274+
return 'https://' . $this->getCustomDomain();
275+
}
276+
277+
return 'https://' . $this->getDomain();
278+
}
279+
260280
/**
261281
* Return the configured domain with protocol.
262282
*/
263-
public function formatDomain(): string
283+
public function formatCustomDomain(): ?string
264284
{
265-
return 'https://' . $this->getDomain();
285+
if ($this->hasCustomDomain()) {
286+
return 'https://' . $this->getCustomDomain();
287+
}
288+
289+
return null;
266290
}
267291

268292
/**

src/Token.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public function validate(
133133
?int $tokenLeeway = null,
134134
?int $tokenNow = null
135135
): self {
136-
$tokenIssuer = $tokenIssuer ?? 'https://' . $this->configuration->getDomain() . '/';
136+
$tokenIssuer = $tokenIssuer ?? $this->configuration->formatDomain() . '/';
137137
$tokenAudience = $tokenAudience ?? $this->configuration->getAudience() ?? [];
138138
$tokenOrganization = $tokenOrganization ?? $this->configuration->getOrganization() ?? null;
139139
$tokenNonce = $tokenNonce ?? null;

tests/Unit/Configuration/SdkConfigurationTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,68 @@
271271
expect($sdk->formatDomain())->toEqual('https://' . $domain);
272272
});
273273

274+
test('formatDomain() returns the custom domain when a custom domain is configured', function(): void
275+
{
276+
$domain = uniqid();
277+
$customDomain = uniqid();
278+
279+
$sdk = new SdkConfiguration([
280+
'domain' => $domain,
281+
'customDomain' => $customDomain,
282+
'cookieSecret' => uniqid(),
283+
'clientId' => uniqid(),
284+
'redirectUri' => uniqid(),
285+
]);
286+
287+
expect($sdk->formatDomain())->toEqual('https://' . $customDomain);
288+
});
289+
290+
test('formatDomain() returns the tenant domain even when a custom domain is configured if `forceTenantDomain` argument is `true`', function(): void
291+
{
292+
$domain = uniqid();
293+
$customDomain = uniqid();
294+
295+
$sdk = new SdkConfiguration([
296+
'domain' => $domain,
297+
'customDomain' => $customDomain,
298+
'cookieSecret' => uniqid(),
299+
'clientId' => uniqid(),
300+
'redirectUri' => uniqid(),
301+
]);
302+
303+
expect($sdk->formatDomain(true))->toEqual('https://' . $domain);
304+
});
305+
306+
test('formatCustomDomain() returns a properly formatted uri', function(): void
307+
{
308+
$domain = uniqid();
309+
$customDomain = uniqid();
310+
311+
$sdk = new SdkConfiguration([
312+
'domain' => $domain,
313+
'customDomain' => $customDomain,
314+
'cookieSecret' => uniqid(),
315+
'clientId' => uniqid(),
316+
'redirectUri' => uniqid(),
317+
]);
318+
319+
expect($sdk->formatCustomDomain())->toEqual('https://' . $customDomain);
320+
});
321+
322+
test('formatCustomDomain() returns null when a custom domain is not configured', function(): void
323+
{
324+
$domain = uniqid();
325+
326+
$sdk = new SdkConfiguration([
327+
'domain' => $domain,
328+
'cookieSecret' => uniqid(),
329+
'clientId' => uniqid(),
330+
'redirectUri' => uniqid(),
331+
]);
332+
333+
expect($sdk->formatCustomDomain())->toBeNull();
334+
});
335+
274336
test('formatScope() returns an empty string when there are no scopes defined', function(): void
275337
{
276338
$sdk = new SdkConfiguration([

0 commit comments

Comments
 (0)