koel / koel

🐦 A personal music streaming server that works.
https://koel.dev
MIT License
15.98k stars 1.97k forks source link

"The MAC is invalid" after upgrade #1781

Closed Mark-Shternberg closed 3 months ago

Mark-Shternberg commented 3 months ago

Describe the bug Error occurs after upgrade from v7.0.1 to v7.0.2 when browser sent get request (start page opening, but in console i see error 500 (trace log attached), and log in doesn't work)

I tried to deactivate Koel plus via CLI, thinking that it is a reason, but it's fail with same error (at the same time php artisan koel:init --no-assets runs successfully)

Environment

Additional context Trace log:

[2024-07-12 20:51:31] production.ERROR: The MAC is invalid. {"userId":1,"exception":"[object] (Illuminate\\Contracts\\Encryption\\DecryptException(code: 0): The MAC is invalid. at /var/www/html/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php:222)
[stacktrace]
#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php(151): Illuminate\\Encryption\\Encrypter->getJsonPayload()
#1 /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(355): Illuminate\\Encryption\\Encrypter->decrypt()
#2 /var/www/html/app/Casts/EncryptedValueCast.php(12): Illuminate\\Support\\Facades\\Facade::__callStatic()
#3 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(816): App\\Casts\\EncryptedValueCast->get()
#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(792): Illuminate\\Database\\Eloquent\\Model->getClassCastableAttributeValue()
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(2136): Illuminate\\Database\\Eloquent\\Model->castAttribute()
#6 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(489): Illuminate\\Database\\Eloquent\\Model->transformModelValue()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(443): Illuminate\\Database\\Eloquent\\Model->getAttributeValue()
#8 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2226): Illuminate\\Database\\Eloquent\\Model->getAttribute()
#9 /var/www/html/app/Models/License.php(39): Illuminate\\Database\\Eloquent\\Model->__get()
#10 [internal function]: App\\Models\\License->App\\Models\\{closure}()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(678): call_user_func()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(2122): Illuminate\\Database\\Eloquent\\Model->mutateAttributeMarkedAttribute()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(489): Illuminate\\Database\\Eloquent\\Model->transformModelValue()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(443): Illuminate\\Database\\Eloquent\\Model->getAttributeValue()
#15 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2226): Illuminate\\Database\\Eloquent\\Model->getAttribute()
#16 /var/www/html/app/Http/Controllers/API/FetchInitialDataController.php(61): Illuminate\\Database\\Eloquent\\Model->__get()
#17 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\\Http\\Controllers\\API\\FetchInitialDataController->__invoke()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction()
#19 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()
#21 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(806): Illuminate\\Routing\\Route->run()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#23 /var/www/html/app/Http/Middleware/Authenticate.php(14): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\Authenticate->handle()
#25 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(159): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(95): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequest()
#29 /var/www/html/app/Http/Middleware/ThrottleRequests.php(14): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\ThrottleRequests->handle()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\\Pipeline\\Pipeline->then()
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(784): Illuminate\\Routing\\Router->runRouteWithinStack()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(748): Illuminate\\Routing\\Router->runRoute()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(737): Illuminate\\Routing\\Router->dispatchToRoute()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustHosts.php(48): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\TrustHosts->handle()
#40 /var/www/html/app/Http/Middleware/ForceHttps.php(28): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\ForceHttps->handle()
#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#45 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#47 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(99): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#49 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then()
#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#52 /var/www/html/public/index.php(57): Illuminate\\Foundation\\Http\\Kernel->handle()
#53 {main}
"} 
[2024-07-12 20:51:35] production.ERROR: The MAC is invalid. {"userId":1,"exception":"[object] (Illuminate\\Contracts\\Encryption\\DecryptException(code: 0): The MAC is invalid. at /var/www/html/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php:222)
[stacktrace]
#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php(151): Illuminate\\Encryption\\Encrypter->getJsonPayload()
#1 /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(355): Illuminate\\Encryption\\Encrypter->decrypt()
#2 /var/www/html/app/Casts/EncryptedValueCast.php(12): Illuminate\\Support\\Facades\\Facade::__callStatic()
#3 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(816): App\\Casts\\EncryptedValueCast->get()
#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(792): Illuminate\\Database\\Eloquent\\Model->getClassCastableAttributeValue()
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(2136): Illuminate\\Database\\Eloquent\\Model->castAttribute()
#6 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(489): Illuminate\\Database\\Eloquent\\Model->transformModelValue()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(443): Illuminate\\Database\\Eloquent\\Model->getAttributeValue()
#8 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2226): Illuminate\\Database\\Eloquent\\Model->getAttribute()
#9 /var/www/html/app/Models/License.php(39): Illuminate\\Database\\Eloquent\\Model->__get()
#10 [internal function]: App\\Models\\License->App\\Models\\{closure}()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(678): call_user_func()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(2122): Illuminate\\Database\\Eloquent\\Model->mutateAttributeMarkedAttribute()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(489): Illuminate\\Database\\Eloquent\\Model->transformModelValue()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(443): Illuminate\\Database\\Eloquent\\Model->getAttributeValue()
#15 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2226): Illuminate\\Database\\Eloquent\\Model->getAttribute()
#16 /var/www/html/app/Http/Controllers/API/FetchInitialDataController.php(61): Illuminate\\Database\\Eloquent\\Model->__get()
#17 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\\Http\\Controllers\\API\\FetchInitialDataController->__invoke()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction()
#19 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()
#21 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(806): Illuminate\\Routing\\Route->run()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#23 /var/www/html/app/Http/Middleware/Authenticate.php(14): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\Authenticate->handle()
#25 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(159): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(95): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequest()
#29 /var/www/html/app/Http/Middleware/ThrottleRequests.php(14): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\ThrottleRequests->handle()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\\Pipeline\\Pipeline->then()
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(784): Illuminate\\Routing\\Router->runRouteWithinStack()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(748): Illuminate\\Routing\\Router->runRoute()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(737): Illuminate\\Routing\\Router->dispatchToRoute()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustHosts.php(48): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\TrustHosts->handle()
#40 /var/www/html/app/Http/Middleware/ForceHttps.php(28): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\ForceHttps->handle()
#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#45 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#47 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(99): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#49 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then()
#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#52 /var/www/html/public/index.php(57): Illuminate\\Foundation\\Http\\Kernel->handle()
#53 {main}
"} 
Mark-Shternberg commented 3 months ago

Problem solved by deactivate license via Lemon Squeezy, and activate again from CLI, but it's not normal for upgrade :)

phanan commented 3 months ago

It certainly isn't, but I'm glad you got it solved! Since I can't reproduce it, I'm going to close the issue, but if anyone else reports the same error I'll look more into it.

phanan commented 3 months ago

Hmm apparently the APP_KEY changed would cause this error. Did you perhaps change the app key somehow?

Mark-Shternberg commented 3 months ago

Hmm apparently the APP_KEY changed would cause this error. Did you perhaps change the app key somehow?

Yep, when i run php artisan koel:init --no-assets after upgrade APP_KEY was recreated. BUT. I included it in my docker-compose.yml and upgrade from v7.0.2 to v7.0.3 fails again with this error

May be Lemon Squeezy somehow check MAC address of server, and when docker recreate container for upgrade assign it new MAC

phanan commented 3 months ago

Hmm I doubt that's LemonSqueezy fault. Koel encrypts the license with APP_KEY, so if APP_KEY is changed, the decryption will fail with the error (that's why you had to re-activate). What confuses me is, APP_KEY isn't supposed to be changed during koel:init, as the task checks for its existence before generating and populating a new one.

I will look deeper into this matter. For now, sorry this happened to you, but I'm glad that the solution/workaround is manageable :)

Mark-Shternberg commented 3 months ago

Hmm I doubt that's LemonSqueezy fault. Koel encrypts the license with APP_KEY, so if APP_KEY is changed, the decryption will fail with the error (that's why you had to re-activate). What confuses me is, APP_KEY isn't supposed to be changed during koel:init, as the task checks for its existence before generating and populating a new one.

I will look deeper into this matter. For now, sorry this happened to you, but I'm glad that the solution/workaround is manageable :)

APP_KEY was changed beacause after recreation of koel container it doesn't contain .env. And if APP_KEY wasn't explicitly appointed, Koel regenerate it. Here is part of php artisan koel:init --no-assets output without APP_KEY in docker-compose.yml:

Clearing caches ......................................................................................................................... 6ms DONE
Copying .env file ....................................................................................................................... 0ms DONE
Generating app key ...................................................................................................................... 1ms DONE
...

And another note: if i return old APP_KEY and rerun php artisan koel:init --no-assets error occurs again anyway

phanan commented 3 months ago

APP_KEY was changed beacause after recreation of koel container it doesn't contain .env.

Not sure I follow. Doesn't this mean whenever you recreate the container, you'll have to re-configure everything (database, keys, etc.) again?

Mark-Shternberg commented 3 months ago

APP_KEY was changed beacause after recreation of koel container it doesn't contain .env.

Not sure I follow. Doesn't this mean whenever you recreate the container, you'll have to re-configure everything (database, keys, etc.) again?

Nope, most of variables from .env included in docker-compose.yml, and so all works My docker-compose.yml looks like this:

version: '3'

services:
  koel:
    image: phanan/koel
    depends_on:
      - database
    ports:
      - 8080:80
    restart: always
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=database
      - DB_USERNAME=koel
      - DB_PASSWORD=***
      - DB_DATABASE=koel
      - FORCE_HTTPS=true
      - TRANSCODE_FLAC=false
      - APP_URL=https://***
      - APP_KEY=***
      - YOUTUBE_API_KEY=***
      - SPOTIFY_CLIENT_ID=***
      - SPOTIFY_CLIENT_SECRET=***
      - LASTFM_API_KEY=***
      - LASTFM_API_SECRET=***
    volumes:
      - music:/music
      - covers:/var/www/html/public/img/covers
      - search_index:/var/www/html/storage/search-indexes

  database:
    image: mysql/mysql-server:5.7
    restart: always
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=***
      - MYSQL_DATABASE=koel
      - MYSQL_USER=koel
      - MYSQL_PASSWORD=***

volumes:
  db:
driver: local
  music:
    driver: local
  covers:
    driver: local
  search_index:
    driver: local

File was taken from here

phanan commented 3 months ago

But if APP_KEY is already in the environment variables, how come Koel doesn't recognize it? If we look at app/Console/Commands/InitCommand.php:128:

        $key = $this->laravel['config']['app.key'];

        $this->components->task($key ? 'Retrieving app key' : 'Generating app key', function () use (&$key): void {
            if (!$key) {
                // Generate the key manually to prevent some clashes with `php artisan key:generate`
                $key = $this->generateRandomKey();
                $this->dotenvEditor->setKey('APP_KEY', $key);
                $this->laravel['config']['app.key'] = $key;
            }
        });

I'd assume that $key shouldn't be empty here.

Mark-Shternberg commented 3 months ago

But if APP_KEY is already in the environment variables, how come Koel doesn't recognize it?

I add APP_KEY in docker-compose.yml yesterday, before that it was not there, and therefore it changed every rerun koel:init Now when I add it to docker-compose.yml Koel recognize it and use as expected, but it doesn't help with error

New note: I noticed that an error appears after run php artisan koel:init --no-assets, not after recreating docker container, here my steps to reproduce:

screenshot

phanan commented 3 months ago

This is getting more and more curious. As you can see in the screenshot, koel:init didn't even change the app key, indicated by "Using app key: …" which is how the code's supposed to work.

This is my output, also on Docker:

# php artisan koel:license:status

   INFO  Checking your Koel Plus license status….  

 [OK] You have a valid Koel Plus license. All Plus features are enabled.                                                

  License Key .................................................................................................................... ****-3BA4029FA623  
  Registered To ............................................................................................................ An Phan <me@phanan.net>  
  Expires On ............................................................................................................................ Never ever  

# php artisan koel:init --no-assets
************************************
*     KOEL INSTALLATION WIZARD     *
************************************

As a reminder, you can always install/upgrade manually following the guide at https://docs.koel.dev

  Clearing caches ......................................................................................................................... 6ms DONE
  .env file exists -- skipping ................................................................................................................ DONE
  Retrieving app key ...................................................................................................................... 0ms DONE
  Using app key: base64:NRq4dgs4l.. ........................................................................................................... DONE
  Migrating database ...................................................................................................................... 4ms DONE
  Data already seeded -- skipping ............................................................................................................. DONE

 [OK] All done!                                                                                                         

Koel can now be run from localhost with `php artisan serve`.
Again, visit 📙 https://docs.koel.dev for more tips and tweaks.
Feeling generous and want to support Koel's development? Check out https://github.com/users/phanan/sponsorship 🤗
Thanks for using Koel. You rock! 🤘

# php artisan koel:license:status

   INFO  Checking your Koel Plus license status….  

 [OK] You have a valid Koel Plus license. All Plus features are enabled.                                                

  License Key .................................................................................................................... ****-3BA4029FA623  
  Registered To ............................................................................................................ An Phan <me@phanan.net>  
  Expires On ............................................................................................................................ Never ever
phanan commented 3 months ago

I think the problem does not come from the fact that APP_KEY was regenerated (because it wasn't). To validate this hunch, can you add this line after app/Services/LicenseService.php:26

\Log::info('Encrypt hash: ' . $this->hashSalt);

and go through license activation and status checking again? If the value remains unchanged, something with your setup might be causing the license encryption and storing to go wrong.

phanan commented 3 months ago

@Mark-Shternberg I deleted your comment as it contained your license key.

Mark-Shternberg commented 3 months ago

I think the problem does not come from the fact that APP_KEY was regenerated (because it wasn't). To validate this hunch, can you add this line after app/Services/LicenseService.php:26

\Log::info('Encrypt hash: ' . $this->hashSalt);

and go through license activation and status checking again? If the value remains unchanged, something with your setup might be causing the license encryption and storing to go wrong.

The hashes are absolutely the same in the logs both during activation and during verification

phanan commented 3 months ago

Great, thanks! Then the storing must have gone wrong somehow. Can you try replacing app/Casts/EncryptedValueCast.php with this? (basically adding two lines of log but I don't want to confuse you):

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Support\Facades\Crypt;

class EncryptedValueCast implements CastsAttributes
{
    public function get($model, string $key, $value, array $attributes): ?string
    {
        \Log::info('Trying to decrypt: ' . $value);
        return $value ? Crypt::decrypt($value) : null;
    }

    public function set($model, string $key, $value, array $attributes): ?string
    {
        \Log::info('Encrypted: ' . Crypt::encrypt($value));
        return $value ? Crypt::encrypt($value) : null;
    }
}

The values logged should be exactly the same.

Mark-Shternberg commented 3 months ago

The values logged should be exactly the same.

nope, they are different:

[2024-07-14 11:42:35] production.INFO: Encrypted: eyJpdiI6InNTTDRnYkt  .... 
[2024-07-14 11:42:35] production.INFO: Trying to decrypt: eyJpdiI6IjlMd25JNVg .... 
phanan commented 3 months ago

nope, they are different:

Very interesting. How many rows do you have in the licenses table? Edit: Though, actually that wouldn't explain why decryption of the second value eyJpdiI6IjlMd25JNVg… fails.

Mark-Shternberg commented 3 months ago

nope, they are different:

Very interesting. How many rows do you have in the licenses table? Edit: Though, actually that wouldn't explain why decryption of the second value eyJpdiI6IjlMd25JNVg… fails.

I have 2 rows with id 1 and id 3, one created 2024-07-12 11:51:13, second 2024-07-14 11:42:35

Mark-Shternberg commented 3 months ago

id 1 has key like "Encrypted" from log id 3 has key like "Trying to decrypt" from log

phanan commented 3 months ago

That's what I thought! So you somehow have a leftover key that was likely encrypted with an old APP_KEY, and Koel's been checking against this key instead of the new one (likely because this key somehow has a newer id). I believe emptying the table will solve your problem, but I'll see how to fix the issue from Koel's side as well.

Mark-Shternberg commented 3 months ago

That's what I thought! So you somehow have a leftover key that was likely encrypted with an old APP_KEY, and Koel's been checking against this key instead of the new one (likely because this key somehow has a newer id). I believe emptying the table will solve your problem, but I'll see how to fix the issue from Koel's side as well.

Yep, problem was here. I deleted rows, reactivate license and now all works great! Thanks for help, that was interesting :D

phanan commented 3 months ago

Thank you! Was interesting to me as well.