diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index a327b35..0000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-version: 2
-updates:
-
- - package-ecosystem: "composer"
- directory: "/app"
- schedule:
- interval: "daily"
- ignore:
- - dependency-name: "*"
- update-types: ["version-update:semver-major", "version-update:semver-patch"]
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index b2e13fc..0000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# Configuration for probot-stale - https://github.com/probot/stale
-
-# Number of days of inactivity before an Issue or Pull Request becomes stale
-daysUntilStale: 90
-
-# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
-daysUntilClose: 7
-
-# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
-exemptLabels: []
-
-# Set to true to ignore issues with an assignee (defaults to false)
-exemptAssignees: true
-
-# Label to use when marking as stale
-staleLabel: closed:stale
-
-# Comment to post when marking as stale. Set to `false` to disable
-markComment: >
- This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇♂️
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 11d0ed3..7315fab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ vendor
.env
composer.lock
.DS_Store
+app/.php-cs-fixer.cache
diff --git a/app/phpunit.xml.dist b/app/phpunit.xml.dist
deleted file mode 100644
index a52f9a8..0000000
--- a/app/phpunit.xml.dist
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- tests/Unit
-
-
-
-
-
-
-
diff --git a/app/src/Application.php b/app/src/Application.php
index 5b0072c..4525424 100644
--- a/app/src/Application.php
+++ b/app/src/Application.php
@@ -4,7 +4,6 @@
namespace Auth0\Quickstart;
-use Auth0\Quickstart\Contract\QuickstartExample;
use Auth0\SDK\Auth0;
use Auth0\SDK\Configuration\SdkConfiguration;
use Auth0\SDK\Exception\InvalidTokenException;
@@ -16,16 +15,6 @@ final class Application
*/
private SdkConfiguration $configuration;
- /**
- * An instance of the Auth0 SDK.
- */
- private Auth0 $sdk;
-
- /**
- * An instance of our application's template rendering helper class, for sending responses.
- */
- private ApplicationTemplates $templates;
-
/**
* An instance of our application's error handling class, for gracefully reporting exceptions.
*/
@@ -37,16 +26,14 @@ final class Application
private ApplicationRouter $router;
/**
- * An instance of a QuickstartExample class, specified from the AUTH0_USE_EXAMPLE env.
+ * An instance of the Auth0 SDK.
*/
- private ?QuickstartExample $example = null;
+ private Auth0 $sdk;
/**
- * An array of hooks with callback functions for examples to override default behavior.
- *
- * @var array
+ * An instance of our application's template rendering helper class, for sending responses.
*/
- private array $exampleHooks = [];
+ private ApplicationTemplates $templates;
/**
* Setup our Quickstart application.
@@ -54,7 +41,7 @@ final class Application
* @param array $env Auth0 configuration imported from .env file.
*/
public function __construct(
- array $env
+ array $env,
) {
// Configure the SDK using our .env configuration.
$this->setupAuth0($env);
@@ -63,41 +50,6 @@ public function __construct(
$this->templates = new ApplicationTemplates($this);
$this->errorHandler = new ApplicationErrorHandler($this);
$this->router = new ApplicationRouter($this);
- $this->example = null;
- }
-
- /**
- * Configure the Auth0 SDK using the .env configuration.
- *
- * @param array $env Auth0 configuration imported from .env file.
- */
- public function setupAuth0(
- array $env
- ): void {
- // Build our SdkConfiguration.
- $this->configuration = new SdkConfiguration([
- 'domain' => $env['AUTH0_DOMAIN'] ?? null,
- 'clientId' => $env['AUTH0_CLIENT_ID'] ?? null,
- 'clientSecret' => $env['AUTH0_CLIENT_SECRET'] ?? null,
- 'audience' => ($env['AUTH0_AUDIENCE'] ?? null) !== null ? [trim($env['AUTH0_AUDIENCE'])] : null,
- 'organization' => ($env['AUTH0_ORGANIZATION'] ?? null) !== null ? [trim($env['AUTH0_ORGANIZATION'])] : null,
- 'strategy' => SdkConfiguration::STRATEGY_API,
- ]);
-
- // Setup the Auth0 SDK.
- $this->sdk = new Auth0($this->configuration);
- }
-
- /**
- * "Run" our application, responding to end-user requests.
- */
- public function run(): void
- {
- // Intercept exceptions to gracefully report them.
- $this->errorHandler->hook();
-
- // Handle incoming requests through the router.
- $this->router->run();
}
/**
@@ -141,40 +93,80 @@ public function &getRouter(): ApplicationRouter
}
/**
- * Called from the ApplicationRouter when end user loads '/'.
+ * Called from the ApplicationRouter when end user loads '/api'.
+ *
+ * @param ApplicationRouter $router
*/
- public function onIndexRoute(
- ApplicationRouter $router
+ public function onApiRoute(
+ ApplicationRouter $router,
): void {
+ $session = $this->getToken();
+
// Send response to browser.
- $this->templates->render('spa', [
- 'config' => $this->getConfiguration(),
+ $this->templates->render('logged-' . ($session instanceof \Auth0\SDK\Contract\TokenInterface ? 'in' : 'out'), [
+ 'session' => $session,
'router' => $router,
]);
}
/**
- * Called from the ApplicationRouter when end user loads '/api'.
+ * Called from the ApplicationRouter when end user loads an unknown route.
+ *
+ * @param ApplicationRouter $router
*/
- public function onApiRoute(
- ApplicationRouter $router
+ public function onError404(
+ ApplicationRouter $router,
): void {
- $session = $this->getToken();
+ $router->setHttpStatus(404);
+ }
+ /**
+ * Called from the ApplicationRouter when end user loads '/'.
+ *
+ * @param ApplicationRouter $router
+ */
+ public function onIndexRoute(
+ ApplicationRouter $router,
+ ): void {
// Send response to browser.
- $this->templates->render('logged-' . ($session === null ? 'out' : 'in'), [
- 'session' => $session,
+ $this->templates->render('spa', [
+ 'config' => $this->getConfiguration(),
'router' => $router,
]);
}
/**
- * Called from the ApplicationRouter when end user loads an unknown route.
+ * "Run" our application, responding to end-user requests.
*/
- public function onError404(
- ApplicationRouter $router
+ public function run(): void
+ {
+ // Intercept exceptions to gracefully report them.
+ $this->errorHandler->hook();
+
+ // Handle incoming requests through the router.
+ $this->router->run();
+ }
+
+ /**
+ * Configure the Auth0 SDK using the .env configuration.
+ *
+ * @param array $env Auth0 configuration imported from .env file.
+ */
+ public function setupAuth0(
+ array $env,
): void {
- $router->setHttpStatus(404);
+ // Build our SdkConfiguration.
+ $this->configuration = new SdkConfiguration([
+ 'domain' => $env['AUTH0_DOMAIN'] ?? null,
+ 'clientId' => $env['AUTH0_CLIENT_ID'] ?? null,
+ 'clientSecret' => $env['AUTH0_CLIENT_SECRET'] ?? null,
+ 'audience' => ($env['AUTH0_AUDIENCE'] ?? null) !== null ? [trim($env['AUTH0_AUDIENCE'])] : null,
+ 'organization' => ($env['AUTH0_ORGANIZATION'] ?? null) !== null ? [trim($env['AUTH0_ORGANIZATION'])] : null,
+ 'strategy' => SdkConfiguration::STRATEGY_API,
+ ]);
+
+ // Setup the Auth0 SDK.
+ $this->sdk = new Auth0($this->configuration);
}
/**
@@ -188,7 +180,7 @@ private function getToken(): ?\Auth0\SDK\Contract\TokenInterface
$token = $_GET['token'] ?? $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['Authorization'] ?? null;
// If no token was present, abort processing.
- if ($token === null) {
+ if (null === $token) {
return null;
}
@@ -196,7 +188,7 @@ private function getToken(): ?\Auth0\SDK\Contract\TokenInterface
$token = trim($token);
// Remove the 'Bearer ' prefix, if present, in the event we're using an Authorization header that's using it.
- if (substr($token, 0, 7) === 'Bearer ') {
+ if (str_starts_with($token, 'Bearer ')) {
$token = substr($token, 7);
}
diff --git a/app/src/ApplicationErrorHandler.php b/app/src/ApplicationErrorHandler.php
index c972e27..6bcd52c 100644
--- a/app/src/ApplicationErrorHandler.php
+++ b/app/src/ApplicationErrorHandler.php
@@ -7,6 +7,8 @@
use Auth0\SDK\Exception\Auth0Exception;
use Throwable;
+use function array_key_exists;
+
final class ApplicationErrorHandler
{
/**
@@ -20,9 +22,9 @@ final class ApplicationErrorHandler
* @param Application $app An instance of our Quickstart Application.
*/
public function __construct(
- Application &$app
+ Application &$app,
) {
- $this->app = & $app;
+ $this->app = &$app;
}
/**
@@ -30,7 +32,9 @@ public function __construct(
*/
public function hook(): void
{
- set_exception_handler([$this, 'onException']);
+ set_exception_handler(function (Throwable $throwable): void {
+ $this->onException($throwable);
+ });
}
/**
@@ -39,7 +43,7 @@ public function hook(): void
* @param Throwable $throwable The throwable to report.
*/
public function onException(
- \Throwable $throwable
+ Throwable $throwable,
): void {
$exception = $throwable;
diff --git a/app/src/ApplicationRouter.php b/app/src/ApplicationRouter.php
index 7408a8d..b0a291a 100644
--- a/app/src/ApplicationRouter.php
+++ b/app/src/ApplicationRouter.php
@@ -4,6 +4,8 @@
namespace Auth0\Quickstart;
+use function array_key_exists;
+
final class ApplicationRouter
{
/**
@@ -17,93 +19,63 @@ final class ApplicationRouter
* @param Application $app An instance of our Quickstart Application.
*/
public function __construct(
- Application &$app
+ Application &$app,
) {
- $this->app = & $app;
- }
-
- /**
- * Process the current request and route it to the class handler.
- *
- * @param string $uri The new uri to redirect the end user to.
- */
- public function redirect(
- string $uri
- ): void {
- header('Location: ' . $uri, true, 303);
- exit;
+ $this->app = &$app;
}
/**
- * Process the current request and route it to the class handler.
+ * Return the request method (GET, POST, etc.).
*/
- public function run(): void
+ public function getMethod(): string
{
- $requestUri = parse_url($this->getUri(), PHP_URL_PATH);
-
- $routed = false;
-
- if ($requestUri === '/') {
- $this->app->onIndexRoute($this);
- $routed = true;
- }
-
- if ($requestUri === '/api') {
- $this->setHeaders();
- $this->app->onApiRoute($this);
- $routed = true;
- }
-
- if ($routed === false) {
- $this->setHeaders();
- $this->app->onError404($this);
- }
-
- exit;
+ return $_SERVER['REQUEST_METHOD'] ?? 'GET';
}
/**
* Return (and optionally manipulate) the currently requested uri.
*
- * @param string|null $path Unless null, manipulates the resulting path to match the value.
- * @param string|null $query Unless, manipulates the resulting query to match the value.
+ * @param null|string $path Unless null, manipulates the resulting path to match the value.
+ * @param null|string $query Unless, manipulates the resulting query to match the value.
*/
public function getUri(
?string $path = null,
- ?string $query = null
+ ?string $query = null,
): string {
$httpScheme = $_SERVER['HTTPS'] ?? '';
- $httpScheme = $httpScheme === 'on' ? 'https' : 'http';
+ $httpScheme = 'on' === $httpScheme ? 'https' : 'http';
+
$httpPort = (int) $_SERVER['SERVER_PORT'];
$httpHost = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
$httpHost = preg_replace('/\:' . $httpPort . '$/', '', $httpHost);
+
$httpRequest = (string) $_SERVER['REQUEST_URI'];
- $httpUri = $httpScheme . '://' . $httpHost . ($httpPort !== 80 ? ':' . $httpPort : '') . $httpRequest;
+ $httpUri = $httpScheme . '://' . $httpHost . (80 !== $httpPort ? ':' . $httpPort : '') . $httpRequest;
// If we aren't making changes, simply return the uri.
- if ($path === null && $query === null) {
+ if (null === $path && null === $query) {
return $httpUri;
}
// Parse a url into it's components so we can manipulate them more easily.
$parsedUri = parse_url($httpUri);
- if ($parsedUri === false) {
+ if (false === $parsedUri) {
return $httpUri;
}
- $parsedUri['scheme'] = $parsedUri['scheme'] ?? 'http';
- $parsedUri['host'] = $parsedUri['host'] ?? $httpHost;
- $parsedUri['path'] = $parsedUri['path'] ?? '';
+ $parsedUri['scheme'] ??= 'http';
+ $parsedUri['host'] ??= $httpHost;
+ $parsedUri['path'] ??= '';
$parsedUri['query'] = '?' . ($parsedUri['query'] ?? '');
// Manipulate the /path portion of the uri.
- if ($path !== null) {
+ if (null !== $path) {
$parsedUri['path'] = $path;
}
// Manipulate the ?query portion of the uri.
- if ($query !== null) {
+ if (null !== $query) {
$parsedUri['query'] = $query;
}
@@ -111,24 +83,56 @@ public function getUri(
$parsedUri['port'] = 80;
}
- if ($parsedUri['query'] === '?') {
+ if ('?' === $parsedUri['query']) {
$parsedUri['query'] = '';
}
- if ($parsedUri['query'] !== '') {
+ if ('' !== $parsedUri['query']) {
$parsedUri['query'] = '?' . $parsedUri['query'];
}
// Reconstruct the manipulated uri and return it.
- return $parsedUri['scheme'] . '://' . $parsedUri['host'] . ($parsedUri['port'] !== 80 ? ':' . $parsedUri['port'] : '') . $parsedUri['path'] . $parsedUri['query'];
+ return $parsedUri['scheme'] . '://' . $parsedUri['host'] . (80 !== $parsedUri['port'] ? ':' . $parsedUri['port'] : '') . $parsedUri['path'] . $parsedUri['query'];
}
/**
- * Return the request method (GET, POST, etc.)
+ * Process the current request and route it to the class handler.
+ *
+ * @param string $uri The new uri to redirect the end user to.
*/
- public function getMethod(): string
+ public function redirect(
+ string $uri,
+ ): void {
+ header('Location: ' . $uri, true, 303);
+ exit;
+ }
+
+ /**
+ * Process the current request and route it to the class handler.
+ */
+ public function run(): void
{
- return $_SERVER['REQUEST_METHOD'] ?? 'GET';
+ $requestUri = parse_url($this->getUri(), PHP_URL_PATH);
+
+ $routed = false;
+
+ if ('/' === $requestUri) {
+ $this->app->onIndexRoute($this);
+ $routed = true;
+ }
+
+ if ('/api' === $requestUri) {
+ $this->setHeaders();
+ $this->app->onApiRoute($this);
+ $routed = true;
+ }
+
+ if (false === $routed) {
+ $this->setHeaders();
+ $this->app->onError404($this);
+ }
+
+ exit;
}
/**
@@ -151,7 +155,7 @@ public function setHeaders(): void
* @param int $status The HTTP status code to send.
*/
public function setHttpStatus(
- int $status
+ int $status,
): void {
http_response_code($status);
}
diff --git a/app/src/ApplicationTemplates.php b/app/src/ApplicationTemplates.php
index dec2cd8..1c17c13 100644
--- a/app/src/ApplicationTemplates.php
+++ b/app/src/ApplicationTemplates.php
@@ -4,6 +4,12 @@
namespace Auth0\Quickstart;
+use Exception;
+use LogicException;
+use Throwable;
+
+use function array_key_exists;
+
final class ApplicationTemplates
{
/**
@@ -14,9 +20,13 @@ final class ApplicationTemplates
/**
* State machine of the template being rendered.
*
- * @var array{section: string|null, sections: array, layout: array{name: string, variables: array}|null}
+ * @var array{section: null|string, sections: array, layout: null|array{name: string, variables: array}}
*/
- private array $state;
+ private array $state = [
+ 'sections' => [],
+ 'section' => null,
+ 'layout' => null,
+ ];
/**
* ApplicationTemplates constructor.
@@ -24,26 +34,20 @@ final class ApplicationTemplates
* @param Application $app An instance of our Quickstart Application.
*/
public function __construct(
- Application &$app
+ Application &$app,
) {
- $this->app = & $app;
-
- $this->state = [
- 'sections' => [],
- 'section' => null,
- 'layout' => null,
- ];
+ $this->app = &$app;
}
/**
* Render a template as the browser response, then exit.
*
- * @param string $template The name of the template to use.
+ * @param string $template The name of the template to use.
* @param array $variables Any variables the template should have access to use.
*/
public function render(
string $template,
- array $variables = []
+ array $variables = [],
): void {
$this->state = [
'sections' => [],
@@ -59,6 +63,22 @@ public function render(
exit;
}
+ /**
+ * Define a container layout in which to render a template.
+ *
+ * @param string $name The name of the layout template to use.
+ * @param array $variables Any additional variables the layout template should have access to use.
+ */
+ private function layout(
+ string $name,
+ array $variables = [],
+ ): void {
+ $this->state['layout'] = [
+ 'name' => $name,
+ 'variables' => $variables,
+ ];
+ }
+
/**
* Render a template, and return the content as a string.
*
@@ -67,19 +87,19 @@ public function render(
*/
private function renderTemplate(
string $template,
- array $variables = []
+ array $variables = [],
): string {
// Keep track of the output buffering 'level'.
$level = 0;
// Resolve the requested template to it's file path:
- $templatePath = join(DIRECTORY_SEPARATOR, [APP_ROOT, 'templates', $template . '.php']);
+ $templatePath = implode(DIRECTORY_SEPARATOR, [APP_ROOT, 'templates', $template . '.php']);
// Extract $variables into current scope, for use in template.
extract($variables);
- if (file_exists($templatePath) === false) {
- throw new \Exception("Template file not found: {$template}");
+ if (! file_exists($templatePath)) {
+ throw new Exception(sprintf('Template file not found: %s', $template));
}
try {
@@ -90,7 +110,7 @@ private function renderTemplate(
$content = ob_get_clean();
- if ($this->state['layout'] !== null) {
+ if (null !== $this->state['layout']) {
$layoutTemplate = $this->state['layout']['name'];
$layoutVariables = array_merge($variables, $this->state['layout']['variables']);
@@ -100,17 +120,17 @@ private function renderTemplate(
$content = $this->renderTemplate($layoutTemplate, $layoutVariables);
}
- if ($content !== false) {
+ if (false !== $content) {
return trim($content);
}
return '';
- } catch (\Throwable $e) {
+ } catch (Throwable $throwable) {
while (ob_get_level() > $level) {
ob_end_clean();
}
- throw $e;
+ throw $throwable;
}
}
@@ -120,7 +140,7 @@ private function renderTemplate(
* @param string $sectionName Name of the section to render into the template.
*/
private function section(
- string $sectionName
+ string $sectionName,
): string {
return $this->state['sections'][$sectionName] ?? '';
}
@@ -131,10 +151,10 @@ private function section(
* @param string $sectionName Name of the section to begin capturing.
*/
private function start(
- string $sectionName
+ string $sectionName,
): void {
- if ($this->state['section'] !== null) {
- throw new \LogicException('Nested sections are not supported.');
+ if (null !== $this->state['section']) {
+ throw new LogicException('Nested sections are not supported.');
}
$this->state['section'] = $sectionName;
@@ -147,8 +167,8 @@ private function start(
*/
private function stop(): void
{
- if ($this->state['section'] === null) {
- throw new \LogicException('You must start a section before stopping it.');
+ if (null === $this->state['section']) {
+ throw new LogicException('You must start a section before stopping it.');
}
if (array_key_exists($this->state['section'], $this->state['sections'])) {
@@ -158,20 +178,4 @@ private function stop(): void
$this->state['sections'][$this->state['section']] = ob_get_clean();
$this->state['section'] = null;
}
-
- /**
- * Define a container layout in which to render a template.
- *
- * @param string $name The name of the layout template to use.
- * @param array $variables Any additional variables the layout template should have access to use.
- */
- private function layout(
- string $name,
- array $variables = []
- ): void {
- $this->state['layout'] = [
- 'name' => $name,
- 'variables' => $variables,
- ];
- }
}
diff --git a/app/tests/Feature/ExampleTest.php b/app/tests/Feature/ExampleTest.php
new file mode 100644
index 0000000..61cd84c
--- /dev/null
+++ b/app/tests/Feature/ExampleTest.php
@@ -0,0 +1,5 @@
+toBeTrue();
+});
diff --git a/app/tests/Pest.php b/app/tests/Pest.php
new file mode 100644
index 0000000..5949c61
--- /dev/null
+++ b/app/tests/Pest.php
@@ -0,0 +1,45 @@
+in('Feature');
+
+/*
+|--------------------------------------------------------------------------
+| Expectations
+|--------------------------------------------------------------------------
+|
+| When you're writing tests, you often need to check that values meet certain conditions. The
+| "expect()" function gives you access to a set of "expectations" methods that you can use
+| to assert different things. Of course, you may extend the Expectation API at any time.
+|
+*/
+
+expect()->extend('toBeOne', function () {
+ return $this->toBe(1);
+});
+
+/*
+|--------------------------------------------------------------------------
+| Functions
+|--------------------------------------------------------------------------
+|
+| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
+| project that you don't want to repeat in every file. Here you can also expose helpers as
+| global functions to help you to reduce the number of lines of code in your test files.
+|
+*/
+
+function something()
+{
+ // ..
+}
diff --git a/app/tests/TestCase.php b/app/tests/TestCase.php
new file mode 100644
index 0000000..cfb05b6
--- /dev/null
+++ b/app/tests/TestCase.php
@@ -0,0 +1,10 @@
+toBeTrue();
+});