12 Commits

Author SHA1 Message Date
d33d0ba6a1 Change visit by js window.open 2025-03-01 14:21:59 +01:00
fcb3f8d7d8 try to finish the job 2025-03-01 13:32:07 +01:00
1bebf03a70 Merge branch 'main' into jobs/epic-games 2025-03-01 12:56:51 +01:00
025711e09d Updated dockerignore
All checks were successful
Push image to registry / build-image (push) Successful in 5m1s
2025-03-01 12:49:02 +01:00
5a30cdeae5 Made a script to patch latest selenium/standalone-chromedriver 2025-03-01 12:33:03 +01:00
7079206658 Added migration, schdule and signing in 2025-03-01 10:03:40 +01:00
db9d65f445 Fix job ordering 2025-03-01 10:02:47 +01:00
a1219b92ce Should fix
All checks were successful
Push image to registry / build-image (push) Successful in 7m31s
2025-02-28 17:05:47 +01:00
ce13d1b0dd Job qui enlève les vieilles jobRun
All checks were successful
Push image to registry / build-image (push) Successful in 6m18s
2025-02-27 18:54:40 +01:00
a80a32eee8 Added links to browser downloads and others
All checks were successful
Push image to registry / build-image (push) Successful in 6m20s
2025-02-27 17:57:54 +01:00
cd3491c5a8 Install reverb for broadcasting
All checks were successful
Push image to registry / build-image (push) Successful in 3m56s
2025-02-26 18:52:12 +01:00
9e55c98d47 Added TODO list 2025-02-26 18:28:42 +01:00
33 changed files with 1857 additions and 12 deletions

View File

@ -14,6 +14,7 @@ database/database.sqlite
**/.dockerignore
**/.env
**/.git
.gitea/
**/.gitignore
**/.project
**/.settings
@ -67,3 +68,5 @@ yarn-error.log
app/Browser/console/**
app/Browser/screenshots/**
app/Browser/source/**
undetectedChromedriver

View File

@ -69,3 +69,15 @@ VITE_APP_URL="${APP_URL}"
DUSK_DRIVER_URL="http://undetected-chromedriver:4444"
DUSK_START_MAXIMIZED=true
# Reverb (broadcasting)
REVERB_APP_ID=943562
REVERB_APP_KEY=jzysqfijn8wdgugrilbb
REVERB_APP_SECRET=gyotb3asui2zbrltd3ob
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

View File

@ -68,3 +68,16 @@ VITE_APP_URL="${APP_URL}"
DUSK_DRIVER_URL="http://127.0.0.1:4444"
DUSK_START_MAXIMIZED=true
# Reverb (broadcasting)
REVERB_APP_ID=943562
REVERB_APP_KEY=jzysqfijn8wdgugrilbb
REVERB_APP_SECRET=gyotb3asui2zbrltd3ob
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

5
.gitignore vendored
View File

@ -21,6 +21,11 @@ yarn-error.log
/.nova
/.vscode
/.zed
# Python projet
venv
__pycache__
# Browser
app/Browser/console
app/Browser/screenshots

View File

@ -156,6 +156,7 @@ abstract class BrowserJob implements ShouldQueue
'--whitelisted-ips=""',
'--disable-dev-shm-usage',
'--user-data-dir=/home/seluser/profile/',
'--auto-open-devtools-for-tabs',
])->all());
return RemoteWebDriver::create(

View File

@ -0,0 +1,47 @@
<?php
namespace App\Browser\Components\Hellcase;
use Laravel\Dusk\Browser;
use Laravel\Dusk\Component as BaseComponent;
class EpicGamesLogin extends BaseComponent
{
/**
* Get the root selector for the component.
*/
public function selector(): string
{
return 'form';
}
/**
* Assert that the browser page contains the component.
*/
public function assert(Browser $browser): void
{
$browser->assertVisible($this->selector());
}
/**
* Get the element shortcuts for the component.
*
* @return array<string, string>
*/
public function elements(): array
{
return [
'@email' => 'input#email',
'@password' => 'input#password',
'@signin-button' => 'button[type="submit"]',
];
}
public function fillForm(Browser $browser, $email, $password) {
$browser->type('@email', $email);
sleep(1);
$browser->type('@password', $password);
sleep(1);
$browser->click('@signin-button');
}
}

View File

