Skip to content

Commit

Permalink
Merge pull request #288 from ash-jc-allen/allowed-url-schemes
Browse files Browse the repository at this point in the history
Add ability to specify the allowed URL schemes
  • Loading branch information
ash-jc-allen committed Jul 2, 2024
2 parents cfa831a + c3b3f05 commit 292d8b0
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 3 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
- [Custom Database Connection](#custom-database-connection)
- [Specifying the Key Generator](#specifying-the-key-generator)
- [Specifying the User Agent Parser](#specifying-the-user-agent-parser)
- [Specifying the Allowed URL Schemes](#specifying-the-allowed-url-schemes)
- [Helper Methods](#helper-methods)
- [Visits](#visits)
- [Find by URL Key](#find-by-url-key)
Expand Down Expand Up @@ -632,6 +633,23 @@ To do this, you can define the class to be used in the `short-url.php` config fi

You'll just need to ensure that your custom user agent parser class implements the `AshAllenDesign\ShortURL\Interfaces\UserAgentDriver` interface.

#### Specifying the Allowed URL Schemes

By default, Short URL will allow you to create a shortened URL for any URLs beginning with `http://` or `https://`.

However, you may want to change this list of allowed URL schemes. For example, this may be to restrict the creation to only `https://` URLs. Or, it may be to allow URLs to be created using other schemes such as `mailto://` or even custom schemes for your own applications.

To change the list of allowed URL schemes, you can define the list using the `allowed_url_schemes` field in your `short-url.php` config file like so:

```php
'allowed_url_schemes' => [
'http://',
'https://',
'mailto://',
'myapp://',
],
```

### Helper Methods
#### Visits
The ShortURL model includes a relationship (that you can use just like any other Laravel model relation) for getting the
Expand Down
14 changes: 14 additions & 0 deletions config/short-url.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@
*/
'enforce_https' => true,

/*
|--------------------------------------------------------------------------
| Allowed URL Schemes
|--------------------------------------------------------------------------
|
| Here you may specify the allowed URL schemes to shorten. For example:
| 'mailto://', 'whatsapp://', 'yourapp://'.
|
*/
'allowed_url_schemes' => [
'http://',
'https://',
],

/*
|--------------------------------------------------------------------------
| URL Length
Expand Down
6 changes: 4 additions & 2 deletions src/Classes/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,10 @@ public function routes(): void
*/
public function destinationUrl(string $url): self
{
if (! Str::startsWith($url, ['http://', 'https://'])) {
throw new ShortURLException('The destination URL must begin with http:// or https://');
$allowedPrefixes = config('short-url.allowed_url_schemes');

if (! Str::startsWith($url, config('short-url.allowed_url_schemes'))) {
throw new ShortURLException('The destination URL must begin with an allowed prefix: '.implode(', ', $allowedPrefixes));
}

$this->destinationUrl = $url;
Expand Down
1 change: 1 addition & 0 deletions src/Classes/Validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public function validateConfig(): bool
Rule::make('enforce_https')->rules(['required', 'boolean']),
Rule::make('forward_query_params')->rules(['required', 'boolean']),
Rule::make('default_url')->rules(['nullable', 'string']),
Rule::make('allowed_url_schemes')->rules(['required', 'array']),
],
]);

Expand Down
26 changes: 25 additions & 1 deletion tests/Unit/Classes/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function exception_is_thrown_in_the_constructor_if_the_config_variables_a
public function exception_is_thrown_if_the_destination_url_does_not_begin_with_http_or_https(): void
{
$this->expectException(ShortURLException::class);
$this->expectExceptionMessage('The destination URL must begin with http:// or https://');
$this->expectExceptionMessage('The destination URL must begin with an allowed prefix: http://, https://');

$builder = app(Builder::class);
$builder->destinationUrl('INVALID');
Expand Down Expand Up @@ -609,4 +609,28 @@ public function builder_works_when_the_date_facade_is_set_to_use_carbon_immutabl

Date::useDefault();
}

#[Test]
public function custom_url_schemes_allowed_if_configured(): void
{
Config::set('short-url.allowed_url_schemes', ['http://', 'https://', 'whatsapp://']);

$shortUrl = app(Builder::class)
->destinationUrl('whatsapp://callMe')
->make();

$this->assertSame('whatsapp://callMe', $shortUrl->destination_url);
}

#[Test]
public function exception_is_thrown_if_invalid_scheme(): void
{
Config::set('short-url.allowed_url_schemes', ['https://', 'whatsapp://']);

$this->expectException(ShortURLException::class);
$this->expectExceptionMessage('The destination URL must begin with an allowed prefix: https://, whatsapp://');

$builder = app(Builder::class);
$builder->destinationUrl('phpstorm://');
}
}
12 changes: 12 additions & 0 deletions tests/Unit/Classes/ValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,16 @@ public function exception_is_thrown_if_the_default_url_is_not_a_string(): void
$validation = new Validation();
$validation->validateConfig();
}

#[Test]
public function exception_is_thrown_if_the_allowed_url_schemes_is_not_an_array(): void
{
$this->expectException(ValidationException::class);
$this->expectExceptionMessage('The short-url.allowed_url_schemes field must be an array.');

Config::set('short-url.allowed_url_schemes', 'INVALID');

$validation = new Validation();
$validation->validateConfig();
}
}

0 comments on commit 292d8b0

Please sign in to comment.