385 lines
10 KiB
PHP
385 lines
10 KiB
PHP
<?php
|
|
|
|
namespace App\Rules;
|
|
|
|
use Closure;
|
|
use Illuminate\Contracts\Validation\ValidationRule;
|
|
use Illuminate\Routing\Route as RouteElement;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Illuminate\Translation\PotentiallyTranslatedString;
|
|
|
|
class TeamName implements ValidationRule
|
|
{
|
|
/**
|
|
* Run the validation rule.
|
|
*
|
|
* @param Closure(string, ?string=): PotentiallyTranslatedString $fail
|
|
*/
|
|
public function validate(string $attribute, mixed $value, Closure $fail): void
|
|
{
|
|
$name = strtolower(trim($value));
|
|
|
|
if (in_array($name, $this->reservedNames(), true)) {
|
|
$fail('This team name is reserved and cannot be used.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a list of all reserved names.
|
|
*/
|
|
protected function reservedNames(): array
|
|
{
|
|
return once(fn () => collect($this->routesPrefixes())
|
|
->merge([
|
|
'300',
|
|
'302',
|
|
'400',
|
|
'401',
|
|
'402',
|
|
'403',
|
|
'404',
|
|
'405',
|
|
'406',
|
|
'407',
|
|
'408',
|
|
'409',
|
|
'410',
|
|
'411',
|
|
'412',
|
|
'413',
|
|
'414',
|
|
'415',
|
|
'416',
|
|
'417',
|
|
'418',
|
|
'419',
|
|
'420',
|
|
'421',
|
|
'422',
|
|
'423',
|
|
'424',
|
|
'425',
|
|
'426',
|
|
'427',
|
|
'428',
|
|
'429',
|
|
'430',
|
|
'431',
|
|
'500',
|
|
'501',
|
|
'502',
|
|
'503',
|
|
'504',
|
|
'505',
|
|
'506',
|
|
'507',
|
|
'508',
|
|
'509',
|
|
'510',
|
|
'511',
|
|
'693',
|
|
'694',
|
|
'695',
|
|
'900',
|
|
'about',
|
|
'account',
|
|
'accounts',
|
|
'accountspayable',
|
|
'accounts-payable',
|
|
'accountsreceivable',
|
|
'accounts-receivable',
|
|
'admin',
|
|
'advisories',
|
|
'anonymous',
|
|
'any',
|
|
'api',
|
|
'app',
|
|
'apps',
|
|
'attributes',
|
|
'auth',
|
|
'billing',
|
|
'bills',
|
|
'blob',
|
|
'blog',
|
|
'bounty',
|
|
'branches',
|
|
'business',
|
|
'businesses',
|
|
'cache',
|
|
'careers',
|
|
'case-studies',
|
|
'categories',
|
|
'central',
|
|
'certification',
|
|
'changelog',
|
|
'chat',
|
|
'cla',
|
|
'claim',
|
|
'claims',
|
|
'cloud',
|
|
'codereview',
|
|
'code-review',
|
|
'code-reviews',
|
|
'collection',
|
|
'collections',
|
|
'comments',
|
|
'commit',
|
|
'commits',
|
|
'companies',
|
|
'compare',
|
|
'contact',
|
|
'contributing',
|
|
'cookbook',
|
|
'copilot',
|
|
'coupons',
|
|
'customer',
|
|
'customer-stories',
|
|
'customers',
|
|
'dashboard',
|
|
'dashboard-feed',
|
|
'dashboards',
|
|
'delete',
|
|
'deploy',
|
|
'design',
|
|
'develop',
|
|
'developer',
|
|
'diff',
|
|
'discover',
|
|
'discussions',
|
|
'downloads',
|
|
'downtime',
|
|
'editor',
|
|
'editors',
|
|
'edu',
|
|
'education',
|
|
'enterprise',
|
|
'events',
|
|
'explore',
|
|
'featured',
|
|
'features',
|
|
'files',
|
|
'fixtures',
|
|
'forked',
|
|
'fraud',
|
|
'garage',
|
|
'gist',
|
|
'gists',
|
|
'graphs',
|
|
'groups',
|
|
'guide',
|
|
'guides',
|
|
'help',
|
|
'help-wanted',
|
|
'home',
|
|
'hooks',
|
|
'hosting',
|
|
'hovercards',
|
|
'identity',
|
|
'images',
|
|
'inbox',
|
|
'index',
|
|
'individual',
|
|
'info',
|
|
'integration',
|
|
'interfaces',
|
|
'introduction',
|
|
'invalid-email-address',
|
|
'investors',
|
|
'invoice',
|
|
'invoices',
|
|
'issues',
|
|
'jobs',
|
|
'join',
|
|
'journal',
|
|
'journals',
|
|
'lab',
|
|
'labs',
|
|
'languages',
|
|
'launch',
|
|
'layouts',
|
|
'learn',
|
|
'legal',
|
|
'library',
|
|
'linux',
|
|
'listings',
|
|
'lists',
|
|
'livewire',
|
|
'login',
|
|
'logos',
|
|
'logout',
|
|
'mac',
|
|
'maintenance',
|
|
'malware',
|
|
'man',
|
|
'mariadb',
|
|
'marketing',
|
|
'marketplace',
|
|
'mention',
|
|
'mentioned',
|
|
'mentioning',
|
|
'mentions',
|
|
'migrating',
|
|
'milestones',
|
|
'mine',
|
|
'mirrors',
|
|
'mobile',
|
|
'mysql',
|
|
'n8n',
|
|
'navigation',
|
|
'network',
|
|
'network-rules',
|
|
'new',
|
|
'news',
|
|
'none',
|
|
'nonprofit',
|
|
'nonprofits',
|
|
'notices',
|
|
'notifications',
|
|
'oauth',
|
|
'offer',
|
|
'open-source',
|
|
'org',
|
|
'organisations',
|
|
'organizations',
|
|
'orgs',
|
|
'pages',
|
|
'partners',
|
|
'pay',
|
|
'payable',
|
|
'payments',
|
|
'percona',
|
|
'personal',
|
|
'plans',
|
|
'plugins',
|
|
'popular',
|
|
'popularity',
|
|
'posts',
|
|
'postgres',
|
|
'postgresql',
|
|
'press',
|
|
'preview',
|
|
'pricing',
|
|
'professional',
|
|
'projects',
|
|
'pulls',
|
|
'raw',
|
|
'readme',
|
|
'recommendations',
|
|
'receivable',
|
|
'redeem',
|
|
'register',
|
|
'releases',
|
|
'render',
|
|
'reply',
|
|
'repositories',
|
|
'resources',
|
|
'restore',
|
|
'revert',
|
|
'review',
|
|
'reviews',
|
|
'save-net-neutrality',
|
|
'saved',
|
|
'scraping',
|
|
'search',
|
|
'security',
|
|
'services',
|
|
'sessions',
|
|
'settings',
|
|
'shareholders',
|
|
'shop',
|
|
'showcases',
|
|
'signin',
|
|
'sign-in',
|
|
'signup',
|
|
'sign-up',
|
|
'site',
|
|
'socials',
|
|
'spam',
|
|
'sponsors',
|
|
'ssh',
|
|
'staff',
|
|
'starred',
|
|
'stars',
|
|
'start',
|
|
'static',
|
|
'status',
|
|
'statuses',
|
|
'storage',
|
|
'store',
|
|
'stories',
|
|
'stripe',
|
|
'styleguide',
|
|
'subscriptions',
|
|
'suggest',
|
|
'suggestion',
|
|
'suggestions',
|
|
'support',
|
|
'suspended',
|
|
'suspension',
|
|
'talks',
|
|
'teach',
|
|
'teacher',
|
|
'teachers',
|
|
'teaching',
|
|
'team',
|
|
'teams',
|
|
'ten',
|
|
'terms',
|
|
'timeline',
|
|
'topic',
|
|
'topics',
|
|
'tos',
|
|
'tour',
|
|
'train',
|
|
'training',
|
|
'translations',
|
|
'tree',
|
|
'trending',
|
|
'undefined',
|
|
'update',
|
|
'updates',
|
|
'upstash',
|
|
'username',
|
|
'users',
|
|
'visualization',
|
|
'watching',
|
|
'wiki',
|
|
'wikis',
|
|
'windows',
|
|
'works-with',
|
|
'www',
|
|
'www0',
|
|
'www1',
|
|
'www2',
|
|
'www3',
|
|
'www4',
|
|
'www5',
|
|
'www6',
|
|
'www7',
|
|
'www8',
|
|
'www9',
|
|
'zones',
|
|
])
|
|
->unique()
|
|
->sort()
|
|
->values()
|
|
->toArray());
|
|
}
|
|
|
|
/**
|
|
* Get a list of reserved names from the application's route prefixes.
|
|
*/
|
|
protected function routesPrefixes(): array
|
|
{
|
|
return collect(Route::getRoutes()->getRoutes())
|
|
->map(fn (RouteElement $route) => $route->uri)
|
|
->map(fn (string $uri) => explode('/', $uri)[0])
|
|
->reject(fn (string $uri) => str_contains($uri, '{'))
|
|
->filter(fn (string $uri) => $uri !== '')
|
|
->unique()
|
|
->sort()
|
|
->values()
|
|
->toArray();
|
|
}
|
|
}
|