@ -0,0 +1,174 @@
<?php
namespace App\Browser\Jobs\EpicGames;
use App\Browser\BrowserJob;
use App\Browser\Components\Hellcase\EpicGamesLogin;
use App\Models\JobInfo;
use App\Models\JobRun;
use App\Notification\Notifications\SimpleNotification;
use App\Notification\Providers\AllNotification;
use Exception;
use Facebook\WebDriver\WebDriverBy;
use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
use Illuminate\Support\Facades\Log;
use Laravel\Dusk\Browser;
class EpicGamesJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
{
private const APPROXIMATIVE_RUNNING_MINUTES = 2;
private const WEBSITE_URL = "https://www.epicgames.com/store/en-US/";
private JobRun $jobRun;
public function __construct()
{
Log::info("Constructing " . self::class);
parent::__construct(3);
}
public function run(Browser $browser): ?JobRun
{
// $browser->visit("https://bscscan.com/contractsVerified");
// sleep(3);
Log::info("Running " . self::class);
$this->jobRun = new JobRun([
"job_id" => $this->jobId,
"success" => false,
]);
$this->jobRun->save();
// $this->goToEpicGamesWebsite($browser);
// $this->removePopups($browser);
sleep(5);
$this->signin($browser);
$this->getFreeGames($browser);
$this->jobRun->success = true;
$this->jobRun->save();
Log::info(self::class . " run ended");
return $this->jobRun;
}
/**
* @inheritDoc
*/
public function runTest(Browser $browser): ?JobRun
{
try {
$this->goToEpicGamesWebsite($browser);
sleep(2);
$this->removePopups($browser);
sleep(2);
$this->signin($browser);
return $this->makeSimpleJobRun(
true,
"Connexion réussie",
"Datboi a réussi à se connecter sur EpicGames"
);
} catch (Exception $e) {
return $this->makeSimpleJobRun(
true,
"Connexion échouée",
"Datboi n'a pas réussi à se connecter sur EpicGames :\n" . $e->getMessage()
);
}
}
private function goToEpicGamesWebsite(Browser $browser)
{
sleep(3);
$browser->visit(self::WEBSITE_URL);
sleep(3);
$this->assertNotDetected($browser);
$browser->waitForText("Store", 30, true);
}
private function signin(Browser $browser)
{
// $browser->visit("https://store.epicgames.com/login?state=%2Fen-US%2F");
$browser->driver->executeScript('window.open("https://store.epicgames.com/login?state=%2Fen-US%2F")');
sleep(5);
$this->assertNotDetected($browser);
$browser->waitForText("Sign In", 30, true);
sleep(3);
$jobInfos = JobInfo::where("job_id", $this->jobId)->get();
$email = $jobInfos->where("key", "epicgames_account_email")->first()->value;
$password = $jobInfos->where("key", "epicgames_account_password")->first()->value;
$browser->within(new EpicGamesLogin, function (Browser $browser) use ($email, $password) {
$browser->fillForm($email, $password);
});
sleep(40);
}
private function getFreeGames(Browser $browser)
{
$browser->driver->executeScript('window.open("https://www.epicgames.com/store/en-US/free-games")');
// $browser->visit('https://www.epicgames.com/store/en-US/free-games');
$browser->waitForText("Free Games", 30, true);
$freeGamesLinkElements = $browser->driver->findElements(WebDriverBy::xpath('//a[contains(@aria-label, "Free Now")]'));
$freeGamesLinks = [];
foreach ($freeGamesLinkElements as $element) {
$freeGamesLinks[] = $element->getAttribute("href");
}
foreach ($freeGamesLinks as $link) {
$browser->visit($link);
$this->claimCurrentGame($browser);
}
}
private function claimCurrentGame(Browser $browser)
{
sleep(5);
$this->assertNotDetected($browser);
if ($this->unratedContent($browser)) {
throw new Exception("Le jeu demande un âge et datboi a la flemme de le mettre");
}
$this->waitForAndClickElementContainingText($browser, '//button', "Get", 30, true);
sleep(5);
$this->assertNotDetected($browser);
$browser->waitForText("Place Order", 30, true);
$browser->click("Place Order");
sleep(5);
$this->assertNotDetected($browser);
$browser->waitForText("Order Confirmation", 30, true);
$browser->click("Close");
sleep(5);
AllNotification::send(
new SimpleNotification($this->jobId, "Un jeu a été ajouté à votre bibliothèque", "Un jeu a été ajouté à votre bibliothèque EpicGames")
);
}
private function unratedContent(Browser $browser)
{
try {
$browser->waitForText("please provide your date of birth", 5, true);
return true;
} catch (Exception $_) {
return false;
}
}
private function removePopups(Browser $browser)
{
// $browser->script('document.querySelector("div.app-modal")[0].remove();');
// $browser->driver->executeScript('document.querySelector("div.app-modal")[0].remove();');
}
private function assertNotDetected(Browser $browser)
{
try {
$browser->waitForText("One more step", 10, true);
} catch (Exception $_) {
return;
}
throw new Exception("Détecté par cloudflare");
}
}

