11 Commits

Author SHA1 Message Date
Italo Baeza Cabrera
af04066dd0 Adds Service Provider tests. 2022-10-28 17:17:07 -03:00
Italo Baeza Cabrera
93d12d12c9 Fixes route registration. 2022-10-28 17:00:52 -03:00
Italo Baeza Cabrera
73e0e6c8ee Fixes static analysis line. 2022-10-28 16:36:00 -03:00
Italo Baeza Cabrera
ed68058bd8 Rewrites controller registration to something more understandable. 2022-10-28 16:35:43 -03:00
Italo Baeza Cabrera
f784f601d4 Merge remote-tracking branch 'origin/1.x' into 1.x 2022-10-28 16:30:56 -03:00
Italo
5ac8f14103 Merge pull request #22 from alresiainc/1.x
[minor] correct publishing the config file not working
2022-10-28 16:30:17 -03:00
Italo Baeza Cabrera
7f4465a4ef Should fix route registration using controller base prefix. 2022-10-28 16:26:53 -03:00
Italo
0b39038873 Merge pull request #20 from Bubka/1.x 2022-10-23 13:43:30 -03:00
Fidelis E. Peter
07283858a9 [minor] correct publishing the config file not working
When Publishing the config file

php artisan vendor:publish --provider="Laragear\WebAuthn\WebAuthnServiceProvider" --tag="config"

Will Return

"INFO  No publishable resources for tag [config]."

LINE FOR CONFIG WAS MISSING
2022-10-23 01:32:27 +01:00
Bubka
b98d07c277 Fixes relaying_party typo 2022-10-22 19:22:17 +02:00
Italo
7f628f9a79 Added better Github and actions config. 2022-08-26 00:25:25 -04:00
24 changed files with 154 additions and 122 deletions

7
.github/FUNDING.yml vendored
View File

@@ -1,6 +1,3 @@
# Help me support this package # Let's keep it free and up to date
github: DarkGhostHunter github: DarkGhostHunter
patreon: PackagesForLaravel custom: "https://paypal.me/darkghosthunter"
ko_fi: DarkGhostHunter
custom: ['https://www.buymeacoffee.com/darkghosthunter', 'https://paypal.me/darkghosthunter']

View File

