diff --git a/config.demo/src/database/migrations/2021_01_26_150000_change_sku_descriptions.php b/config.demo/src/database/migrations/2021_01_26_150000_change_sku_descriptions.php deleted file mode 100644 --- a/config.demo/src/database/migrations/2021_01_26_150000_change_sku_descriptions.php +++ /dev/null @@ -1,42 +0,0 @@ -first(); - - if ($beta_sku) { - $beta_sku->name = 'Private Beta (invitation only)'; - $beta_sku->description = 'Access to the private beta program subscriptions'; - $beta_sku->save(); - } - - $meet_sku = \App\Sku::where('title', 'meet')->first(); - - if ($meet_sku) { - $meet_sku->name = 'Voice & Video Conferencing (public beta)'; - $meet_sku->handler_class = 'App\Handlers\Meet'; - $meet_sku->save(); - } - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - } -} diff --git a/config.demo/src/database/migrations/2021_02_19_100000_transaction_amount_fix.php b/config.demo/src/database/migrations/2021_02_19_100000_transaction_amount_fix.php deleted file mode 100644 --- a/config.demo/src/database/migrations/2021_02_19_100000_transaction_amount_fix.php +++ /dev/null @@ -1,38 +0,0 @@ -get()->each(function ($sku) { - $sku->title = 'beta-distlists'; - $sku->handler_class = 'App\Handlers\Beta\Distlists'; - $sku->save(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - \App\Sku::where('title', 'beta-distlists')->get()->each(function ($sku) { - $sku->title = 'distlist'; - $sku->handler_class = 'App\Handlers\Distlist'; - $sku->save(); - }); - } -} diff --git a/config.demo/src/database/migrations/2022_05_13_090000_permissions_and_room_subscriptions.php b/config.demo/src/database/migrations/2022_05_13_090000_permissions_and_room_subscriptions.php deleted file mode 100644 --- a/config.demo/src/database/migrations/2022_05_13_090000_permissions_and_room_subscriptions.php +++ /dev/null @@ -1,57 +0,0 @@ - 'group-room', - 'name' => 'Group conference room', - 'description' => 'Shareable audio & video conference room', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\GroupRoom', - 'active' => true, - ]); - - \App\Sku::create([ - 'title' => 'room', - 'name' => 'Standard conference room', - 'description' => 'Audio & video conference room', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Room', - 'active' => true, - ]); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - \App\Sku::where('title', 'room')->delete(); - \App\Sku::where('title', 'group-room')->delete(); - - \App\Sku::create([ - 'title' => 'meet', - 'name' => 'Voice & Video Conferencing (public beta)', - 'description' => 'Video conferencing tool', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Meet', - 'active' => true, - ]); - } -}; diff --git a/config.demo/src/database/migrations/2022_07_08_100000_fix_group_sku_name.php b/config.demo/src/database/migrations/2022_07_08_100000_fix_group_sku_name.php deleted file mode 100644 --- a/config.demo/src/database/migrations/2022_07_08_100000_fix_group_sku_name.php +++ /dev/null @@ -1,32 +0,0 @@ -get()->each(function ($sku) { - $sku->name = 'Distribution list'; - $sku->description = 'Mail distribution list'; - $sku->save(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - \App\Sku::where('title', 'group')->get()->each(function ($sku) { - $sku->name = 'Group'; - $sku->description = 'Distribution list'; - $sku->save(); - }); - } -}; diff --git a/config.demo/src/database/migrations/2022_09_08_100001_plans_free_months.php b/config.demo/src/database/migrations/2022_09_08_100001_plans_free_months.php deleted file mode 100644 --- a/config.demo/src/database/migrations/2022_09_08_100001_plans_free_months.php +++ /dev/null @@ -1,26 +0,0 @@ -update(['free_months' => 1]); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - } -}; diff --git a/config.prod/src/database/migrations b/config.prod/src/database/migrations deleted file mode 120000 --- a/config.prod/src/database/migrations +++ /dev/null @@ -1 +0,0 @@ -../../../config.demo/src/database/migrations \ No newline at end of file diff --git a/config.prod/src/database/seeds/AdminSeeder.php b/config.prod/src/database/seeds/AdminSeeder.php --- a/config.prod/src/database/seeds/AdminSeeder.php +++ b/config.prod/src/database/seeds/AdminSeeder.php @@ -2,13 +2,11 @@ namespace Database\Seeds; -use App\Sku; -use App\Package; use App\Domain; use App\User; -use Laravel\Passport\Passport; +use App\Sku; +use App\Package; use Illuminate\Database\Seeder; -use Illuminate\Encryption\Encrypter; class AdminSeeder extends Seeder { @@ -21,13 +19,140 @@ */ public function run() { - //Create required packages + $skus = [ + [ + 'title' => 'mailbox', + 'name' => 'User Mailbox', + 'description' => 'Just a mailbox', + 'cost' => 0, + 'units_free' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Mailbox', + 'active' => true, + ], + [ + 'title' => 'domain', + 'name' => 'Hosted Domain', + 'description' => 'Somewhere to place a mailbox', + 'cost' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Domain', + 'active' => false, + ], + [ + 'title' => 'domain-hosting', + 'name' => 'External Domain', + 'description' => 'Host a domain that is externally registered', + 'cost' => 0, + 'units_free' => 1, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\DomainHosting', + 'active' => true, + ], + [ + 'title' => 'storage', + 'name' => 'Storage Quota', + 'description' => 'Some wiggle room', + 'cost' => 0, + 'units_free' => 5, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Storage', + 'active' => true, + ], + [ + 'title' => 'groupware', + 'name' => 'Groupware Features', + 'description' => 'Groupware functions like Calendar, Tasks, Notes, etc.', + 'cost' => 0, + 'units_free' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Groupware', + 'active' => true, + ], + [ + 'title' => 'resource', + 'name' => 'Resource', + 'description' => 'Reservation taker', + 'cost' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Resource', + 'active' => true, + ], + [ + 'title' => 'shared-folder', + 'name' => 'Shared Folder', + 'description' => 'A shared folder', + 'cost' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\SharedFolder', + 'active' => true, + ], + [ + 'title' => '2fa', + 'name' => '2-Factor Authentication', + 'description' => 'Two factor authentication for webmail and administration panel', + 'cost' => 0, + 'units_free' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Auth2F', + 'active' => true, + ], + [ + 'title' => 'activesync', + 'name' => 'Activesync', + 'description' => 'Mobile synchronization', + 'cost' => 0, + 'units_free' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Activesync', + 'active' => true, + ], + [ + 'title' => 'group', + 'name' => 'Distribution list', + 'description' => 'Mail distribution list', + 'cost' => 0, + 'units_free' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Group', + 'active' => true, + ], + [ + 'title' => 'group-room', + 'name' => 'Group conference room', + 'description' => 'Shareable audio & video conference room', + 'cost' => 0, + 'units_free' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\GroupRoom', + 'active' => true, + ], + [ + 'title' => 'room', + 'name' => 'Standard conference room', + 'description' => 'Audio & video conference room', + 'cost' => 0, + 'units_free' => 0, + 'period' => 'monthly', + 'handler_class' => 'App\Handlers\Room', + 'active' => true, + ], + ]; + + foreach ($skus as $sku) { + // Check existence because migration might have added this already + if (!Sku::where('title', $sku['title'])->where('tenant_id', \config('app.tenant_id'))->first()) { + Sku::create($sku); + } + } + $skuDomain = Sku::where(['title' => 'domain-hosting', 'tenant_id' => \config('app.tenant_id')])->first(); $skuGroupware = Sku::where(['title' => 'groupware', 'tenant_id' => \config('app.tenant_id')])->first(); $skuMailbox = Sku::where(['title' => 'mailbox', 'tenant_id' => \config('app.tenant_id')])->first(); $skuStorage = Sku::where(['title' => 'storage', 'tenant_id' => \config('app.tenant_id')])->first(); + // $skuGroup = Sku::where(['title' => 'group', 'tenant_id' => \config('app.tenant_id')])->first(); - $packageKolab = Package::create( + $userPackage = Package::create( [ 'title' => 'kolab', 'name' => 'Groupware Account', @@ -35,35 +160,22 @@ 'discount_rate' => 0, ] ); - $packageKolab->skus()->saveMany([ + + $userPackage->skus()->saveMany([ $skuMailbox, $skuGroupware, $skuStorage ]); - - $packageDomain = Package::create( - [ - 'title' => 'domain-hosting', - 'name' => 'Domain Hosting', - 'description' => 'Use your own, existing domain.', - 'discount_rate' => 0, - ] + // This package contains 2 units of the storage SKU, which just so happens to also + // be the number of SKU free units. + $userPackage->skus()->updateExistingPivot( + $skuStorage, + ['qty' => 5], + false ); - $packageDomain->skus()->saveMany([ - $skuDomain - ]); - - //Create primary domain - $appDomain = Domain::create( - [ - 'namespace' => \config('app.domain'), - 'status' => DOMAIN::STATUS_CONFIRMED + Domain::STATUS_ACTIVE, - 'type' => Domain::TYPE_PUBLIC, - ] - ); //Create admin user $admin = User::create( @@ -79,8 +191,28 @@ ] ); - $appDomain->assignPackage($packageDomain, $admin); - $admin->assignPackage($packageKolab); + $admin->assignPackage($userPackage); + + + //Create primary domain + $domain = Domain::create( + [ + 'namespace' => \config('app.domain'), + 'status' => DOMAIN::STATUS_CONFIRMED + Domain::STATUS_ACTIVE, + 'type' => Domain::TYPE_EXTERNAL, + ] + ); + + $domainPackage = Package::create( + [ + 'title' => 'domain', + 'name' => 'Domain', + 'description' => 'Domain.', + 'discount_rate' => 0, + ] + ); + $domainPackage->skus()->saveMany([$skuDomain]); + + $domain->assignPackage($domainPackage, $admin); } } - diff --git a/config.prod/src/database/seeds/DatabaseSeeder.php b/config.prod/src/database/seeds/DatabaseSeeder.php --- a/config.prod/src/database/seeds/DatabaseSeeder.php +++ b/config.prod/src/database/seeds/DatabaseSeeder.php @@ -16,8 +16,8 @@ $this->call([ Seeds\PassportSeeder::class, Seeds\PowerDNSSeeder::class, - Seeds\SkuSeeder::class, Seeds\AdminSeeder::class, + Seeds\ImapAdminSeeder::class, ]); } } diff --git a/config.prod/src/database/seeds/ImapAdminSeeder.php b/config.prod/src/database/seeds/ImapAdminSeeder.php new file mode 100644 --- /dev/null +++ b/config.prod/src/database/seeds/ImapAdminSeeder.php @@ -0,0 +1,26 @@ + \config('imap.admin_login'), + 'password' => \config('imap.admin_password') + ] + ); + } +} diff --git a/config.prod/src/database/seeds/SkuSeeder.php b/config.prod/src/database/seeds/SkuSeeder.php deleted file mode 100644 --- a/config.prod/src/database/seeds/SkuSeeder.php +++ /dev/null @@ -1,172 +0,0 @@ - 'mailbox', - 'name' => 'User Mailbox', - 'description' => 'Just a mailbox', - 'cost' => 500, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Mailbox', - 'active' => true, - ], - [ - 'title' => 'domain', - 'name' => 'Hosted Domain', - 'description' => 'Somewhere to place a mailbox', - 'cost' => 100, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Domain', - 'active' => false, - ], - [ - 'title' => 'domain-registration', - 'name' => 'Domain Registration', - 'description' => 'Register a domain with us', - 'cost' => 101, - 'period' => 'yearly', - 'handler_class' => 'App\Handlers\DomainRegistration', - 'active' => false, - ], - [ - 'title' => 'domain-hosting', - 'name' => 'External Domain', - 'description' => 'Host a domain that is externally registered', - 'cost' => 100, - 'units_free' => 1, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\DomainHosting', - 'active' => true, - ], - [ - 'title' => 'domain-relay', - 'name' => 'Domain Relay', - 'description' => 'A domain you host at home, for which we relay email', - 'cost' => 103, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\DomainRelay', - 'active' => false, - ], - [ - 'title' => 'storage', - 'name' => 'Storage Quota', - 'description' => 'Some wiggle room', - 'cost' => 25, - 'units_free' => 5, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Storage', - 'active' => true, - ], - [ - 'title' => 'groupware', - 'name' => 'Groupware Features', - 'description' => 'Groupware functions like Calendar, Tasks, Notes, etc.', - 'cost' => 490, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Groupware', - 'active' => true, - ], - [ - 'title' => 'resource', - 'name' => 'Resource', - 'description' => 'Reservation taker', - 'cost' => 101, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Resource', - 'active' => true, - ], - [ - 'title' => 'shared-folder', - 'name' => 'Shared Folder', - 'description' => 'A shared folder', - 'cost' => 89, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\SharedFolder', - 'active' => true, - ], - [ - 'title' => '2fa', - 'name' => '2-Factor Authentication', - 'description' => 'Two factor authentication for webmail and administration panel', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Auth2F', - 'active' => true, - ], - [ - 'title' => 'activesync', - 'name' => 'Activesync', - 'description' => 'Mobile synchronization', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Activesync', - 'active' => true, - ], - [ - 'title' => 'beta', - 'name' => 'Private Beta (invitation only)', - 'description' => 'Access to the private beta program features', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta', - 'active' => false, - ], - [ - 'title' => 'group', - 'name' => 'Distribution list', - 'description' => 'Mail distribution list', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Group', - 'active' => true, - ], - [ - 'title' => 'group-room', - 'name' => 'Group conference room', - 'description' => 'Shareable audio & video conference room', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\GroupRoom', - 'active' => true, - ], - [ - 'title' => 'room', - 'name' => 'Standard conference room', - 'description' => 'Audio & video conference room', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Room', - 'active' => true, - ], - ]; - - foreach ($skus as $sku) { - // Check existence because migration might have added this already - if (!Sku::where('title', $sku['title'])->where('tenant_id', \config('app.tenant_id'))->first()) { - Sku::create($sku); - } - } - } -} diff --git a/src/app/Http/Controllers/API/V4/UsersController.php b/src/app/Http/Controllers/API/V4/UsersController.php --- a/src/app/Http/Controllers/API/V4/UsersController.php +++ b/src/app/Http/Controllers/API/V4/UsersController.php @@ -169,9 +169,10 @@ $isDegraded = $user->isDegraded(); $hasMeet = !$isDegraded && Sku::withObjectTenantContext($user)->where('title', 'room')->exists(); + // Enable all features if there are no skus for domain-hosting $hasCustomDomain = $user->wallet()->entitlements() ->where('entitleable_type', Domain::class) - ->count() > 0; + ->count() > 0 || !Sku::withObjectTenantContext($user)->where('title', 'domain-hosting')->exists(); // Get user's entitlements titles $skus = $user->entitlements()->select('skus.title') @@ -183,13 +184,13 @@ ->values() ->all(); - $hasBeta = in_array('beta', $skus); + $hasBeta = in_array('beta', $skus) || !Sku::withObjectTenantContext($user)->where('title', 'beta')->exists(); $plan = $isController ? $user->wallet()->plan() : null; $result = [ 'skus' => $skus, - 'enableBeta' => in_array('beta', $skus), + 'enableBeta' => $hasBeta, // TODO: This will change when we enable all users to create domains 'enableDomains' => $isController && $hasCustomDomain, // TODO: Make 'enableDistlists' working for wallet controllers that aren't account owners diff --git a/src/database/migrations/2020_10_29_100000_add_beta_skus.php b/src/database/migrations/2020_10_29_100000_add_beta_skus.php deleted file mode 100644 --- a/src/database/migrations/2020_10_29_100000_add_beta_skus.php +++ /dev/null @@ -1,53 +0,0 @@ -first()) { - \App\Sku::create([ - 'title' => 'beta', - 'name' => 'Beta program', - 'description' => 'Access to beta program subscriptions', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta', - 'active' => false, - ]); - } - - if (!\App\Sku::where('title', 'meet')->first()) { - \App\Sku::create([ - 'title' => 'meet', - 'name' => 'Video chat', - 'description' => 'Video conferencing tool', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta\Meet', - 'active' => true, - ]); - } - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - // there's no need to remove these SKUs - } -} diff --git a/src/database/migrations/2021_04_22_120000_add_distlist_beta_sku.php b/src/database/migrations/2021_04_22_120000_add_distlist_beta_sku.php deleted file mode 100644 --- a/src/database/migrations/2021_04_22_120000_add_distlist_beta_sku.php +++ /dev/null @@ -1,40 +0,0 @@ -first()) { - \App\Sku::create([ - 'title' => 'distlist', - 'name' => 'Distribution lists', - 'description' => 'Access to mail distribution lists', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Distlist', - 'active' => true, - ]); - } - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - // there's no need to remove this SKU - } -} diff --git a/src/database/migrations/2021_11_16_100000_create_resources_tables.php b/src/database/migrations/2021_11_16_100000_create_resources_tables.php --- a/src/database/migrations/2021_11_16_100000_create_resources_tables.php +++ b/src/database/migrations/2021_11_16_100000_create_resources_tables.php @@ -45,24 +45,6 @@ $table->unique(['resource_id', 'key']); } ); - - \App\Sku::where('title', 'resource')->update([ - 'active' => true, - 'cost' => 0, - ]); - - if (!\App\Sku::where('title', 'beta-resources')->first()) { - \App\Sku::create([ - 'title' => 'beta-resources', - 'name' => 'Calendaring resources', - 'description' => 'Access to calendaring resources', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta\Resources', - 'active' => true, - ]); - } } /** diff --git a/src/database/migrations/2021_11_25_100000_create_shared_folders_table.php b/src/database/migrations/2021_11_25_100000_create_shared_folders_table.php --- a/src/database/migrations/2021_11_25_100000_create_shared_folders_table.php +++ b/src/database/migrations/2021_11_25_100000_create_shared_folders_table.php @@ -47,25 +47,6 @@ $table->unique(['shared_folder_id', 'key']); } ); - - \App\Sku::where('title', 'shared_folder')->update([ - 'active' => true, - 'cost' => 0, - 'title' => 'shared-folder', - ]); - - if (!\App\Sku::where('title', 'beta-shared-folders')->first()) { - \App\Sku::create([ - 'title' => 'beta-shared-folders', - 'name' => 'Shared folders', - 'description' => 'Access to shared folders', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta\SharedFolders', - 'active' => true, - ]); - } } /** diff --git a/src/database/migrations/2022_03_02_100000_create_filesystem_tables.php b/src/database/migrations/2022_03_02_100000_create_filesystem_tables.php --- a/src/database/migrations/2022_03_02_100000_create_filesystem_tables.php +++ b/src/database/migrations/2022_03_02_100000_create_filesystem_tables.php @@ -62,19 +62,6 @@ ->onUpdate('cascade')->onDelete('cascade'); } ); - - if (\config('app.with_files') && !\App\Sku::where('title', 'files')->first()) { - \App\Sku::create([ - 'title' => 'files', - 'name' => 'File storage', - 'description' => 'Access to file storage', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Files', - 'active' => true, - ]); - } } /** @@ -82,8 +69,6 @@ */ public function down(): void { - \App\Sku::where('title', 'files')->delete(); - Schema::dropIfExists('fs_properties'); Schema::dropIfExists('fs_chunks'); Schema::dropIfExists('fs_items'); diff --git a/src/database/migrations/2022_06_03_100000_drop_beta_skus.php b/src/database/migrations/2022_06_03_100000_drop_beta_skus.php deleted file mode 100644 --- a/src/database/migrations/2022_06_03_100000_drop_beta_skus.php +++ /dev/null @@ -1,67 +0,0 @@ -delete(); - - \App\Sku::where('title', 'beta')->update(['description' => 'Access to the private beta program features']); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - \App\Sku::create([ - 'title' => 'beta-distlists', - 'name' => 'Distribution lists', - 'description' => 'Access to mail distribution lists', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta\Distlists', - 'active' => true, - ]); - \App\Sku::create([ - 'title' => 'beta-resources', - 'name' => 'Calendaring resources', - 'description' => 'Access to calendaring resources', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta\Resources', - 'active' => true, - ]); - \App\Sku::create([ - 'title' => 'beta-shared-folders', - 'name' => 'Shared folders', - 'description' => 'Access to shared folders', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Beta\SharedFolders', - 'active' => true, - ]); - \App\Sku::create([ - 'title' => 'files', - 'name' => 'File storage', - 'description' => 'Access to file storage', - 'cost' => 0, - 'units_free' => 0, - 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Files', - 'active' => true, - ]); - } -};