View File

@ -21,26 +21,27 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
{
private const STEAM_LOGIN_THRESHOLD = 5 * 60; // 5 minutes
private const APPROXIMATIVE_RUNNING_MINUTES = 2;
private const WEBSITE_URL = "https://hellcase.com";
private JobRun $jobRun;
public function __construct()
{
Log::info("Constructing HellcaseJob");
Log::info("Constructing " . self::class);
parent::__construct(2);
}
public function run(Browser $browser): ?JobRun
{
Log::info("Running HellcaseJob");
Log::info("Running " . self::class);
$this->jobRun = new JobRun([
"job_id" => $this->jobId,
"success" => false,
]);
$this->jobRun->save();
$browser->visit('https://hellcase.com');
$browser->waitForText("Store", 30, true);
$browser->visit(self::WEBSITE_URL);
$browser->waitForText("CASES", 30, true);
$this->removePopups($browser);
sleep(5);
$this->signin($browser);
@ -50,7 +51,7 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
$this->jobRun->success = true;
$this->jobRun->save();
Log::info("HellcaseJob run ended");
Log::info(self::class . " run ended");
return $this->jobRun;
}
@ -61,7 +62,7 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
public function runTest(Browser $browser): ?JobRun
{
try {
$browser->visit('https://hellcase.com');
$browser->visit(self::WEBSITE_URL);
$browser->waitForText("CASES", 30, true);
$this->removePopups($browser);
sleep(2);

View File

@ -0,0 +1,35 @@
<?php
namespace App\Jobs;
use App\Models\Job;
use App\Models\JobRun;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class PruneOldJobRuns implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
public function __construct()
{
//
}
/**
* Execute the job.
*/
public function handle(): void
{
// For each job, keep only the last N runs
foreach (Job::all() as $job) {
$job->jobRuns()
->orderByDesc('id')
->skip(config('jobs.pruneOldJobRuns.max_runs_per_job'))
->delete();
}
}
}

View File

@ -9,6 +9,7 @@ return Application::configure(basePath: dirname(__DIR__))
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
channels: __DIR__.'/../routes/channels.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {

View File

@ -14,6 +14,7 @@
"inertiajs/inertia-laravel": "^2.0",
"laravel/dusk": "^8.2",
"laravel/framework": "^11.31",
"laravel/reverb": "^1.0",
"laravel/sanctum": "^4.0",
"laravel/telescope": "^5.5",
"laravel/tinker": "^2.9",

1000
composer.lock generated

File diff suppressed because it is too large Load Diff

82
config/broadcasting.php Normal file
View File

@ -0,0 +1,82 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "reverb", "pusher", "ably", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_CONNECTION', 'reverb'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over WebSockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'reverb' => [
'driver' => 'reverb',
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
'app_id' => env('REVERB_APP_ID'),
'options' => [
'host' => env('REVERB_HOST'),
'port' => env('REVERB_PORT', 443),
'scheme' => env('REVERB_SCHEME', 'https'),
'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'ably' => [
'driver' => 'ably',
'key' => env('ABLY_KEY'),
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];

View File

@ -75,6 +75,10 @@ return [
'links' => [
public_path('storage') => storage_path('app/public'),
public_path('console') => base_path('app/Browser/console'),
public_path('downloads') => base_path('app/Browser/downloads'),
public_path('screenshots') => base_path('app/Browser/screenshots'),
public_path('source') => base_path('app/Browser/source'),
],
];

20
config/jobs.php Normal file
View File

@ -0,0 +1,20 @@
<?php
use Laravel\Telescope\Http\Middleware\Authorize;
use Laravel\Telescope\Watchers;
return [
/**
* Remove old job runs from the database.
*/
'pruneOldJobRuns' => [
'enabled' => true,
/**
* How many job runs a job can keep before we start pruning old ones.
*/
'max_runs_per_job' => 50,
],
];

92
config/reverb.php Normal file
View File

@ -0,0 +1,92 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Reverb Server
|--------------------------------------------------------------------------
|
| This option controls the default server used by Reverb to handle
| incoming messages as well as broadcasting message to all your
| connected clients. At this time only "reverb" is supported.
|
*/
'default' => env('REVERB_SERVER', 'reverb'),
/*
|--------------------------------------------------------------------------
| Reverb Servers
|--------------------------------------------------------------------------
|
| Here you may define details for each of the supported Reverb servers.
| Each server has its own configuration options that are defined in
| the array below. You should ensure all the options are present.
|
*/
'servers' => [
'reverb' => [
'host' => env('REVERB_SERVER_HOST', '0.0.0.0'),
'port' => env('REVERB_SERVER_PORT', 8080),
'hostname' => env('REVERB_HOST'),
'options' => [
'tls' => [],
],
'max_request_size' => env('REVERB_MAX_REQUEST_SIZE', 10_000),
'scaling' => [
'enabled' => env('REVERB_SCALING_ENABLED', false),
'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
'server' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'database' => env('REDIS_DB', '0'),
],
],
'pulse_ingest_interval' => env('REVERB_PULSE_INGEST_INTERVAL', 15),
'telescope_ingest_interval' => env('REVERB_TELESCOPE_INGEST_INTERVAL', 15),
],
],
/*
|--------------------------------------------------------------------------
| Reverb Applications
|--------------------------------------------------------------------------
|
| Here you may define how Reverb applications are managed. If you choose
| to use the "config" provider, you may define an array of apps which
| your server will support, including their connection credentials.
|
*/
'apps' => [
'provider' => 'config',
'apps' => [
[
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
'app_id' => env('REVERB_APP_ID'),
'options' => [
'host' => env('REVERB_HOST'),
'port' => env('REVERB_PORT', 443),
'scheme' => env('REVERB_SCHEME', 'https'),
'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
],
'allowed_origins' => ['*'],
'ping_interval' => env('REVERB_APP_PING_INTERVAL', 60),
'activity_timeout' => env('REVERB_APP_ACTIVITY_TIMEOUT', 30),
'max_message_size' => env('REVERB_APP_MAX_MESSAGE_SIZE', 10_000),
],
],
],
];