@@ -1,5 +1,8 @@
name: Bug Report name: Bug Report
description: File a bug report description: |
File a bug report to be fixed.
Sponsors get priority issues, PRs, fixes and requests. Not a sponsor? [You're a just click away!](https://github.com/sponsors/DarkGhostHunter).
title: "[X.x] What does happen that is considered an error or bug?" title: "[X.x] What does happen that is considered an error or bug?"
labels: ["bug"] labels: ["bug"]
assignees: assignees:
@@ -9,6 +12,7 @@ body:
attributes: attributes:
value: | value: |
Thanks for taking the time to fill out this bug report! Thanks for taking the time to fill out this bug report!
The more detailed this bug report is, the faster it can be reviewed and fixed. The more detailed this bug report is, the faster it can be reviewed and fixed.
- type: input - type: input
id: version-php-os id: version-php-os
@@ -18,6 +22,14 @@ body:
placeholder: 8.1.2 - Ubuntu 22.04 x64 placeholder: 8.1.2 - Ubuntu 22.04 x64
validations: validations:
required: true required: true
- type: input
id: version-db
attributes:
label: Database
description: Exact DB version using this package, if applicable.
placeholder: MySQL 8.0.28
validations:
required: false
- type: input - type: input
id: version-laravel id: version-laravel
attributes: attributes:
@@ -26,28 +38,12 @@ body:
placeholder: 9.2.3 placeholder: 9.2.3
validations: validations:
required: true required: true
- type: input
id: version-authenticator
attributes:
label: Authenticator type
description: If applicable, exact authenticator you're using.
placeholder: YubiKey 5, iPhone 7s, Samsung Galaxy S11+...
validations:
required: false
- type: input
id: version-os-browser
attributes:
label: OS and Browser versions
description: If applicable, exact OS and Browser versions
placeholder: Android 12.0 - Chrome 102.0.5005.99
validations:
required: false
- type: checkboxes - type: checkboxes
id: requirements id: requirements
attributes: attributes:
label: Have you done this? label: Have you done this?
options: options:
- label: I am willing to share my stack trace and logs - label: I have checked my logs and I'm sure is a bug in this package.
required: true required: true
- label: I can reproduce this bug in isolation (vanilla Laravel install) - label: I can reproduce this bug in isolation (vanilla Laravel install)
required: true required: true
@@ -58,7 +54,7 @@ body:
attributes: attributes:
label: Expectation label: Expectation
description: Write what you expect to (correctly) happen. description: Write what you expect to (correctly) happen.
placeholder: When I do this, I expect to this to happen. placeholder: When I do this, I expect to happen that.
validations: validations:
required: true required: true
- type: textarea - type: textarea
@@ -73,7 +69,7 @@ body:
id: reproduction id: reproduction
attributes: attributes:
label: Reproduction label: Reproduction
description: Paste the code to assert in a test, or just comment with the repository with the bug. description: Paste the code to assert in a test, or just comment with the repository with the bug to download.
render: php render: php
placeholder: | placeholder: |
$test = Laragear::make()->break(); $test = Laragear::make()->break();
@@ -87,27 +83,8 @@ body:
id: logs id: logs
attributes: attributes:
label: Stack trace & logs label: Stack trace & logs
description: If you have a stack trace, you can copy it here. You may hide sensible information. description: If you have a **full** stack trace, you can copy it here. You may hide sensible information.
placeholder: This is automatically formatted into code, no need for backticks. placeholder: This is automatically formatted into code, no need for ``` backticks.
render: shell render: shell
validations: validations:
required: false required: false
- type: textarea
id: attestation-assertion
attributes:
label: Attestation / Assertion objects
description: If applicable, add the Attestation and Assertion objects you have debugged.
placeholder: This is automatically formatted into Javascript, no need for backticks.
render: javascript
validations:
required: false
- type: dropdown
id: supporter
attributes:
label: Are you a Patreon supporter?
description: Patreon supporters get priority review, fixing and responses. Are you not? [Become one!](https://patreon.com/packagesforlaravel)
options:
- Yes, with my username
- No, don't give priority to this
validations:
required: true

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -1,5 +1,8 @@
name: Feature request name: Feature request
description: Suggest a feature for this package description: |
Suggest a feature for this package.
Sponsors get priority issues, PRs, fixes and requests. Not a sponsor? [You're a just click away!](https://github.com/sponsors/DarkGhostHunter).
title: "[X.x] Add this cool feature for this package" title: "[X.x] Add this cool feature for this package"
labels: ["enhancement"] labels: ["enhancement"]
assignees: assignees:
@@ -28,7 +31,12 @@ body:
attributes: attributes:
label: Description label: Description
description: Describe how the feature works description: Describe how the feature works
placeholder: This new feature would accomplish this, and would be cool to integrate it to the package because... placeholder: |
This new feature would accomplish...
It could be implemented by doing...
And it would be cool because...
validations: validations:
required: true required: true
- type: textarea - type: textarea
@@ -41,13 +49,3 @@ body:
render: php render: php
validations: validations:
required: true required: true
- type: dropdown
id: supporter
attributes:
label: Are you a Patreon supporter?
description: Patreon supporters get priority review, fixing and responses. Are you not? [Become one!](https://patreon.com/packagesforlaravel)
options:
- Yes, with my username
- No, don't give priority to this
validations:
required: true

View File

@@ -1,23 +1,22 @@
<!-- <!--
Thanks for contributing to this package! We only accept PR to the latest stable version. Thanks for contributing to this package! We only accept PR to the latest stable version.
If you're pushing a Feature: If you're pushing a Feature:
- Title it: "[X.x] This new feature" - Title it: "[X.x] This new feature"
- Describe what the new feature enables - Describe what the new feature enables
- Show a small code snippet of the new feature - Show a small code snippet of the new feature
- Ensure it doesn't break any feature. - Ensure it doesn't break backward compatibility.
If you're pushing a Fix: If you're pushing a Fix:
- Title it: "[X.x] FIX: The bug name" - Title it: "[X.x] FIX: The bug name"
- Describe how it fixes in a few words. - Describe how it fixes in a few words.
- Ensure it doesn't break any feature. - Ensure it doesn't break backward compatibility.
All Pull Requests run with extensive tests for stable and latest versions of PHP and Laravel. All Pull Requests run with extensive tests for stable and latest versions of PHP and Laravel.
Ensure your tests pass or your PR may be taken down. Ensure your tests pass or your PR may be taken down.
If you're a Patreon supporter, this PR will have priority. If you're a Sponsor, this PR will have priority review.
Not a Patreon supporter? Become one at https://patreon.com/packagesforlaravel Not a Sponsor? Become one at https://github.com/sponsors/DarkGhostHunter
--> -->
# Description # Description
@@ -29,5 +28,3 @@ This feature/fix allows to...
```php ```php
Laragear::sample(); Laragear::sample();
``` ```
<!-- You may delete this section if it's a FIX -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

BIN
.github/assets/support.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -1,6 +1,6 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow # yaml-language-server: $schema=https://json.schemastore.org/github-workflow
name: "Tests" name: Tests
on: on:
push: push:
@@ -21,6 +21,7 @@ jobs:
- name: "Find non-printable ASCII characters" - name: "Find non-printable ASCII characters"
run: | run: |
! LC_ALL=C.UTF-8 find ./src -type f -name "*.php" -print0 | xargs -0 -- grep -PHn "[^ -~]" ! LC_ALL=C.UTF-8 find ./src -type f -name "*.php" -print0 | xargs -0 -- grep -PHn "[^ -~]"
syntax_errors: syntax_errors:
name: "1⃣ Syntax errors" name: "1⃣ Syntax errors"
runs-on: "ubuntu-latest" runs-on: "ubuntu-latest"
@@ -34,10 +35,8 @@ jobs:
- name: "Checkout code" - name: "Checkout code"
uses: "actions/checkout@v3" uses: "actions/checkout@v3"
- name: "Install dependencies" - name: "Validate Composer configuration"
uses: "ramsey/composer-install@v2" run: "composer validate --strict"
with:
dependency-versions: "highest"
- name: "Check source code for syntax errors" - name: "Check source code for syntax errors"
run: "composer exec -- parallel-lint src/" run: "composer exec -- parallel-lint src/"
@@ -51,6 +50,7 @@ jobs:
strategy: strategy:
matrix: matrix:
php-version: php-version:
- "8.0"
- "8.1" - "8.1"
laravel-constrain: laravel-constrain:
- "9.*" - "9.*"
@@ -89,19 +89,14 @@ jobs:
- name: "Set up PHP" - name: "Set up PHP"
uses: "shivammathur/setup-php@v2" uses: "shivammathur/setup-php@v2"
with: with:
php-version: "8.1"
tools: "phpstan" tools: "phpstan"
php-version: "latest"
- name: "Checkout code" - name: "Checkout code"
uses: "actions/checkout@v3" uses: "actions/checkout@v3"
- name: "Validate Composer configuration"
run: "composer validate --strict"
- name: "Install dependencies" - name: "Install dependencies"
uses: "ramsey/composer-install@v2" uses: "ramsey/composer-install@v2"
with:
dependency-versions: "highest"
- name: "Execute static analysis" - name: "Execute static analysis"
run: "composer exec -- phpstan analyze -l 5 src/" run: "composer exec -- phpstan analyze -l 5 src/"
@@ -119,7 +114,7 @@ jobs:
- name: "Check exported files" - name: "Check exported files"
run: | run: |
EXPECTED="LICENSE.md,README.md,composer.json" EXPECTED="LICENSE.md,README.md,composer.json"
CURRENT="$(git archive HEAD | tar --list --exclude="src" --exclude="src/*" --exclude=".stubs" --exclude=".stubs/*" --exclude="stubs" --exclude="stubs/*" --exclude="lang" --exclude="lang/*" --exclude="config" --exclude="config/*" --exclude="database" --exclude="database/*" --exclude="resources" --exclude="resources/*" --exclude="routes" --exclude="routes/*" | paste -s -d ",")" CURRENT="$(git archive HEAD | tar --list --exclude="src" --exclude="src/*" --exclude=".stubs" --exclude=".stubs/*" --exclude="routes" --exclude="routes/*" --exclude="stubs" --exclude="stubs/*" --exclude="lang" --exclude="lang/*" --exclude="config" --exclude="config/*" --exclude="database" --exclude="database/*" --exclude="resources" --exclude="resources/*" | paste -s -d ",")"
echo "CURRENT =${CURRENT}" echo "CURRENT =${CURRENT}"
echo "EXPECTED=${EXPECTED}" echo "EXPECTED=${EXPECTED}"
test "${CURRENT}" == "${EXPECTED}" test "${CURRENT}" == "${EXPECTED}"

View File

@@ -23,9 +23,9 @@ public function login(AssertedRequest $request)
> You want to add two-factor authentication to your app? Check out [Laragear TwoFactor](https://github.com/Laragear/TwoFactor). > You want to add two-factor authentication to your app? Check out [Laragear TwoFactor](https://github.com/Laragear/TwoFactor).
## Keep this package free ## Become a sponsor
[![Patreon](.github/assets/patreon.png)](https://patreon.com/packagesforlaravel)[![Ko-fi](.github/assets/ko-fi.png)](https://ko-fi.com/DarkGhostHunter)[![Buymeacoffee](.github/assets/buymeacoffee.png)](https://www.buymeacoffee.com/darkghosthunter)[![PayPal](.github/assets/paypal.png)](https://www.paypal.com/paypalme/darkghosthunter) [![](.github/assets/support.png)](https://github.com/sponsors/DarkGhostHunter)
Your support allows me to keep this package free, up-to-date and maintainable. Alternatively, you can **[spread the word!](http://twitter.com/share?text=I%20am%20using%20this%20cool%20PHP%20package&url=https://github.com%2FLaragear%2FWebAuthn&hashtags=PHP,Laravel)** Your support allows me to keep this package free, up-to-date and maintainable. Alternatively, you can **[spread the word!](http://twitter.com/share?text=I%20am%20using%20this%20cool%20PHP%20package&url=https://github.com%2FLaragear%2FWebAuthn&hashtags=PHP,Laravel)**
@@ -547,7 +547,7 @@ After that, you will receive the `config/webauthn.php` config file with an array
<?php <?php
return [ return [
'relaying_party' => [ 'relying_party' => [
'name' => env('WEBAUTHN_NAME', env('APP_NAME')), 'name' => env('WEBAUTHN_NAME', env('APP_NAME')),
'id' => env('WEBAUTHN_ID'), 'id' => env('WEBAUTHN_ID'),
], ],
@@ -559,18 +559,18 @@ return [
]; ];
``` ```
### Relaying Party Information ### Relying Party Information
```php ```php
return [ return [
'relaying_party' => [ 'relying_party' => [
'name' => env('WEBAUTHN_NAME', env('APP_NAME')), 'name' => env('WEBAUTHN_NAME', env('APP_NAME')),
'id' => env('WEBAUTHN_ID'), 'id' => env('WEBAUTHN_ID'),
], ],
]; ];
``` ```
The _Relaying Party_ is just a way to uniquely identify your application in the user device: The _Relying Party_ is just a way to uniquely identify your application in the user device:
* `name`: The name of the application. Defaults to the application name. * `name`: The name of the application. Defaults to the application name.
* `id`: An unique ID the application, like the site domain. If `null`, the device may fill it internally, usually as the full domain. * `id`: An unique ID the application, like the site domain. If `null`, the device may fill it internally, usually as the full domain.

View File

@@ -4,11 +4,11 @@ return [
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Relaying Party | Relying Party
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| We will use your application information to inform the device who is the | We will use your application information to inform the device who is the
| relaying party. While only the name is enough, you can further set the | relying party. While only the name is enough, you can further set the
| a custom domain as ID and even an icon image data encoded as BASE64. | a custom domain as ID and even an icon image data encoded as BASE64.
| |
*/ */

View File

@@ -4,14 +4,17 @@ use App\Http\Controllers\WebAuthn\WebAuthnLoginController;
use App\Http\Controllers\WebAuthn\WebAuthnRegisterController; use App\Http\Controllers\WebAuthn\WebAuthnRegisterController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::middleware('web')->group(static function (): void { Route::middleware('web')
Route::post('webauthn/register/options', [WebAuthnRegisterController::class, 'options']) ->group(static function (): void {
->name('webauthn.register.options'); Route::controller(WebAuthnRegisterController::class)
Route::post('webauthn/register', [WebAuthnRegisterController::class, 'register']) ->group(static function (): void {
->name('webauthn.register'); Route::post('webauthn/register/options', 'options')->name('webauthn.register.options');
Route::post('webauthn/register', 'register')->name('webauthn.register');
});
Route::post('webauthn/login/options', [WebAuthnLoginController::class, 'options']) Route::controller(WebAuthnLoginController::class)
->name('webauthn.login.options'); ->group(static function (): void {
Route::post('webauthn/login', [WebAuthnLoginController::class, 'login']) Route::post('webauthn/login/options', 'options')->name('webauthn.login.options');
->name('webauthn.login'); Route::post('webauthn/login', 'login')->name('webauthn.login');
}); });
});

View File

@@ -35,6 +35,6 @@ class CheckRelyingPartyHashSame extends BaseCheckRelyingPartyHashSame
*/ */
protected function relyingPartyId(AssertionValidation|AttestationValidation $validation): string protected function relyingPartyId(AssertionValidation|AttestationValidation $validation): string
{ {
return $this->config->get('webauthn.relaying_party.id') ?? $this->config->get('app.url'); return $this->config->get('webauthn.relying_party.id') ?? $this->config->get('app.url');
} }
} }

View File

@@ -41,7 +41,7 @@ class MakeWebAuthnCredential
'alias' => $validation->request->json('response.alias'), 'alias' => $validation->request->json('response.alias'),
'counter' => $validation->attestationObject->authenticatorData->counter, 'counter' => $validation->attestationObject->authenticatorData->counter,
'rp_id' => $this->config->get('webauthn.relaying_party.id') ?? $this->config->get('app.url'), 'rp_id' => $this->config->get('webauthn.relying_party.id') ?? $this->config->get('app.url'),
'origin' => $validation->clientDataJson->origin, 'origin' => $validation->clientDataJson->origin,
'transports' => $validation->request->json('response.transports'), 'transports' => $validation->request->json('response.transports'),
'aaguid' => Uuid::fromBytes($validation->attestationObject->authenticatorData->attestedCredentialData->aaguid), 'aaguid' => Uuid::fromBytes($validation->attestationObject->authenticatorData->attestedCredentialData->aaguid),

View File

@@ -39,11 +39,11 @@ abstract class CheckRelyingPartyHashSame
public function handle(AttestationValidation|AssertionValidation $validation, Closure $next): mixed public function handle(AttestationValidation|AssertionValidation $validation, Closure $next): mixed
{ {
// This way we can get the app RP ID on attestation, and the Credential RP ID // This way we can get the app RP ID on attestation, and the Credential RP ID
// on assertion. The credential will have the same Relaying Party ID on both // on assertion. The credential will have the same Relying Party ID on both
// the authenticator and the application so on assertion both should match. // the authenticator and the application so on assertion both should match.
$relayingParty = parse_url($this->relyingPartyId($validation), PHP_URL_HOST); $relyingParty = parse_url($this->relyingPartyId($validation), PHP_URL_HOST);
if ($this->authenticatorData($validation)->hasNotSameRPIdHash($relayingParty)) { if ($this->authenticatorData($validation)->hasNotSameRPIdHash($relyingParty)) {
static::throw($validation, 'Response has different Relying Party ID hash.'); static::throw($validation, 'Response has different Relying Party ID hash.');
} }

View File

@@ -40,11 +40,11 @@ abstract class CheckRelyingPartyIdContained
public function handle(AttestationValidation|AssertionValidation $validation, Closure $next): mixed public function handle(AttestationValidation|AssertionValidation $validation, Closure $next): mixed
{ {
if (!$host = parse_url($validation->clientDataJson->origin, PHP_URL_HOST)) { if (!$host = parse_url($validation->clientDataJson->origin, PHP_URL_HOST)) {
static::throw($validation, 'Relaying Party ID is invalid.'); static::throw($validation, 'Relying Party ID is invalid.');
} }
$current = parse_url( $current = parse_url(
$this->config->get('webauthn.relaying_party.id') ?? $this->config->get('app.url'), PHP_URL_HOST $this->config->get('webauthn.relying_party.id') ?? $this->config->get('app.url'), PHP_URL_HOST
); );
// Check the host is the same or is a subdomain of the current config domain. // Check the host is the same or is a subdomain of the current config domain.
@@ -52,6 +52,6 @@ abstract class CheckRelyingPartyIdContained
return $next($validation); return $next($validation);
} }
static::throw($validation, 'Relaying Party ID not scoped to current.'); static::throw($validation, 'Relying Party ID not scoped to current.');
} }
} }

View File

@@ -31,20 +31,19 @@ class WebAuthn
*/ */
public static function routes(): void public static function routes(): void
{ {
Route::middleware('web')->group(static function (): void { Route::middleware('web')
Route::post('webauthn/register/options') ->group(static function (): void {
->uses([\App\Http\Controllers\WebAuthn\WebAuthnRegisterController::class, 'options']) Route::controller(\App\Http\Controllers\WebAuthn\WebAuthnRegisterController::class)
->name('webauthn.register.options'); ->group(static function (): void {
Route::post('webauthn/register') Route::post('webauthn/register/options', 'options')->name('webauthn.register.options');
->uses([\App\Http\Controllers\WebAuthn\WebAuthnRegisterController::class, 'register']) Route::post('webauthn/register', 'register')->name('webauthn.register');
->name('webauthn.register'); });
Route::post('webauthn/login/options') Route::controller(\App\Http\Controllers\WebAuthn\WebAuthnLoginController::class)
->uses([\App\Http\Controllers\WebAuthn\WebAuthnLoginController::class, 'options']) ->group(static function (): void {
->name('webauthn.login.options'); Route::post('webauthn/login/options', 'options')->name('webauthn.login.options');
Route::post('webauthn/login') Route::post('webauthn/login', 'login')->name('webauthn.login');
->uses([\App\Http\Controllers\WebAuthn\WebAuthnLoginController::class, 'login']) });
->name('webauthn.login');
}); });
} }
} }

View File

@@ -45,6 +45,7 @@ class WebAuthnServiceProvider extends ServiceProvider
if ($this->app->runningInConsole()) { if ($this->app->runningInConsole()) {
$this->publishesMigrations(static::MIGRATIONS); $this->publishesMigrations(static::MIGRATIONS);
$this->publishes([static::ROUTES => $this->app->basePath('routes/webauthn.php')], 'routes'); $this->publishes([static::ROUTES => $this->app->basePath('routes/webauthn.php')], 'routes');
$this->publishes([static::CONFIG => $this->app->configPath('webauthn.php')], 'config');
// @phpstan-ignore-next-line // @phpstan-ignore-next-line
$this->publishes([static::CONTROLLERS => $this->app->path('Http/Controllers/WebAuthn')], 'controllers'); $this->publishes([static::CONTROLLERS => $this->app->path('Http/Controllers/WebAuthn')], 'controllers');
$this->publishes([static::JS => $this->app->resourcePath('js/vendor/webauthn')], 'js'); $this->publishes([static::JS => $this->app->resourcePath('js/vendor/webauthn')], 'js');

View File

@@ -457,7 +457,7 @@ class ValidationTest extends TestCase
$this->request->setJson(new ParameterBag($invalid)); $this->request->setJson(new ParameterBag($invalid));
$this->expectException(AssertionException::class); $this->expectException(AssertionException::class);
$this->expectExceptionMessage('Assertion Error: Relaying Party ID not scoped to current.'); $this->expectExceptionMessage('Assertion Error: Relying Party ID not scoped to current.');
$this->validate(); $this->validate();
} }
@@ -477,7 +477,7 @@ class ValidationTest extends TestCase
$this->request->setJson(new ParameterBag($invalid)); $this->request->setJson(new ParameterBag($invalid));
$this->expectException(AssertionException::class); $this->expectException(AssertionException::class);
$this->expectExceptionMessage('Assertion Error: Relaying Party ID not scoped to current.'); $this->expectExceptionMessage('Assertion Error: Relying Party ID not scoped to current.');
$this->validate(); $this->validate();
} }

View File

@@ -80,7 +80,7 @@ class CreatorTest extends TestCase
]); ]);
} }
public function test_uses_relaying_party_config(): void public function test_uses_relying_party_config(): void
{ {
config(['webauthn.relying_party' => [ config(['webauthn.relying_party' => [
'id' => 'https://foo.bar', 'id' => 'https://foo.bar',

View File

@@ -504,7 +504,7 @@ class ValidationTest extends TestCase
public function test_rp_id_fails_if_not_equal(): void public function test_rp_id_fails_if_not_equal(): void
{ {
$this->expectException(AttestationException::class); $this->expectException(AttestationException::class);
$this->expectExceptionMessage('Attestation Error: Relaying Party ID not scoped to current.'); $this->expectExceptionMessage('Attestation Error: Relying Party ID not scoped to current.');
$invalid = FakeAuthenticator::attestationResponse(); $invalid = FakeAuthenticator::attestationResponse();
@@ -524,7 +524,7 @@ class ValidationTest extends TestCase
public function test_rp_id_fails_if_not_contained(): void public function test_rp_id_fails_if_not_contained(): void
{ {
$this->expectException(AttestationException::class); $this->expectException(AttestationException::class);
$this->expectExceptionMessage('Attestation Error: Relaying Party ID not scoped to current.'); $this->expectExceptionMessage('Attestation Error: Relying Party ID not scoped to current.');
$invalid = FakeAuthenticator::attestationResponse(); $invalid = FakeAuthenticator::attestationResponse();
@@ -546,7 +546,7 @@ class ValidationTest extends TestCase
$this->app->when(CheckRelyingPartyHashSame::class) $this->app->when(CheckRelyingPartyHashSame::class)
->needs(ConfigContract::class) ->needs(ConfigContract::class)
->give(static function (): Repository { ->give(static function (): Repository {
return tap(new Repository())->set('webauthn.relaying_party.id', 'https://otherhost.com'); return tap(new Repository())->set('webauthn.relying_party.id', 'https://otherhost.com');
}); });
$this->expectException(AttestationException::class); $this->expectException(AttestationException::class);

View File

@@ -0,0 +1,64 @@
<?php
namespace Tests;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Fluent;
use Illuminate\Support\ServiceProvider;
use Laragear\WebAuthn\Contracts\WebAuthnAuthenticatable;
use Laragear\WebAuthn\WebAuthnAuthentication;
use Laragear\WebAuthn\WebAuthnServiceProvider;
class ServiceProviderTest extends TestCase
{
public function test_merges_config(): void
{
static::assertSame(
File::getRequire(WebAuthnServiceProvider::CONFIG),
$this->app->make('config')->get('webauthn')
);
}
public function test_publishes_config(): void
{
static::assertSame(
[WebAuthnServiceProvider::CONFIG => $this->app->configPath('webauthn.php')],
ServiceProvider::$publishGroups['config']
);
}
public function test_publishes_migrations(): void
{
$format = now()->format('Y_m_d_His');
static::assertSame(
[
realpath(WebAuthnServiceProvider::MIGRATIONS . '/2022_07_01_000000_create_webauthn_credentials.php') =>
$this->app->databasePath("migrations/{$format}_create_webauthn_credentials.php"),
],
ServiceProvider::pathsToPublish(WebAuthnServiceProvider::class, 'migrations')
);
}
public function test_bounds_user(): void
{
static::assertNull($this->app->make(WebAuthnAuthenticatable::class));
$user = new class extends Fluent implements WebAuthnAuthenticatable {
use WebAuthnAuthentication;
};
$this->app->instance(Authenticatable::class, $user);
static::assertSame($user, $this->app->make(WebAuthnAuthenticatable::class));
}
public function test_publishes_routes_file(): void
{
static::assertSame(
[WebAuthnServiceProvider::ROUTES => $this->app->basePath('routes/webauthn.php')],
ServiceProvider::$publishGroups['routes']
);
}
}