Skip to content

Commit

Permalink
Merge pull request #17 from JakyeRU/feature/custom-callback
Browse files Browse the repository at this point in the history
Custom Callback
  • Loading branch information
JakyeRU authored Jan 11, 2022
2 parents 43baff4 + e2e7736 commit 3671668
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 94 deletions.
37 changes: 31 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,48 @@ Larascord is a package that allows you to authenticate users in your Laravel app
## Laravel
> :warning: You must use this package in a fresh Laravel application otherwise unexpected behavior may occur.
### Step 1: Install Larascord
* `composer require jakyeru/larascord`
```shell
composer require jakyeru/larascord
```
### Step 2: Run the installation command
* `php artisan larascord:install`
```shell
php artisan larascord:install
```
### Step 3: Follow Larascord's instructions
* You can get your Discord application's `CLIENT ID` and `CLIENT SECRET` from the "OAuth2" tab of your application.
* ![](https://i.imgur.com/YJnM4H5.png)
* The `REDIRECT URI` has to be the **same** as the one you provided in your application's OAuth2 redirect.
![](https://i.imgur.com/YJnM4H5.png)

Your application should now be able to authenticate users using Discord.

## Configuration
#### You can publish Larascord's configuration using the following commands:
```shell
php artisan larascord:publish
```
```shell
php artisan vendor:publish --provider="Jakyeru\Larascord\LarascordServiceProvider" --tag="config"
```
#### You can also forcefully publish Larascord's configuration, overwriting any existing configuration:
```shell
php artisan larascord:publish --force
```
_You shouldn't need these commands as the configuration is automatically published when the package is installed._

---
# Larascord Routes
> 💡 These routes can be found in the `routes/auth.php` file.
| Route Name | URI | Description | Action | Method |
| ---------- | ---- | ----------- | ------ | ------ |
| `login` | `/login` | Redirects the user to Discord's OAuth2 authorization page. | REDIRECT | `GET` |
| `logout` | `/logout` | Invalidates the current session. | `AuthenticatedSessionController@destroy` | `POST` |
| `larascord.login` | `/larascord/callback` | Callback route for Discord OAuth2 authentication. | `DiscordController@handle` | `GET` |
| `larascord.refresh_token` | `/larascord/refresh-token` | Redirects to the login page. (Used to access secure parts of the application through the middleware `password.confirm`.) | REDIRECT | `GET` |

# Possible Errors
## `Invalid OAuth2 redirect_uri`
This error occurs when your `redirect_uri` is not listed in your application's OAuth2 redirects.

If you are sure your `redirect_uri` is correct, make sure that `APP_URL` is correct in `config/app.php`.

---

If you encounter any other error(s), please open an issue on [GitHub](https://github.com/JakyeRU/Larascord/issues/new/choose).
72 changes: 33 additions & 39 deletions src/Console/Commands/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class InstallCommand extends Command
*/
protected $description = 'Use this command to install Larascord.';

private string|null $clientId;
private string|null $clientSecret;
private string|null $redirectUri;
private ?string $clientId;
private ?string $clientSecret;
private ?string $prefix;

/**
* Execute the console command.
Expand All @@ -38,13 +38,14 @@ public function handle()
// Getting the user's input
$this->clientId = $this->ask('What is your Discord application\'s client id?');
$this->clientSecret = $this->ask('What is your Discord application\'s client secret?');
$this->redirectUri = $this->ask('What is your Discord application\'s redirect uri?', 'http://localhost:8000/larascord/callback');
$this->prefix = $this->ask('What route prefix should Larascord use?', 'larascord');

// Validating the user's input
try {$this->validateInput();} catch (\Exception $e) {$this->error($e->getMessage()); return;}

// Installing laravel/breeze
$this->requireComposerPackages('laravel/breeze:^1.4');
$this->info('Please wait while we install Larascord...');
$this->requireComposerPackages('laravel/breeze:^1.4', '-q');
shell_exec('php artisan breeze:install');

// Appending the secrets to the .env file
Expand All @@ -56,20 +57,17 @@ public function handle()
// Create the model files
$this->createModelFiles();

// Create the controller file
$this->createControllerFiles();

// Create the route files
$this->createRouteFiles();

// Create the view files
$this->createViewFiles();

// Remove Laravel Breeze routes
$this->replaceBreezeRoutes();

// Asking the user to build the assets
if ($this->confirm('Do you want to build the assets?', true)) {
try {
shell_exec('npm install');
shell_exec('npm run dev');
shell_exec('npm install --silent');
shell_exec('npm run dev --silent');
} catch (\Exception $e) {
$this->error($e->getMessage());
$this->comment('Please execute the "npm install && npm run dev" command to build your assets.');
Expand All @@ -92,6 +90,12 @@ public function handle()
$this->comment('php artisan migrate');
}

// Automatically publishing the configuration file
$this->call('larascord:publish');

$this->alert('Please make sure you add "' . env('APP_URL', 'http://localhost:8000') . '/' . env('LARASCORD_PREFIX', 'larascord') . '/callback' . '" to your Discord application\'s redirect urls in the OAuth2 tab.');
$this->warn('If the domain doesn\'t match your current environment\'s domain you need to set it manually in the .env file. (APP_URL)');

$this->info('Larascord has been successfully installed!');
}

Expand All @@ -104,13 +108,13 @@ protected function validateInput()
$rules = [
'clientId' => ['required', 'numeric'],
'clientSecret' => ['required', 'string'],
'redirectUri' => ['required', 'url'],
'prefix' => ['required', 'string'],
];

$validator = Validator::make([
'clientId' => $this->clientId,
'clientSecret' => $this->clientSecret,
'redirectUri' => $this->redirectUri,
'prefix' => $this->prefix,
], $rules);

$validator->validate();
Expand All @@ -127,19 +131,19 @@ protected function appendToEnvFile()
(new Filesystem())->append('.env',PHP_EOL);

(new Filesystem())->append('.env',PHP_EOL);
(new Filesystem())->append('.env','DISCORD_CLIENT_ID='.$this->clientId);
(new Filesystem())->append('.env','LARASCORD_CLIENT_ID='.$this->clientId);

(new Filesystem())->append('.env',PHP_EOL);
(new Filesystem())->append('.env','DISCORD_CLIENT_SECRET='.$this->clientSecret);
(new Filesystem())->append('.env','LARASCORD_CLIENT_SECRET='.$this->clientSecret);

(new Filesystem())->append('.env',PHP_EOL);
(new Filesystem())->append('.env','DISCORD_GRANT_TYPE=authorization_code');
(new Filesystem())->append('.env','LARASCORD_GRANT_TYPE=authorization_code');

(new Filesystem())->append('.env',PHP_EOL);
(new Filesystem())->append('.env','DISCORD_REDIRECT_URI='.$this->redirectUri);
(new Filesystem())->append('.env','LARASCORD_PREFIX='.$this->prefix);

(new Filesystem())->append('.env',PHP_EOL);
(new Filesystem())->append('.env','DISCORD_SCOPE=identify&email');
(new Filesystem())->append('.env','LARASCORD_SCOPE=identify&email');
}

/**
Expand All @@ -165,35 +169,25 @@ public function createModelFiles()
}

/**
* Create the controller files.
* Create the view files.
*
* @return void
*/
public function createControllerFiles()
public function createViewFiles()
{
(new Filesystem())->ensureDirectoryExists(app_path('Http/Controllers'));
(new Filesystem())->copyDirectory(__DIR__ . '/../../Http/Controllers/', app_path('Http/Controllers/'));
}

/**
* Create the route files.
*
* @return void
*/
public function createRouteFiles() {
(new Filesystem())->ensureDirectoryExists(base_path('routes'));
(new Filesystem())->copyDirectory(__DIR__ . '/../../routes', base_path('routes'));
(new Filesystem())->ensureDirectoryExists(resource_path('views'));
(new Filesystem())->copyDirectory(__DIR__ . '/../../resources/views', resource_path('views'));
}

/**
* Create the view files.
*
* Removes Laravel Breeze's default routes and replaces them with Larascord's routes.
* @return void
*/
public function createViewFiles()
public function replaceBreezeRoutes()
{
(new Filesystem())->ensureDirectoryExists(resource_path('views'));
(new Filesystem())->copyDirectory(__DIR__ . '/../../resources/views', resource_path('views'));
(new Filesystem())->ensureDirectoryExists(resource_path('routes'));
(new Filesystem())->copy(__DIR__ . '/../../routes/web.php', base_path('routes/web.php'));
(new Filesystem())->delete(base_path('routes/auth.php'));
}

/**
Expand Down
55 changes: 55 additions & 0 deletions src/Console/Commands/PublishCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Jakyeru\Larascord\Console\Commands;

use Illuminate\Console\Command;

class PublishCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'larascord:publish
{--force : Overwrite any existing files.}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Use this command to publish Larascord\'s settings.';

/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
// Checking if the configuration has already been published.
if (file_exists(config_path('larascord.php')) && !$this->option('force')) {
$this->error('The configuration file has already been published.');
$this->error('If you want to overwrite the existing file, use the --force option.');

return;
}

// Checking if the command should be run forcefully.
if ($this->option('force')) {
$this->warn('This command is running in force mode. Any existing configuration file will be overwritten.');
}

// Publish the configuration file.
try {
shell_exec('php artisan vendor:publish --provider="Jakyeru\Larascord\LarascordServiceProvider" --tag=config' . ($this->option('force') ? ' --force' : ''));
} catch (\Exception $e) {
$this->error('Could not publish the configuration file.');
$this->error($e->getMessage());
}

// Inform the user that the command has finished.
$this->info('Larascord\'s settings have been published successfully.');
}
}
2 changes: 1 addition & 1 deletion src/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Controllers;
namespace Jakyeru\Larascord\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
Expand Down
13 changes: 6 additions & 7 deletions src/Http/Controllers/DiscordController.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<?php

namespace App\Http\Controllers;
namespace Jakyeru\Larascord\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Validation\ValidationException;

class DiscordController extends Controller
{
Expand All @@ -29,11 +28,11 @@ class DiscordController extends Controller
*/
public function __construct()
{
$this->tokenData['client_id'] = env('DISCORD_CLIENT_ID');
$this->tokenData['client_secret'] = env('DISCORD_CLIENT_SECRET');
$this->tokenData['grant_type'] = env('DISCORD_GRANT_TYPE');
$this->tokenData['redirect_uri'] = env('DISCORD_REDIRECT_URI');
$this->tokenData['scope'] = env('DISCORD_SCOPE');
$this->tokenData['client_id'] = config('larascord.client_id');
$this->tokenData['client_secret'] = config('larascord.client_secret');
$this->tokenData['grant_type'] = config('larascord.grant_type');
$this->tokenData['redirect_uri'] = config('larascord.redirect_uri');
$this->tokenData['scope'] = config('larascord.scopes');
}

/**
Expand Down
32 changes: 25 additions & 7 deletions src/LarascordServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,38 @@ class LarascordServiceProvider extends ServiceProvider
{
public function register()
{
$this->registerCommands();
if ($this->app->runningInConsole()) {
$this->registerCommands();
$this->registerConfiguration();
}
}

public function boot()
{
// $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
if ($this->app->runningInConsole()) {
$this->registerConfiguration();
}

$this->registerRoutes();
}

protected function registerCommands()
{
if ($this->app->runningInConsole()) {
$this->commands([
Console\Commands\InstallCommand::class,
]);
}
$this->commands([
Console\Commands\InstallCommand::class,
Console\Commands\PublishCommand::class,
]);
}

protected function registerConfiguration()
{
$this->publishes([
__DIR__.'./config/config.php' => config_path('larascord.php'),
], 'config');
}

protected function registerRoutes()
{
$this->loadRoutesFrom(__DIR__.'/routes/larascord.php');
}
}
Loading

0 comments on commit 3671668

Please sign in to comment.