View File

@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
$jobId = 3;
\App\Models\Job::forcecreate([
'id' => $jobId,
'name' => 'Jeu gratuit Epic Games',
'description' => 'Prends le jeu gratuit Epic games. Tourne tous les jours.',
]);
\App\Models\JobInfo::forceCreate([
"key" => "epicgames_account_email",
"name" => "E-mail",
"description" => "L'adresse e-mail utilisée pour votre compte Epic Games.",
"job_info_type_id" => 2,
"job_id" => $jobId,
], );
\App\Models\JobInfo::forceCreate([
"key" => "epicgames_account_password",
"name" => "Mot de passe",
"description" => "Le mot de passe utilisé pour votre compte Epic Games.",
"job_info_type_id" => 3,
"job_id" => $jobId,
]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
\App\Models\Job::find(3)->delete();
\App\Models\JobInfo::where('job_id', 3)->delete();
}
};

View File

@ -12,8 +12,10 @@
"autoprefixer": "^10.4.12",
"axios": "^1.7.4",
"concurrently": "^9.0.1",
"laravel-echo": "^2.0.2",
"laravel-vite-plugin": "^1.2.0",
"postcss": "^8.4.31",
"pusher-js": "^8.4.0",
"sass-embedded": "^1.83.4",
"tailwindcss": "^3.2.1",
"typescript": "^5.6.3",

231
pnpm-lock.yaml generated
View File

