AdminInviteCommand.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use App\Models\AdminInvite;
  5. use Illuminate\Support\Str;
  6. class AdminInviteCommand extends Command
  7. {
  8. /**
  9. * The name and signature of the console command.
  10. *
  11. * @var string
  12. */
  13. protected $signature = 'admin:invite';
  14. /**
  15. * The console command description.
  16. *
  17. * @var string
  18. */
  19. protected $description = 'Create an invite link';
  20. /**
  21. * Execute the console command.
  22. *
  23. * @return int
  24. */
  25. public function handle()
  26. {
  27. $this->info(' ____ _ ______ __ ');
  28. $this->info(' / __ \(_) _____ / / __/__ ____/ / ');
  29. $this->info(' / /_/ / / |/_/ _ \/ / /_/ _ \/ __ / ');
  30. $this->info(' / ____/ /> </ __/ / __/ __/ /_/ / ');
  31. $this->info(' /_/ /_/_/|_|\___/_/_/ \___/\__,_/ ');
  32. $this->info(' ');
  33. $this->info(' Pixelfed Admin Inviter');
  34. $this->line(' ');
  35. $this->info(' Manage user registration invite links');
  36. $this->line(' ');
  37. $action = $this->choice(
  38. 'Select an action',
  39. [
  40. 'Create invite',
  41. 'View invites',
  42. 'Expire invite',
  43. 'Cancel'
  44. ],
  45. 3
  46. );
  47. switch($action) {
  48. case 'Create invite':
  49. return $this->create();
  50. break;
  51. case 'View invites':
  52. return $this->view();
  53. break;
  54. case 'Expire invite':
  55. return $this->expire();
  56. break;
  57. case 'Cancel':
  58. return;
  59. break;
  60. }
  61. }
  62. protected function create()
  63. {
  64. $this->info('Create Invite');
  65. $this->line('=============');
  66. $this->info('Set an optional invite name (only visible to admins)');
  67. $name = $this->ask('Invite Name (optional)', 'Untitled Invite');
  68. $this->info('Set an optional invite description (only visible to admins)');
  69. $description = $this->ask('Invite Description (optional)');
  70. $this->info('Set an optional message to invitees (visible to all)');
  71. $message = $this->ask('Invite Message (optional)', 'You\'ve been invited to join');
  72. $this->info('Set maximum # of invite uses, use 0 for unlimited');
  73. $max_uses = $this->ask('Max uses', 1);
  74. $shouldExpire = $this->choice(
  75. 'Set an invite expiry date?',
  76. [
  77. 'No - invite never expires',
  78. 'Yes - expire after 24 hours',
  79. 'Custom - let me pick an expiry date'
  80. ],
  81. 0
  82. );
  83. switch($shouldExpire) {
  84. case 'No - invite never expires':
  85. $expires = null;
  86. break;
  87. case 'Yes - expire after 24 hours':
  88. $expires = now()->addHours(24);
  89. break;
  90. case 'Custom - let me pick an expiry date':
  91. $this->info('Set custom expiry date in days');
  92. $customExpiry = $this->ask('Custom Expiry', 14);
  93. $expires = now()->addDays($customExpiry);
  94. break;
  95. }
  96. $this->info('Skip email verification for invitees?');
  97. $skipEmailVerification = $this->choice('Skip email verification', ['No', 'Yes'], 0);
  98. $invite = new AdminInvite;
  99. $invite->name = $name;
  100. $invite->description = $description;
  101. $invite->message = $message;
  102. $invite->max_uses = $max_uses;
  103. $invite->skip_email_verification = $skipEmailVerification === 'Yes';
  104. $invite->expires_at = $expires;
  105. $invite->invite_code = Str::uuid() . Str::random(random_int(1,6));
  106. $invite->save();
  107. $this->info('####################');
  108. $this->info('# Invite Generated!');
  109. $this->line(' ');
  110. $this->info($invite->url());
  111. $this->line(' ');
  112. return Command::SUCCESS;
  113. }
  114. protected function view()
  115. {
  116. $this->info('View Invites');
  117. $this->line('=============');
  118. if(AdminInvite::count() == 0) {
  119. $this->line(' ');
  120. $this->error('No invites found!');
  121. return;
  122. }
  123. $this->table(
  124. ['Invite Code', 'Uses Left', 'Expires'],
  125. AdminInvite::all(['invite_code', 'max_uses', 'uses', 'expires_at'])->map(function($invite) {
  126. return [
  127. 'invite_code' => $invite->invite_code,
  128. 'uses_left' => $invite->max_uses ? ($invite->max_uses - $invite->uses) : '∞',
  129. 'expires_at' => $invite->expires_at ? $invite->expires_at->diffForHumans() : 'never'
  130. ];
  131. })->toArray()
  132. );
  133. }
  134. protected function expire()
  135. {
  136. $token = $this->anticipate('Enter invite code to expire', function($val) {
  137. if(!$val || empty($val)) {
  138. return [];
  139. }
  140. return AdminInvite::where('invite_code', 'like', '%' . $val . '%')->pluck('invite_code')->toArray();
  141. });
  142. if(!$token || empty($token)) {
  143. $this->error('Invalid invite code');
  144. return;
  145. }
  146. $invite = AdminInvite::whereInviteCode($token)->first();
  147. if(!$invite) {
  148. $this->error('Invalid invite code');
  149. return;
  150. }
  151. $invite->max_uses = 1;
  152. $invite->expires_at = now()->subHours(2);
  153. $invite->save();
  154. $this->info('Expired the following invite: ' . $invite->url());
  155. }
  156. }