diff --git a/.blueprint b/.blueprint
index d3837fc4..1c9ac7cf 100644
--- a/.blueprint
+++ b/.blueprint
@@ -5,10 +5,11 @@ models:
Course: { lecturer_id: biginteger, name: string }
Event: { course_id: biginteger, venue_id: biginteger, '"from"': datetime, '"to"': datetime }
Lecturer: { team_id: biginteger, name: string, slug: string, active: 'boolean default:1' }
+ LoginKey: { }
Membership: { team_id: biginteger, user_id: biginteger, role: 'string nullable' }
Participant: { first_name: string, last_name: string }
Registration: { event_id: biginteger, participant_id: biginteger, active: 'boolean default:1' }
Team: { user_id: biginteger, name: string, personal_team: boolean }
TeamInvitation: { team_id: biginteger, email: string, role: 'string nullable' }
- User: { name: string, email: string, email_verified_at: 'datetime nullable', password: string, remember_token: 'string:100 nullable', current_team_id: 'biginteger nullable', profile_photo_path: 'string:2048 nullable', is_lecturer: 'boolean default:', two_factor_secret: 'text nullable', two_factor_recovery_codes: 'text nullable', two_factor_confirmed_at: 'datetime nullable' }
+ User: { name: string, public_key: 'string nullable', email: 'string nullable', email_verified_at: 'datetime nullable', password: 'string nullable', remember_token: 'string:100 nullable', current_team_id: 'biginteger nullable', profile_photo_path: 'string:2048 nullable', is_lecturer: 'boolean default:', two_factor_secret: 'text nullable', two_factor_recovery_codes: 'text nullable', two_factor_confirmed_at: 'datetime nullable' }
Venue: { city_id: biginteger, name: string, slug: string, street: string }
diff --git a/app/Http/Livewire/Auth/LNUrlAuth.php b/app/Http/Livewire/Auth/LNUrlAuth.php
new file mode 100644
index 00000000..101bf672
--- /dev/null
+++ b/app/Http/Livewire/Auth/LNUrlAuth.php
@@ -0,0 +1,51 @@
+k1 = bin2hex(str()->random(32));
+ $this->lnurl = lnurl\encodeUrl(url('/lnurl-auth-callback',
+ ['tag' => 'login', 'k1' => $this->k1, 'action' => 'login']));
+ $this->qrCode = QrCode::size(300)
+ ->generate($this->lnurl);
+ }
+
+ public function checkAuth()
+ {
+ $loginKey = LoginKey::where('k1', $this->k1)
+ ->where('created_at', '<=', now()->subMinutes(5))
+ ->first();
+ // you should also restrict this 👆🏻 by time, and find only the $k1 that were created in the last 5 minutes
+
+ if ($loginKey) {
+ $user = User::find($loginKey->user_id);
+ auth()->login($user);
+ return to_route('welcome');
+ }
+
+ return true;
+ }
+
+ public function render()
+ {
+ return view('livewire.auth.ln-url-auth')->layout('layouts.guest');
+ }
+}
diff --git a/app/Models/LoginKey.php b/app/Models/LoginKey.php
new file mode 100644
index 00000000..a335843e
--- /dev/null
+++ b/app/Models/LoginKey.php
@@ -0,0 +1,23 @@
+=8.0.15",
+ "simplito/elliptic-php": "^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5.20",
+ "squizlabs/php_codesniffer": "^2.9.2"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/lnurl.php"
+ ],
+ "psr-4": {
+ "eza\\lnurl\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "DBAD"
+ ],
+ "authors": [
+ {
+ "name": "Enzo Zadrima",
+ "role": "Author"
+ }
+ ],
+ "description": "PHP implementation of LNURL Spec, including LNURL Auth",
+ "homepage": "https://github.com/eza/lnurl-php",
+ "support": {
+ "issues": "https://github.com/eza/lnurl-php/issues",
+ "source": "https://github.com/eza/lnurl-php/tree/1.0.1"
+ },
+ "time": "2022-05-08T12:55:38+00:00"
+ },
{
"name": "fruitcake/php-cors",
"version": "v1.2.0",
@@ -4534,6 +4630,221 @@
],
"time": "2022-07-25T00:44:21+00:00"
},
+ {
+ "name": "simplesoftwareio/simple-qrcode",
+ "version": "4.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/SimpleSoftwareIO/simple-qrcode.git",
+ "reference": "916db7948ca6772d54bb617259c768c9cdc8d537"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/SimpleSoftwareIO/simple-qrcode/zipball/916db7948ca6772d54bb617259c768c9cdc8d537",
+ "reference": "916db7948ca6772d54bb617259c768c9cdc8d537",
+ "shasum": ""
+ },
+ "require": {
+ "bacon/bacon-qr-code": "^2.0",
+ "ext-gd": "*",
+ "php": ">=7.2|^8.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~1",
+ "phpunit/phpunit": "~9"
+ },
+ "suggest": {
+ "ext-imagick": "Allows the generation of PNG QrCodes.",
+ "illuminate/support": "Allows for use within Laravel."
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "SimpleSoftwareIO\\QrCode\\QrCodeServiceProvider"
+ ],
+ "aliases": {
+ "QrCode": "SimpleSoftwareIO\\QrCode\\Facades\\QrCode"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "SimpleSoftwareIO\\QrCode\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Simple Software LLC",
+ "email": "support@simplesoftware.io"
+ }
+ ],
+ "description": "Simple QrCode is a QR code generator made for Laravel.",
+ "homepage": "https://www.simplesoftware.io/#/docs/simple-qrcode",
+ "keywords": [
+ "Simple",
+ "generator",
+ "laravel",
+ "qrcode",
+ "wrapper"
+ ],
+ "support": {
+ "issues": "https://github.com/SimpleSoftwareIO/simple-qrcode/issues",
+ "source": "https://github.com/SimpleSoftwareIO/simple-qrcode/tree/4.2.0"
+ },
+ "time": "2021-02-08T20:43:55+00:00"
+ },
+ {
+ "name": "simplito/bigint-wrapper-php",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/simplito/bigint-wrapper-php.git",
+ "reference": "cf21ec76d33f103add487b3eadbd9f5033a25930"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/simplito/bigint-wrapper-php/zipball/cf21ec76d33f103add487b3eadbd9f5033a25930",
+ "reference": "cf21ec76d33f103add487b3eadbd9f5033a25930",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BI\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Simplito Team",
+ "email": "s.smyczynski@simplito.com",
+ "homepage": "https://simplito.com"
+ }
+ ],
+ "description": "Common interface for php_gmp and php_bcmath modules",
+ "support": {
+ "issues": "https://github.com/simplito/bigint-wrapper-php/issues",
+ "source": "https://github.com/simplito/bigint-wrapper-php/tree/1.0.0"
+ },
+ "time": "2018-02-27T12:38:08+00:00"
+ },
+ {
+ "name": "simplito/bn-php",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/simplito/bn-php.git",
+ "reference": "189167f940cdb681288a967b0f4d66de81adcd97"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/simplito/bn-php/zipball/189167f940cdb681288a967b0f4d66de81adcd97",
+ "reference": "189167f940cdb681288a967b0f4d66de81adcd97",
+ "shasum": ""
+ },
+ "require": {
+ "simplito/bigint-wrapper-php": "~1.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BN\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Simplito Team",
+ "email": "s.smyczynski@simplito.com",
+ "homepage": "https://simplito.com"
+ }
+ ],
+ "description": "Big number implementation compatible with bn.js",
+ "support": {
+ "issues": "https://github.com/simplito/bn-php/issues",
+ "source": "https://github.com/simplito/bn-php/tree/1.1.3"
+ },
+ "time": "2022-08-12T18:58:14+00:00"
+ },
+ {
+ "name": "simplito/elliptic-php",
+ "version": "1.0.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/simplito/elliptic-php.git",
+ "reference": "a6228f480c729cf8efe2650a617c8500e981716d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/simplito/elliptic-php/zipball/a6228f480c729cf8efe2650a617c8500e981716d",
+ "reference": "a6228f480c729cf8efe2650a617c8500e981716d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-gmp": "*",
+ "simplito/bn-php": "~1.1.0"
+ },
+ "require-dev": {
+ "phpbench/phpbench": "@dev",
+ "phpunit/phpunit": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Elliptic\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Simplito Team",
+ "email": "s.smyczynski@simplito.com",
+ "homepage": "https://simplito.com"
+ }
+ ],
+ "description": "Fast elliptic curve cryptography",
+ "homepage": "https://github.com/simplito/elliptic-php",
+ "keywords": [
+ "Curve25519",
+ "ECDSA",
+ "Ed25519",
+ "EdDSA",
+ "cryptography",
+ "curve",
+ "curve25519-weier",
+ "ecc",
+ "ecdh",
+ "elliptic",
+ "nistp192",
+ "nistp224",
+ "nistp256",
+ "nistp384",
+ "nistp521",
+ "secp256k1"
+ ],
+ "support": {
+ "issues": "https://github.com/simplito/elliptic-php/issues",
+ "source": "https://github.com/simplito/elliptic-php/tree/1.0.10"
+ },
+ "time": "2022-08-12T19:00:25+00:00"
+ },
{
"name": "spatie/laravel-google-fonts",
"version": "1.2.1",
diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php
index e05cead8..35e74c03 100644
--- a/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/database/migrations/2014_10_12_000000_create_users_table.php
@@ -14,11 +14,16 @@ return new class extends Migration {
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
+ $table->string('public_key')
+ ->unique()
+ ->nullable();
$table->string('email')
- ->unique();
+ ->unique()
+ ->nullable();
$table->timestamp('email_verified_at')
->nullable();
- $table->string('password');
+ $table->string('password')
+ ->nullable();
$table->rememberToken();
$table->foreignId('current_team_id')
->nullable();
diff --git a/database/migrations/2022_12_01_180529_create_login_keys_table.php b/database/migrations/2022_12_01_180529_create_login_keys_table.php
new file mode 100644
index 00000000..de64c8f2
--- /dev/null
+++ b/database/migrations/2022_12_01_180529_create_login_keys_table.php
@@ -0,0 +1,31 @@
+id();
+ $table->string('k1');
+ $table->foreignId('user_id')
+ ->index();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('login_keys');
+ }
+};
diff --git a/docker-compose.yml b/docker-compose.yml
index 51e14da3..3c145640 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,7 +3,7 @@ version: '3'
services:
laravel.test:
build:
- context: ./vendor/laravel/sail/runtimes/8.1
+ context: ./docker/8.1
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
diff --git a/docker/7.4/Dockerfile b/docker/7.4/Dockerfile
new file mode 100644
index 00000000..2184e49a
--- /dev/null
+++ b/docker/7.4/Dockerfile
@@ -0,0 +1,62 @@
+FROM ubuntu:20.04
+
+LABEL maintainer="Taylor Otwell"
+
+ARG WWWGROUP
+ARG NODE_VERSION=16
+ARG POSTGRES_VERSION=13
+
+WORKDIR /var/www/html
+
+ENV DEBIAN_FRONTEND noninteractive
+ENV TZ=UTC
+
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+RUN apt-get update \
+ && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
+ && mkdir -p ~/.gnupg \
+ && chmod 600 ~/.gnupg \
+ && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
+ && echo "keyserver hkp://keyserver.ubuntu.com:80" >> ~/.gnupg/dirmngr.conf \
+ && gpg --recv-key 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c \
+ && gpg --export 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c > /usr/share/keyrings/ppa_ondrej_php.gpg \
+ && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu focal main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
+ && apt-get update \
+ && apt-get install -y php7.4-cli php7.4-dev \
+ php7.4-pgsql php7.4-sqlite3 php7.4-gd \
+ php7.4-curl php7.4-memcached \
+ php7.4-imap php7.4-mysql php7.4-mbstring \
+ php7.4-xml php7.4-zip php7.4-bcmath php7.4-soap \
+ php7.4-intl php7.4-readline php7.4-pcov \
+ php7.4-msgpack php7.4-igbinary php7.4-ldap \
+ php7.4-redis php7.4-xdebug \
+ && php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
+ && curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \
+ && apt-get install -y nodejs \
+ && npm install -g npm \
+ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
+ && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt focal-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
+ && apt-get update \
+ && apt-get install -y yarn \
+ && apt-get install -y mysql-client \
+ && apt-get install -y postgresql-client-$POSTGRES_VERSION \
+ && apt-get -y autoremove \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+RUN setcap "cap_net_bind_service=+ep" /usr/bin/php7.4
+
+RUN groupadd --force -g $WWWGROUP sail
+RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
+
+COPY start-container /usr/local/bin/start-container
+COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+COPY php.ini /etc/php/7.4/cli/conf.d/99-sail.ini
+RUN chmod +x /usr/local/bin/start-container
+
+EXPOSE 8000
+
+ENTRYPOINT ["start-container"]
diff --git a/docker/7.4/php.ini b/docker/7.4/php.ini
new file mode 100644
index 00000000..66d04d5b
--- /dev/null
+++ b/docker/7.4/php.ini
@@ -0,0 +1,4 @@
+[PHP]
+post_max_size = 100M
+upload_max_filesize = 100M
+variables_order = EGPCS
diff --git a/docker/7.4/start-container b/docker/7.4/start-container
new file mode 100644
index 00000000..b8643990
--- /dev/null
+++ b/docker/7.4/start-container
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+if [ ! -z "$WWWUSER" ]; then
+ usermod -u $WWWUSER sail
+fi
+
+if [ ! -d /.composer ]; then
+ mkdir /.composer
+fi
+
+chmod -R ugo+rw /.composer
+
+if [ $# -gt 0 ]; then
+ exec gosu $WWWUSER "$@"
+else
+ exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
+fi
diff --git a/docker/7.4/supervisord.conf b/docker/7.4/supervisord.conf
new file mode 100644
index 00000000..9d284795
--- /dev/null
+++ b/docker/7.4/supervisord.conf
@@ -0,0 +1,14 @@
+[supervisord]
+nodaemon=true
+user=root
+logfile=/var/log/supervisor/supervisord.log
+pidfile=/var/run/supervisord.pid
+
+[program:php]
+command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80
+user=sail
+environment=LARAVEL_SAIL="1"
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
diff --git a/docker/8.0/Dockerfile b/docker/8.0/Dockerfile
new file mode 100644
index 00000000..15456ca8
--- /dev/null
+++ b/docker/8.0/Dockerfile
@@ -0,0 +1,64 @@
+FROM ubuntu:20.04
+
+LABEL maintainer="Taylor Otwell"
+
+ARG WWWGROUP
+ARG NODE_VERSION=16
+ARG POSTGRES_VERSION=13
+
+WORKDIR /var/www/html
+
+ENV DEBIAN_FRONTEND noninteractive
+ENV TZ=UTC
+
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+RUN apt-get update \
+ && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
+ && mkdir -p ~/.gnupg \
+ && chmod 600 ~/.gnupg \
+ && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
+ && echo "keyserver hkp://keyserver.ubuntu.com:80" >> ~/.gnupg/dirmngr.conf \
+ && gpg --recv-key 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c \
+ && gpg --export 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c > /usr/share/keyrings/ppa_ondrej_php.gpg \
+ && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu focal main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
+ && apt-get update \
+ && apt-get install -y php8.0-cli php8.0-dev \
+ php8.0-pgsql php8.0-sqlite3 php8.0-gd \
+ php8.0-curl php8.0-memcached \
+ php8.0-imap php8.0-mysql php8.0-mbstring \
+ php8.0-xml php8.0-zip php8.0-bcmath php8.0-soap \
+ php8.0-intl php8.0-readline php8.0-pcov \
+ php8.0-msgpack php8.0-igbinary php8.0-ldap \
+ php8.0-redis php8.0-swoole php8.0-xdebug \
+ && php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
+ && curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \
+ && apt-get install -y nodejs \
+ && npm install -g npm \
+ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
+ && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt focal-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
+ && apt-get update \
+ && apt-get install -y yarn \
+ && apt-get install -y mysql-client \
+ && apt-get install -y postgresql-client-$POSTGRES_VERSION \
+ && apt-get -y autoremove \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+RUN update-alternatives --set php /usr/bin/php8.0
+
+RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.0
+
+RUN groupadd --force -g $WWWGROUP sail
+RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
+
+COPY start-container /usr/local/bin/start-container
+COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+COPY php.ini /etc/php/8.0/cli/conf.d/99-sail.ini
+RUN chmod +x /usr/local/bin/start-container
+
+EXPOSE 8000
+
+ENTRYPOINT ["start-container"]
diff --git a/docker/8.0/php.ini b/docker/8.0/php.ini
new file mode 100644
index 00000000..66d04d5b
--- /dev/null
+++ b/docker/8.0/php.ini
@@ -0,0 +1,4 @@
+[PHP]
+post_max_size = 100M
+upload_max_filesize = 100M
+variables_order = EGPCS
diff --git a/docker/8.0/start-container b/docker/8.0/start-container
new file mode 100644
index 00000000..b8643990
--- /dev/null
+++ b/docker/8.0/start-container
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+if [ ! -z "$WWWUSER" ]; then
+ usermod -u $WWWUSER sail
+fi
+
+if [ ! -d /.composer ]; then
+ mkdir /.composer
+fi
+
+chmod -R ugo+rw /.composer
+
+if [ $# -gt 0 ]; then
+ exec gosu $WWWUSER "$@"
+else
+ exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
+fi
diff --git a/docker/8.0/supervisord.conf b/docker/8.0/supervisord.conf
new file mode 100644
index 00000000..9d284795
--- /dev/null
+++ b/docker/8.0/supervisord.conf
@@ -0,0 +1,14 @@
+[supervisord]
+nodaemon=true
+user=root
+logfile=/var/log/supervisor/supervisord.log
+pidfile=/var/run/supervisord.pid
+
+[program:php]
+command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80
+user=sail
+environment=LARAVEL_SAIL="1"
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
diff --git a/docker/8.1/Dockerfile b/docker/8.1/Dockerfile
new file mode 100644
index 00000000..9343b645
--- /dev/null
+++ b/docker/8.1/Dockerfile
@@ -0,0 +1,63 @@
+FROM ubuntu:22.04
+
+LABEL maintainer="Taylor Otwell"
+
+ARG WWWGROUP
+ARG NODE_VERSION=16
+ARG POSTGRES_VERSION=14
+
+WORKDIR /var/www/html
+
+ENV DEBIAN_FRONTEND noninteractive
+ENV TZ=UTC
+
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+RUN apt-get update \
+ && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
+ && mkdir -p ~/.gnupg \
+ && chmod 600 ~/.gnupg \
+ && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
+ && echo "keyserver hkp://keyserver.ubuntu.com:80" >> ~/.gnupg/dirmngr.conf \
+ && gpg --recv-key 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c \
+ && gpg --export 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c > /usr/share/keyrings/ppa_ondrej_php.gpg \
+ && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
+ && apt-get update \
+ && apt-get install -y php8.1-cli php8.1-dev \
+ php8.1-pgsql php8.1-sqlite3 php8.1-gd \
+ php8.1-curl \
+ php8.1-imap php8.1-mysql php8.1-mbstring \
+ php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \
+ php8.1-intl php8.1-readline \
+ php8.1-ldap php8.1-gmp \
+ php8.1-msgpack php8.1-igbinary php8.1-redis php8.1-swoole \
+ php8.1-memcached php8.1-pcov php8.1-xdebug \
+ && php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
+ && curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \
+ && apt-get install -y nodejs \
+ && npm install -g npm \
+ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
+ && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
+ && apt-get update \
+ && apt-get install -y yarn \
+ && apt-get install -y mysql-client \
+ && apt-get install -y postgresql-client-$POSTGRES_VERSION \
+ && apt-get -y autoremove \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1
+
+RUN groupadd --force -g $WWWGROUP sail
+RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
+
+COPY start-container /usr/local/bin/start-container
+COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+COPY php.ini /etc/php/8.1/cli/conf.d/99-sail.ini
+RUN chmod +x /usr/local/bin/start-container
+
+EXPOSE 8000
+
+ENTRYPOINT ["start-container"]
diff --git a/docker/8.1/php.ini b/docker/8.1/php.ini
new file mode 100644
index 00000000..66d04d5b
--- /dev/null
+++ b/docker/8.1/php.ini
@@ -0,0 +1,4 @@
+[PHP]
+post_max_size = 100M
+upload_max_filesize = 100M
+variables_order = EGPCS
diff --git a/docker/8.1/start-container b/docker/8.1/start-container
new file mode 100644
index 00000000..b8643990
--- /dev/null
+++ b/docker/8.1/start-container
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+if [ ! -z "$WWWUSER" ]; then
+ usermod -u $WWWUSER sail
+fi
+
+if [ ! -d /.composer ]; then
+ mkdir /.composer
+fi
+
+chmod -R ugo+rw /.composer
+
+if [ $# -gt 0 ]; then
+ exec gosu $WWWUSER "$@"
+else
+ exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
+fi
diff --git a/docker/8.1/supervisord.conf b/docker/8.1/supervisord.conf
new file mode 100644
index 00000000..9d284795
--- /dev/null
+++ b/docker/8.1/supervisord.conf
@@ -0,0 +1,14 @@
+[supervisord]
+nodaemon=true
+user=root
+logfile=/var/log/supervisor/supervisord.log
+pidfile=/var/run/supervisord.pid
+
+[program:php]
+command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80
+user=sail
+environment=LARAVEL_SAIL="1"
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
diff --git a/docker/8.2/Dockerfile b/docker/8.2/Dockerfile
new file mode 100644
index 00000000..e177eb8e
--- /dev/null
+++ b/docker/8.2/Dockerfile
@@ -0,0 +1,63 @@
+FROM ubuntu:22.04
+
+LABEL maintainer="Taylor Otwell"
+
+ARG WWWGROUP
+ARG NODE_VERSION=16
+ARG POSTGRES_VERSION=14
+
+WORKDIR /var/www/html
+
+ENV DEBIAN_FRONTEND noninteractive
+ENV TZ=UTC
+
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+RUN apt-get update \
+ && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
+ && mkdir -p ~/.gnupg \
+ && chmod 600 ~/.gnupg \
+ && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
+ && echo "keyserver hkp://keyserver.ubuntu.com:80" >> ~/.gnupg/dirmngr.conf \
+ && gpg --recv-key 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c \
+ && gpg --export 0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c > /usr/share/keyrings/ppa_ondrej_php.gpg \
+ && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \
+ && apt-get update \
+ && apt-get install -y php8.2-cli php8.2-dev \
+ php8.2-pgsql php8.2-sqlite3 php8.2-gd \
+ php8.2-curl \
+ php8.2-imap php8.2-mysql php8.2-mbstring \
+ php8.2-xml php8.2-zip php8.2-bcmath php8.2-soap \
+ php8.2-intl php8.2-readline \
+ php8.2-ldap \
+ # php8.2-msgpack php8.2-igbinary php8.2-redis php8.2-swoole \
+ # php8.2-memcached php8.2-pcov php8.2-xdebug \
+ && php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
+ && curl -sLS https://deb.nodesource.com/setup_$NODE_VERSION.x | bash - \
+ && apt-get install -y nodejs \
+ && npm install -g npm \
+ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \
+ && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
+ && apt-get update \
+ && apt-get install -y yarn \
+ && apt-get install -y mysql-client \
+ && apt-get install -y postgresql-client-$POSTGRES_VERSION \
+ && apt-get -y autoremove \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.2
+
+RUN groupadd --force -g $WWWGROUP sail
+RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail
+
+COPY start-container /usr/local/bin/start-container
+COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+COPY php.ini /etc/php/8.2/cli/conf.d/99-sail.ini
+RUN chmod +x /usr/local/bin/start-container
+
+EXPOSE 8000
+
+ENTRYPOINT ["start-container"]
diff --git a/docker/8.2/php.ini b/docker/8.2/php.ini
new file mode 100644
index 00000000..66d04d5b
--- /dev/null
+++ b/docker/8.2/php.ini
@@ -0,0 +1,4 @@
+[PHP]
+post_max_size = 100M
+upload_max_filesize = 100M
+variables_order = EGPCS
diff --git a/docker/8.2/start-container b/docker/8.2/start-container
new file mode 100644
index 00000000..b8643990
--- /dev/null
+++ b/docker/8.2/start-container
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+if [ ! -z "$WWWUSER" ]; then
+ usermod -u $WWWUSER sail
+fi
+
+if [ ! -d /.composer ]; then
+ mkdir /.composer
+fi
+
+chmod -R ugo+rw /.composer
+
+if [ $# -gt 0 ]; then
+ exec gosu $WWWUSER "$@"
+else
+ exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
+fi
diff --git a/docker/8.2/supervisord.conf b/docker/8.2/supervisord.conf
new file mode 100644
index 00000000..9d284795
--- /dev/null
+++ b/docker/8.2/supervisord.conf
@@ -0,0 +1,14 @@
+[supervisord]
+nodaemon=true
+user=root
+logfile=/var/log/supervisor/supervisord.log
+pidfile=/var/run/supervisord.pid
+
+[program:php]
+command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80
+user=sail
+environment=LARAVEL_SAIL="1"
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
diff --git a/resources/views/livewire/auth/ln-url-auth.blade.php b/resources/views/livewire/auth/ln-url-auth.blade.php
new file mode 100644
index 00000000..ad0e913b
--- /dev/null
+++ b/resources/views/livewire/auth/ln-url-auth.blade.php
@@ -0,0 +1,25 @@
+