@ -8,6 +8,9 @@ importers:
.:
dependencies:
'@vueuse/core':
specifier: ^12.5.0
version: 12.7.0(typescript@5.7.3)
class-variance-authority:
specifier: ^0.7.1
version: 0.7.1
@ -17,6 +20,12 @@ importers:
lucide-react:
specifier: ^0.474.0
version: 0.474.0(react@19.0.0)
lucide-vue-next:
specifier: ^0.474.0
version: 0.474.0(vue@3.5.13(typescript@5.7.3))
radix-vue:
specifier: ^1.9.13
version: 1.9.16(vue@3.5.13(typescript@5.7.3))
tailwind-merge:
specifier: ^2.6.0
version: 2.6.0
@ -42,12 +51,18 @@ importers:
concurrently:
specifier: ^9.0.1
version: 9.1.2
laravel-echo:
specifier: ^2.0.2
version: 2.0.2
laravel-vite-plugin:
specifier: ^1.2.0
version: 1.2.0(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0))
postcss:
specifier: ^8.4.31
version: 8.5.1
pusher-js:
specifier: ^8.4.0
version: 8.4.0
sass-embedded:
specifier: ^1.83.4
version: 1.83.4
@ -243,6 +258,18 @@ packages:
cpu: [x64]
os: [win32]
'@floating-ui/core@1.6.9':
resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==}
'@floating-ui/dom@1.6.13':
resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==}
'@floating-ui/utils@0.2.9':
resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
'@floating-ui/vue@1.1.6':
resolution: {integrity: sha512-XFlUzGHGv12zbgHNk5FN2mUB7ROul3oG2ENdTpWdE+qMFxyNxWSRmsoyhiEnpmabNm6WnUvR1OvJfUfN4ojC1A==}
'@inertiajs/core@2.0.3':
resolution: {integrity: sha512-JvXzqc2XAt3WgEDMyxCyXO6bDLMCsBjFsYREU1/+3wtNTib7QKwK71+aF+MrhILpz+kRTi29TsLqnbkPHBAZjw==}
@ -251,6 +278,12 @@ packages:
peerDependencies:
vue: ^3.0.0
'@internationalized/date@3.7.0':
resolution: {integrity: sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==}
'@internationalized/number@3.6.0':
resolution: {integrity: sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
@ -384,14 +417,28 @@ packages:
cpu: [x64]
os: [win32]
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
'@tailwindcss/forms@0.5.10':
resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==}
peerDependencies:
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
'@tanstack/virtual-core@3.13.2':
resolution: {integrity: sha512-Qzz4EgzMbO5gKrmqUondCjiHcuu4B1ftHb0pjCut661lXZdGoHeze9f/M8iwsK1t5LGR6aNuNGU7mxkowaW6RQ==}
'@tanstack/vue-virtual@3.13.2':
resolution: {integrity: sha512-z4swzjdhzCh95n9dw9lTvw+t3iwSkYRlVkYkra3C9mul/m5fTzHR7KmtkwH4qXMTXGJUbngtC/bz2cHQIHkO8g==}
peerDependencies:
vue: ^2.7.0 || ^3.0.0
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
'@vitejs/plugin-vue@5.2.1':
resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
engines: {node: ^18.0.0 || >=20.0.0}
@ -448,6 +495,24 @@ packages:
'@vue/shared@3.5.13':
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
'@vueuse/core@10.11.1':
resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
'@vueuse/core@12.7.0':
resolution: {integrity: sha512-jtK5B7YjZXmkGNHjviyGO4s3ZtEhbzSgrbX+s5o+Lr8i2nYqNyHuPVOeTdM1/hZ5Tkxg/KktAuAVDDiHMraMVA==}
'@vueuse/metadata@10.11.1':
resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
'@vueuse/metadata@12.7.0':
resolution: {integrity: sha512-4VvTH9mrjXqFN5LYa5YfqHVRI6j7R00Vy4995Rw7PQxyCL3z0Lli86iN4UemWqixxEvYfRjG+hF9wL8oLOn+3g==}
'@vueuse/shared@10.11.1':
resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
'@vueuse/shared@12.7.0':
resolution: {integrity: sha512-coLlUw2HHKsm7rPN6WqHJQr18WymN4wkA/3ThFaJ4v4gWGWAQQGK+MJxLuJTBs4mojQiazlVWAKNJNpUWGRkNw==}
alien-signals@0.4.14:
resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==}
@ -477,6 +542,10 @@ packages:
arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
aria-hidden@1.2.4:
resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
engines: {node: '>=10'}
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
@ -588,6 +657,9 @@ packages:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
@ -642,6 +714,9 @@ packages:
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-glob@3.3.3:
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
engines: {node: '>=8.6.0'}
@ -762,6 +837,10 @@ packages:
resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
hasBin: true
laravel-echo@2.0.2:
resolution: {integrity: sha512-Ciai6hA7r35MFqNRb8G034cvm9WiveSTFQQKRGJhWtZGbng7C8BBa5QvqDxk/Mw5GeJ+q19jrEwQhf7r1b1lcg==}
engines: {node: '>=20'}
laravel-vite-plugin@1.2.0:
resolution: {integrity: sha512-R0pJ+IcTVeqEMoKz/B2Ij57QVq3sFTABiFmb06gAwFdivbOgsUtuhX6N2MGLEArajrS3U5JbberzwOe7uXHMHQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@ -794,6 +873,11 @@ packages:
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
lucide-vue-next@0.474.0:
resolution: {integrity: sha512-bQaSBjfJ33xiPQCxCf4JD3rcUgZFgWZzxSY8SScNa4Mcq2vWGlbvQx6icTL1UXRqsxzfoT13RXawePSmgg4iWw==}
peerDependencies:
vue: '>=3.0.1'
magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
@ -840,6 +924,11 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
nanoid@5.1.2:
resolution: {integrity: sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==}
engines: {node: ^18 || >=20}
hasBin: true
node-releases@2.0.19:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
@ -939,6 +1028,9 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
pusher-js@8.4.0:
resolution: {integrity: sha512-wp3HqIIUc1GRyu1XrP6m2dgyE9MoCsXVsWNlohj0rjSkLf+a0jLvEyVubdg58oMk7bhjBWnFClgp8jfAa6Ak4Q==}
qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
@ -946,6 +1038,11 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
radix-vue@1.9.16:
resolution: {integrity: sha512-xwkTfQ7Ub/0XmT40JDc3g03xuYqKIJzVKGazcIkk8mUksj/tbw1pcCVRP0e3hKvPHKeQ0cktI1MvRnlUwCRvoQ==}
peerDependencies:
vue: '>= 3.2.0'
react@19.0.0:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'}
@ -1217,6 +1314,9 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
tweetnacl@1.0.3:
resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==}
typescript@5.7.3:
resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
engines: {node: '>=14.17'}
@ -1280,6 +1380,17 @@ packages:
vscode-uri@3.0.8:
resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
hasBin: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue-tsc@2.2.0:
resolution: {integrity: sha512-gtmM1sUuJ8aSb0KoAFmK9yMxb8TxjewmxqTJ1aKphD5Cbu0rULFY6+UQT51zW7SpUcenfPUuflKyVwyx9Qdnxg==}
hasBin: true
@ -1418,6 +1529,26 @@ snapshots:
'@esbuild/win32-x64@0.24.2':
optional: true
'@floating-ui/core@1.6.9':
dependencies:
'@floating-ui/utils': 0.2.9
'@floating-ui/dom@1.6.13':
dependencies:
'@floating-ui/core': 1.6.9
'@floating-ui/utils': 0.2.9
'@floating-ui/utils@0.2.9': {}
'@floating-ui/vue@1.1.6(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@floating-ui/dom': 1.6.13
'@floating-ui/utils': 0.2.9
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
'@inertiajs/core@2.0.3':
dependencies:
axios: 1.7.9
@ -1435,6 +1566,14 @@ snapshots:
transitivePeerDependencies:
- debug
'@internationalized/date@3.7.0':
dependencies:
'@swc/helpers': 0.5.15
'@internationalized/number@3.6.0':
dependencies:
'@swc/helpers': 0.5.15
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
@ -1533,13 +1672,26 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.32.1':
optional: true
'@swc/helpers@0.5.15':
dependencies:
tslib: 2.8.1
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.17)':
dependencies:
mini-svg-data-uri: 1.4.4
tailwindcss: 3.4.17
'@tanstack/virtual-core@3.13.2': {}
'@tanstack/vue-virtual@3.13.2(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@tanstack/virtual-core': 3.13.2
vue: 3.5.13(typescript@5.7.3)
'@types/estree@1.0.6': {}
'@types/web-bluetooth@0.0.20': {}
'@vitejs/plugin-vue@5.2.1(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))':
dependencies:
vite: 6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0)
@ -1629,6 +1781,42 @@ snapshots:
'@vue/shared@3.5.13': {}
'@vueuse/core@10.11.1(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 10.11.1
'@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.7.3))
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
'@vueuse/core@12.7.0(typescript@5.7.3)':
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 12.7.0
'@vueuse/shared': 12.7.0(typescript@5.7.3)
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
- typescript
'@vueuse/metadata@10.11.1': {}
'@vueuse/metadata@12.7.0': {}
'@vueuse/shared@10.11.1(vue@3.5.13(typescript@5.7.3))':
dependencies:
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3))
transitivePeerDependencies:
- '@vue/composition-api'
- vue
'@vueuse/shared@12.7.0(typescript@5.7.3)':
dependencies:
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
- typescript
alien-signals@0.4.14: {}
ansi-regex@5.0.1: {}
@ -1650,6 +1838,10 @@ snapshots:
arg@5.0.2: {}
aria-hidden@1.2.4:
dependencies:
tslib: 2.8.1
asynckit@0.4.0: {}
autoprefixer@10.4.20(postcss@8.5.1):
@ -1772,6 +1964,8 @@ snapshots:
deepmerge@4.3.1: {}
defu@6.1.4: {}
delayed-stream@1.0.0: {}
didyoumean@1.2.2: {}
@ -1834,6 +2028,8 @@ snapshots:
estree-walker@2.0.2: {}
fast-deep-equal@3.1.3: {}
fast-glob@3.3.3:
dependencies:
'@nodelib/fs.stat': 2.0.5
@ -1949,6 +2145,8 @@ snapshots:
jiti@1.21.7: {}
laravel-echo@2.0.2: {}
laravel-vite-plugin@1.2.0(vite@6.0.11(jiti@1.21.7)(sass-embedded@1.83.4)(yaml@2.7.0)):
dependencies:
picocolors: 1.1.1
@ -1971,6 +2169,10 @@ snapshots:
dependencies:
react: 19.0.0
lucide-vue-next@0.474.0(vue@3.5.13(typescript@5.7.3)):
dependencies:
vue: 3.5.13(typescript@5.7.3)
magic-string@0.30.17:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
@ -2008,6 +2210,8 @@ snapshots:
nanoid@3.3.8: {}
nanoid@5.1.2: {}
node-releases@2.0.19: {}
normalize-path@3.0.0: {}
@ -2080,12 +2284,33 @@ snapshots:
proxy-from-env@1.1.0: {}
pusher-js@8.4.0:
dependencies:
tweetnacl: 1.0.3
qs@6.14.0:
dependencies:
side-channel: 1.1.0
queue-microtask@1.2.3: {}
radix-vue@1.9.16(vue@3.5.13(typescript@5.7.3)):
dependencies:
'@floating-ui/dom': 1.6.13
'@floating-ui/vue': 1.1.6(vue@3.5.13(typescript@5.7.3))
'@internationalized/date': 3.7.0
'@internationalized/number': 3.6.0
'@tanstack/vue-virtual': 3.13.2(vue@3.5.13(typescript@5.7.3))
'@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.7.3))
'@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.7.3))
aria-hidden: 1.2.4
defu: 6.1.4
fast-deep-equal: 3.1.3
nanoid: 5.1.2
vue: 3.5.13(typescript@5.7.3)
transitivePeerDependencies:
- '@vue/composition-api'
react@19.0.0: {}
read-cache@1.0.0:
@ -2368,6 +2593,8 @@ snapshots:
tslib@2.8.1: {}
tweetnacl@1.0.3: {}
typescript@5.7.3: {}
update-browserslist-db@1.1.2(browserslist@4.24.4):
@ -2398,6 +2625,10 @@ snapshots:
vscode-uri@3.0.8: {}
vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)):
dependencies:
vue: 3.5.13(typescript@5.7.3)
vue-tsc@2.2.0(typescript@5.7.3):
dependencies:
'@volar/typescript': 2.4.11

