-
Notifications
You must be signed in to change notification settings - Fork 0
Add php artisan login command for quick dev login
#20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c73c4fa
4dc1045
d87421b
e71011a
7c3977d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,70 @@ | ||||||||||||||||||||||
| <?php | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| namespace App\Console\Commands; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| use App\Models\User; | ||||||||||||||||||||||
| use Illuminate\Console\Command; | ||||||||||||||||||||||
| use Illuminate\Support\Facades\Hash; | ||||||||||||||||||||||
| use Illuminate\Support\Facades\Process; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| class LoginCommand extends Command | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| protected $signature = 'login {--email=dev@test.com : Email for the test user}'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| protected $description = 'Ensure a user exists and login via browser'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public function handle(): int | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $email = $this->option('email'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (! $this->shouldLogin()) { | ||||||||||||||||||||||
| $this->fixLoginRequirements($email); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $url = config('app.url'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->info("Logging in as: {$email}"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $result = Process::path(base_path()) | ||||||||||||||||||||||
| ->run(['npx', 'playwright', 'test', '--', 'node', 'scripts/login.cjs', $url, $email, 'password']); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (! $result->successful()) { | ||||||||||||||||||||||
| // Try direct node execution | ||||||||||||||||||||||
| $result = Process::path(base_path()) | ||||||||||||||||||||||
| ->run(['node', 'scripts/login.cjs', $url, $email, 'password']); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+28
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Simplify Playwright execution - the test runner isn't needed. The command Apply this diff to simplify: - $result = Process::path(base_path())
- ->run(['npx', 'playwright', 'test', '--', 'node', 'scripts/login.cjs', $url, $email, 'password']);
-
- if (! $result->successful()) {
- // Try direct node execution
- $result = Process::path(base_path())
- ->run(['node', 'scripts/login.cjs', $url, $email, 'password']);
- }
+ $result = Process::path(base_path())
+ ->run(['node', 'scripts/login.cjs', $url, $email, 'password']);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| $this->line($result->output()); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if ($result->failed()) { | ||||||||||||||||||||||
| $this->error($result->errorOutput()); | ||||||||||||||||||||||
| return self::FAILURE; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return self::SUCCESS; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| protected function shouldLogin(): bool | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| $email = $this->option('email'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (! User::where('email', $email)->exists()) { | ||||||||||||||||||||||
| return false; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return true; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| protected function fixLoginRequirements(string $email): void | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| if (! User::where('email', $email)->exists()) { | ||||||||||||||||||||||
| $this->info("Creating user: {$email}"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| User::create([ | ||||||||||||||||||||||
| 'name' => 'Dev User', | ||||||||||||||||||||||
| 'email' => $email, | ||||||||||||||||||||||
| 'password' => Hash::make('password'), | ||||||||||||||||||||||
| ]); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { chromium } = require('playwright'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix ESLint violation: use ES6 import syntax. The pipeline flagged this line: CommonJS Apply this diff to fix the import: -const { chromium } = require('playwright');
+import { chromium } from 'playwright';Also update
🧰 Tools🪛 GitHub Actions: linter[error] 1-1: ESLint: A 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const url = process.argv[2] || 'http://chat.test'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const email = process.argv[3] || 'dev@test.com'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const password = process.argv[4] || 'password'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const browser = await chromium.launch({ headless: false }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const page = await browser.newPage(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await page.goto(url + '/login'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await page.fill('input[type="email"], input[name="email"]', email); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await page.fill('input[type="password"], input[name="password"]', password); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await page.click('button[type="submit"]'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await page.waitForURL('**/dashboard**'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const finalUrl = page.url(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('Logged in as ' + email + ' - now on ' + finalUrl); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+7
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Memory leak - browser never closed. The browser instance is launched but never closed, causing a resource leak. Additionally, there's no error handling if navigation or form interactions fail. Apply this diff to fix both issues: (async () => {
- const browser = await chromium.launch({ headless: false });
- const page = await browser.newPage();
-
- await page.goto(url + '/login');
- await page.fill('input[type="email"], input[name="email"]', email);
- await page.fill('input[type="password"], input[name="password"]', password);
- await page.click('button[type="submit"]');
-
- await page.waitForURL('**/dashboard**');
-
- const finalUrl = page.url();
- console.log('Logged in as ' + email + ' - now on ' + finalUrl);
+ const browser = await chromium.launch({ headless: false });
+ try {
+ const page = await browser.newPage();
+
+ await page.goto(url + '/login', { timeout: 30000 });
+ await page.fill('input[type="email"], input[name="email"]', email);
+ await page.fill('input[type="password"], input[name="password"]', password);
+ await page.click('button[type="submit"]');
+
+ await page.waitForURL('**/dashboard**', { timeout: 30000 });
+
+ const finalUrl = page.url();
+ console.log('Logged in as ' + email + ' - now on ' + finalUrl);
+ } finally {
+ await browser.close();
+ }
})();📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add environment guards to prevent production use.
This command creates users with a known password ('password') and should never run in production. Add an environment check in the
handle()method to ensure it only runs in local/testing environments.Apply this diff to add a production guard:
public function handle(): int { + if (! app()->environment(['local', 'testing'])) { + $this->error('This command can only be run in local or testing environments.'); + return self::FAILURE; + } + $email = $this->option('email');🤖 Prompt for AI Agents