Skip to content

Commit

Permalink
Autodetect secret key from environment variable (#4)
Browse files Browse the repository at this point in the history
Allow `new \SnapAuth\Client()` for even simpler setup, which will try to
read from `SNAPAUTH_SECRET_KEY`.
  • Loading branch information
Firehed authored Apr 19, 2024
1 parent 9f2dbb7 commit 8046ef5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ $snapAuth = new Client(secretKey: $yourSecret);
> Secret keys are specific to an environment and domain.
> We HIGHLY RECOMMEND using environment variables or another external storage mechanism.
> Avoid committing them to version control, as this can more easily lead to compromise.
>
> The SDK will auto-detect the `SNAPAUTH_SECRET_KEY` environment variable if you do not provide a value directly.
## Usage

Expand Down
18 changes: 17 additions & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,31 @@ class Client
{
private const DEFAULT_API_HOST = 'https://api.snapauth.app';

private string $secretKey;

public function __construct(
#[SensitiveParameter] private string $secretKey,
#[SensitiveParameter] ?string $secretKey = null,
private string $apiHost = self::DEFAULT_API_HOST,
) {
// Auto-detect if not provided
if ($secretKey === null) {
$env = getenv('SNAPAUTH_SECRET_KEY');
if ($env === false) {
throw new ApiError(
'Secret key missing. It can be explictly provided, or it ' .
'can be auto-detected from the SNAPAUTH_SECRET_KEY ' .
'environment variable.',
);
}
$secretKey = $env;
}
if (!str_starts_with($secretKey, 'secret_')) {
throw new ApiError(
'Invalid secret key. Please verify you copied the full value from the SnapAuth dashboard.',
);
}

$this->secretKey = $secretKey;
}

/**
Expand Down
23 changes: 23 additions & 0 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ public function testConstructApi(): void
self::assertInstanceOf(Client::class, $client);
}

public function testConstructSecretKeyAutodetectInvalid(): void
{
assert(getenv('SNAPAUTH_SECRET_KEY') === false);
putenv('SNAPAUTH_SECRET_KEY=invalid');
self::expectException(ApiError::class);
self::expectExceptionMessage('Invalid secret key.');
new Client();
}

public function testConstructSecretKeyAutodetectMissing(): void
{
assert(getenv('SNAPAUTH_SECRET_KEY') === false);
self::expectException(ApiError::class);
self::expectExceptionMessage('Secret key missing.');
new Client();
}

public function testSecretKeyValidation(): void
{
self::expectException(ApiError::class);
Expand All @@ -31,4 +48,10 @@ public function testKeyIsRedactedInDebugInfo(): void
$result = print_r($client, true);
self::assertStringNotContainsString('secret_abc_123', $result);
}

public function tearDown(): void
{
// Note: trailing = sets it to empty string. This actually clears it.
putenv('SNAPAUTH_SECRET_KEY');
}
}

0 comments on commit 8046ef5

Please sign in to comment.