mirror of
https://github.com/Einundzwanzig-Podcast/einundzwanzig-portal.git
synced 2025-12-11 06:46:47 +00:00
encrypt user data
This commit is contained in:
@@ -13,10 +13,15 @@ use Laravel\Sanctum\HasApiTokens;
|
||||
use QCod\Gamify\Gamify;
|
||||
use Spatie\Comments\Models\Concerns\InteractsWithComments;
|
||||
use Spatie\Comments\Models\Concerns\Interfaces\CanComment;
|
||||
use Spatie\LaravelCipherSweet\Concerns\UsesCipherSweet;
|
||||
use Spatie\LaravelCipherSweet\Contracts\CipherSweetEncrypted;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
use ParagonIE\CipherSweet\EncryptedRow;
|
||||
use ParagonIE\CipherSweet\BlindIndex;
|
||||
|
||||
class User extends Authenticatable implements MustVerifyEmail, CanComment
|
||||
class User extends Authenticatable implements MustVerifyEmail, CanComment, CipherSweetEncrypted
|
||||
{
|
||||
use UsesCipherSweet;
|
||||
use HasApiTokens;
|
||||
use HasFactory;
|
||||
use HasProfilePhoto;
|
||||
@@ -56,6 +61,21 @@ class User extends Authenticatable implements MustVerifyEmail, CanComment
|
||||
'profile_photo_url',
|
||||
];
|
||||
|
||||
public static function configureCipherSweet(EncryptedRow $encryptedRow): void
|
||||
{
|
||||
$encryptedRow
|
||||
->addField('public_key')
|
||||
->addField('lightning_address')
|
||||
->addField('lnurl')
|
||||
->addField('node_id')
|
||||
->addField('email')
|
||||
->addBlindIndex('public_key', new BlindIndex('public_key_index'))
|
||||
->addBlindIndex('lightning_address', new BlindIndex('lightning_address_index'))
|
||||
->addBlindIndex('lnurl', new BlindIndex('lnurl_index'))
|
||||
->addBlindIndex('node_id', new BlindIndex('node_id_index'))
|
||||
->addBlindIndex('email', new BlindIndex('email_index'));
|
||||
}
|
||||
|
||||
public function orangePills()
|
||||
{
|
||||
return $this->hasMany(OrangePill::class);
|
||||
|
||||
@@ -30,7 +30,7 @@ class User extends Resource
|
||||
* @var array
|
||||
*/
|
||||
public static $search = [
|
||||
'id', 'name', 'email',
|
||||
'id', 'name',
|
||||
];
|
||||
|
||||
public static function label()
|
||||
|
||||
@@ -9,14 +9,17 @@ use App\Actions\Jetstream\DeleteUser;
|
||||
use App\Actions\Jetstream\InviteTeamMember;
|
||||
use App\Actions\Jetstream\RemoveTeamMember;
|
||||
use App\Actions\Jetstream\UpdateTeamName;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Fortify\Fortify;
|
||||
use Laravel\Jetstream\Jetstream;
|
||||
|
||||
class JetstreamServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
@@ -26,7 +29,6 @@ class JetstreamServiceProvider extends ServiceProvider
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
@@ -40,11 +42,22 @@ class JetstreamServiceProvider extends ServiceProvider
|
||||
Jetstream::removeTeamMembersUsing(RemoveTeamMember::class);
|
||||
Jetstream::deleteTeamsUsing(DeleteTeam::class);
|
||||
Jetstream::deleteUsersUsing(DeleteUser::class);
|
||||
|
||||
Fortify::authenticateUsing(function (Request $request) {
|
||||
$user = User::query()
|
||||
->whereBlind('email', 'email_index', $request->email)
|
||||
->first();
|
||||
|
||||
if ($user &&
|
||||
Hash::check($request->password, $user->password)) {
|
||||
|
||||
return $user;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the roles and permissions that are available within the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configurePermissions()
|
||||
@@ -56,12 +69,14 @@ class JetstreamServiceProvider extends ServiceProvider
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
])->description('Administrator users can perform any action.');
|
||||
])
|
||||
->description('Administrator users can perform any action.');
|
||||
|
||||
Jetstream::role('editor', 'Editor', [
|
||||
'read',
|
||||
'create',
|
||||
'update',
|
||||
])->description('Editor users have the ability to read, create, and update.');
|
||||
])
|
||||
->description('Editor users have the ability to read, create, and update.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"simplito/elliptic-php": "^1.0",
|
||||
"spatie/eloquent-sortable": "^4.0",
|
||||
"spatie/icalendar-generator": "^2.5",
|
||||
"spatie/laravel-ciphersweet": "^1.0",
|
||||
"spatie/laravel-comments": "^1.4",
|
||||
"spatie/laravel-comments-livewire": "^1.2",
|
||||
"spatie/laravel-google-fonts": "^1.2",
|
||||
|
||||
135
composer.lock
generated
135
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "de6fecaf71d0b9f0abef4ce825043f92",
|
||||
"content-hash": "1c4001e831e2129cc09124c228198ef2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "akuechler/laravel-geoly",
|
||||
@@ -5400,6 +5400,67 @@
|
||||
],
|
||||
"time": "2023-01-19T13:22:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/ciphersweet",
|
||||
"version": "v4.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/ciphersweet.git",
|
||||
"reference": "7459af64c412453ffa8813518c44292a9742c326"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/ciphersweet/zipball/7459af64c412453ffa8813518c44292a9742c326",
|
||||
"reference": "7459af64c412453ffa8813518c44292a9742c326",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"paragonie/constant_time_encoding": "^2",
|
||||
"paragonie/sodium_compat": ">= 1.17 <2",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9",
|
||||
"vimeo/psalm": "^4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ParagonIE\\CipherSweet\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"ISC"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "Searchable field-level encryption library for relational databases",
|
||||
"keywords": [
|
||||
"FIPS 140-2",
|
||||
"SQL encryption",
|
||||
"crm",
|
||||
"cryptography",
|
||||
"database encryption",
|
||||
"encrypt",
|
||||
"encryption",
|
||||
"field-level encryption",
|
||||
"libsodium",
|
||||
"queryable encryption",
|
||||
"searchable encryption"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/paragonie/ciphersweet/issues",
|
||||
"source": "https://github.com/paragonie/ciphersweet/tree/v4.2.0"
|
||||
},
|
||||
"time": "2023-01-15T19:02:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v2.6.3",
|
||||
@@ -8259,6 +8320,78 @@
|
||||
},
|
||||
"time": "2021-12-21T10:08:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-ciphersweet",
|
||||
"version": "1.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/laravel-ciphersweet.git",
|
||||
"reference": "cc336648b94f88e9d0fd4be11c14e61e2f5882e0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/laravel-ciphersweet/zipball/cc336648b94f88e9d0fd4be11c14e61e2f5882e0",
|
||||
"reference": "cc336648b94f88e9d0fd4be11c14e61e2f5882e0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^9.19|^10.0",
|
||||
"paragonie/ciphersweet": "^4.0.1",
|
||||
"php": "^8.1",
|
||||
"spatie/laravel-package-tools": "^1.12.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.8",
|
||||
"nunomaduro/collision": "^6.0",
|
||||
"nunomaduro/larastan": "^2.0.1",
|
||||
"orchestra/testbench": "^7.0|^8.0",
|
||||
"pestphp/pest": "^1.21",
|
||||
"pestphp/pest-plugin-laravel": "^1.1",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"spatie/laravel-ray": "^1.26"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Spatie\\LaravelCipherSweet\\LaravelCipherSweetServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"LaravelCipherSweet": "Spatie\\LaravelCipherSweet\\Facades\\LaravelCipherSweet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\LaravelCipherSweet\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Rias Van der Veken",
|
||||
"email": "rias@spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Use ciphersweet in your Laravel project",
|
||||
"homepage": "https://github.com/spatie/laravel-ciphersweet",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"laravel-ciphersweet",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/spatie/laravel-ciphersweet/tree/1.0.4"
|
||||
},
|
||||
"time": "2023-01-26T12:33:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-comments",
|
||||
"version": "1.4.3",
|
||||
|
||||
36
config/ciphersweet.php
Normal file
36
config/ciphersweet.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/**
|
||||
* This controls which cryptographic backend will be used by CipherSweet.
|
||||
* Unless you have specific compliance requirements, you should choose
|
||||
* "nacl".
|
||||
*
|
||||
* Supported: "boring", "fips", "nacl"
|
||||
*/
|
||||
'backend' => env('CIPHERSWEET_BACKEND', 'nacl'),
|
||||
|
||||
/**
|
||||
* Select which key provider your application will use. The default option
|
||||
* is to read a string literal out of .env, but it's also possible to
|
||||
* provide the key in a file or use random keys for testing.
|
||||
*
|
||||
* Supported: "file", "random", "string"
|
||||
*/
|
||||
'provider' => env('CIPHERSWEET_PROVIDER', 'string'),
|
||||
|
||||
/**
|
||||
* Set provider-specific options here. "string" will read the key directly
|
||||
* from your .env file. "file" will read the contents of the specified file
|
||||
* to use as your key. "custom" points to a factory class that returns a
|
||||
* provider from its `__invoke` method. Please see the docs for more details.
|
||||
*/
|
||||
'providers' => [
|
||||
'file' => [
|
||||
'path' => env('CIPHERSWEET_FILE_PATH'),
|
||||
],
|
||||
'string' => [
|
||||
'key' => env('CIPHERSWEET_KEY'),
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('blind_indexes', function (Blueprint $table) {
|
||||
$table->morphs('indexable');
|
||||
$table->string('name');
|
||||
$table->string('value');
|
||||
|
||||
$table->index(['name', 'value']);
|
||||
$table->unique(['indexable_type', 'indexable_id', 'name']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->text('public_key')->nullable()->change();
|
||||
$table->text('email')->nullable()->change();
|
||||
$table->text('node_id')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
};
|
||||
18
resources/views/errors/503.blade.php
Normal file
18
resources/views/errors/503.blade.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<title>Site Maintenance</title>
|
||||
<style>
|
||||
body { text-align: center; padding: 150px; }
|
||||
h1 { font-size: 50px; }
|
||||
body { font: 20px Helvetica, sans-serif; color: #333; }
|
||||
article { display: block; text-align: left; width: 650px; margin: 0 auto; }
|
||||
a { color: #dc8100; text-decoration: none; }
|
||||
a:hover { color: #333; text-decoration: none; }
|
||||
</style>
|
||||
|
||||
<article>
|
||||
<h1>We’ll be back soon!</h1>
|
||||
<div>
|
||||
<p>Sorry for the inconvenience but we’re performing some maintenance at the moment. If you need to you can always <a href="https://t.me/HolgerHatGarKeineNode">contact us</a>, otherwise we’ll be back online shortly!</p>
|
||||
<p>— Einundzwanzig Team</p>
|
||||
</div>
|
||||
</article>
|
||||
@@ -57,13 +57,21 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@php
|
||||
$address = match(true) {
|
||||
$pleb->lightning_address !== '' => $pleb->lightning_address,
|
||||
$pleb->lnurl !== '' => $pleb->lnurl,
|
||||
$pleb->node_id !== '' => $pleb->node_id,
|
||||
default => null,
|
||||
};
|
||||
@endphp
|
||||
<div x-show="show">
|
||||
@if($pleb->lightning_address || $pleb->lnurl || $pleb->node_id)
|
||||
@if($address)
|
||||
<div wire:ignore>
|
||||
<lightning-widget
|
||||
name="{{ $pleb->name }}"
|
||||
accent="#f7931a"
|
||||
to="{{ $pleb->lightning_address ?? $pleb->lnurl ?? $pleb->node_id }}"
|
||||
to="{{ $address }}"
|
||||
image="{{ $pleb->profile_photo_url }}"
|
||||
amounts="21,210,2100,21000"
|
||||
/>
|
||||
|
||||
@@ -34,7 +34,8 @@ Route::middleware([])
|
||||
->group(function () {
|
||||
Route::resource('languages', \App\Http\Controllers\Api\LanguageController::class);
|
||||
Route::get('meetups', function () {
|
||||
return \App\Models\Meetup::with([
|
||||
return \App\Models\Meetup::query()
|
||||
->with([
|
||||
'city',
|
||||
])
|
||||
->get()
|
||||
@@ -46,8 +47,8 @@ Route::middleware([])
|
||||
'country' => str($meetup->city->country->code)->upper(),
|
||||
'state' => $meetup->github_data['state'] ?? null,
|
||||
'city' => $meetup->city->name,
|
||||
'longitude' => (float)$meetup->city->longitude,
|
||||
'latitude' => (float)$meetup->city->latitude,
|
||||
'longitude' => (float) $meetup->city->longitude,
|
||||
'latitude' => (float) $meetup->city->latitude,
|
||||
'twitter_username' => $meetup->twitter_username,
|
||||
'website' => $meetup->webpage,
|
||||
]);
|
||||
@@ -57,7 +58,7 @@ Route::middleware([])
|
||||
Route::get('/lnurl-auth-callback', function (\Illuminate\Http\Request $request) {
|
||||
if (lnurl\auth($request->k1, $request->sig, $request->key)) {
|
||||
// find User by $wallet_public_key
|
||||
$user = User::where('public_key', $request->key)
|
||||
$user = User::query()->whereBlind('public_key', 'public_key_index', $request->key)
|
||||
->first();
|
||||
if (!$user) {
|
||||
// create User
|
||||
|
||||
Reference in New Issue
Block a user