1
public/console Symbolic link
View File

@ -0,0 +1 @@
/home/ninluc/Documents/codage/DatBrowser/app/Browser/console

1
public/downloads Symbolic link
View File

@ -0,0 +1 @@
/home/ninluc/Documents/codage/DatBrowser/app/Browser/downloads

1
public/screenshots Symbolic link
View File

@ -0,0 +1 @@
/home/ninluc/Documents/codage/DatBrowser/app/Browser/screenshots

1
public/source Symbolic link
View File

@ -0,0 +1 @@
/home/ninluc/Documents/codage/DatBrowser/app/Browser/source

View File

@ -11,7 +11,7 @@ const jobs = ref<Job[]>([]);
async function fetchJobs() {
let jobsRaw = await httpApi<Job[]>("/jobs");
jobs.value = jobsRaw.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
jobs.value = jobsRaw.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
}
onMounted(fetchJobs);

14
resources/js/echo.js Normal file
View File

@ -0,0 +1,14 @@
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});

4
routes/channels.php Normal file
View File

@ -0,0 +1,4 @@
<?php
use Illuminate\Support\Facades\Broadcast;

View File

@ -1,7 +1,8 @@
<?php
use App\Browser\Jobs\EpicGames\EpicGamesJob;
use App\Browser\Jobs\Hellcase\HellcaseJob;
use App\Models\Job;
use App\Jobs\PruneOldJobRuns;
use App\Services\BrowserJobsInstances;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
@ -13,6 +14,14 @@ Artisan::command('inspire', function () {
// Telescope
Schedule::command('telescope:prune')->monthly();
// Prune old job runs
Schedule::job(new PruneOldJobRuns)->monthly()->onOneServer()->withoutOverlapping()->name('prune-old-job-runs')->description('Prune old job runs')->skip(function () {
return !config('jobs.pruneOldJobRuns.enabled');
});
// Jobs
Schedule::job(new HellcaseJob)->daily()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
// Schedule::job(new HellcaseJob)->everyMinute()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
Schedule::job(new EpicGamesJob())->daily()->onOneServer()->withoutOverlapping()->name('epic-games')->description('Epic Games job');

20
todo.md Normal file
View File

@ -0,0 +1,20 @@
# TODO
- Fix hellcase, fermer lespopups à chaque nouvelle visite
- Voir si le scheduler fonctionne au démmarage
- Mettre un timeout pour pas overwhelm le pc au démmarage
- Image pour le join de giveaway
- → Notification
- Ou ajouter des images base64 dans les jobRun
- Risque de devenir volumineux
- Sauf avec le job qui enlève les vieilles jobRun
- Notification live websocket
- Websocket installé
- Serveur php plus propre (nginx, apache, n'importe)
- Epic games
## Pour deploy Lama
- Version Lama du compose
- Tuto installation

Binary file not shown.

View File

@ -1 +1,20 @@
sudo docker run --rm -it -p 3389:3389 -v ./undetectedChromedriver:/root/.local/share/undetected_chromedriver/ ultrafunk/undetected-chromedriver:latest
#!/bin/bash
# From undetected chromedriver docker
#sudo docker run --rm -it -p 3389:3389 -v ./undetectedChromedriver:/root/.local/share/undetected_chromedriver/ ultrafunk/undetected-chromedriver:latest
# With undetected chromedriver patcher
# Run the selenium/standalone-chrome:latest with a specific container name in the background
sudo docker run -d --name standalone-chrome selenium/standalone-chrome:latest
sleep 5
# Copy the chromedriver binary from the container to the host
sudo docker cp -L standalone-chrome:/bin/chromedriver ./chromedriver
# Stop the container
sudo docker stop standalone-chrome
sudo chmod 777 ./chromedriver
# Patch the chromedriver binary
python3 ./patchChromedriver.py

View File

@ -0,0 +1,8 @@
#!/bin/python3
import undetected_chromedriver as uc
options = uc.ChromeOptions()
# Chromedriver is in current directory
driver = uc.Chrome(options = options, browser_executable_path="/usr/bin/google-chrome", driver_executable_path="/home/ninluc/Documents/codage/DatBrowser/undetectedChromedriver/chromedriver")
driver.get('https://nowsecure.nl')

View File

@ -1,6 +1,7 @@
FROM selenium/standalone-chrome:108.0 AS final
# FROM selenium/standalone-chrome:108.0 AS final
FROM selenium/standalone-chrome:latest AS final
COPY undetectedChromedriver/chromedriver-linux /bin/chromedriver
COPY undetectedChromedriver/chromedriver /bin/chromedriver
RUN mkdir -p /home/seluser/profile/
ENV TZ=Europe/Brussels