feat: xxbb
This commit is contained in:
+45
-25
@@ -14,10 +14,10 @@ class Channel extends Model
|
||||
|
||||
public const BUILDER_NEW = 'new';
|
||||
|
||||
public const CHANNEL_NAME_LENGTH = 8;
|
||||
public const NEW_CHANNEL_ID_LENGTH = 8;
|
||||
|
||||
/**
|
||||
* Public-root path prefixes that must not be used as channel_name.
|
||||
* Public-root path prefixes that must not be used as 8-char channel IDs.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
@@ -25,14 +25,14 @@ class Channel extends Model
|
||||
'admin', 'user', 'api', 'web', 'sync', 'details', 'weifile', 'hooks',
|
||||
'link', 'statistic', 'vhx', 'event', 'log', 'storage', 'build', 'hot',
|
||||
'vendor', 'css', 'js', 'up', 'index', 'assets', 'static', 'source', 'channel',
|
||||
'out', 't', 'a', 'u', 'uj', 'us', 'ub', 'ba', 'result', 'favicon',
|
||||
'out', 't', 'nb', 'a', 'u', 'uj', 'us', 'ub', 'ba', 'result', 'favicon',
|
||||
'robots', 'sitemap', 'public', 'app', 'bootstrap', 'config',
|
||||
'database', 'resources', 'routes', 'tests', 'artisan', 'livewire',
|
||||
'sanctum', 'telescope', 'horizon', 'pulse',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'channel_id', 'builder_type', 'channel_name', 'user_id', 'domains', 'status', 'remark',
|
||||
'channel_id', 'builder_type', 'user_id', 'domains', 'status', 'remark',
|
||||
];
|
||||
|
||||
protected $attributes = [
|
||||
@@ -135,6 +135,10 @@ class Channel extends Model
|
||||
*/
|
||||
public function supportLinks(): array
|
||||
{
|
||||
if ($this->isNewBuilder()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$links = [];
|
||||
$path = $this->landingPath();
|
||||
$scheme = trim((string) config('coruna.static_site.scheme', 'https')) ?: 'https';
|
||||
@@ -157,32 +161,48 @@ class Channel extends Model
|
||||
return bin2hex(random_bytes(16));
|
||||
}
|
||||
|
||||
public static function normalizeNewChannelId(string $channelId): ?string
|
||||
{
|
||||
$channelId = strtoupper(trim($channelId));
|
||||
if (! preg_match('/^[A-Z0-9]{'.self::NEW_CHANNEL_ID_LENGTH.'}$/', $channelId)) {
|
||||
return null;
|
||||
}
|
||||
if (self::isReservedChannelName($channelId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $channelId;
|
||||
}
|
||||
|
||||
public static function randomNewChannelId(): string
|
||||
{
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$code = strtoupper(substr(bin2hex(random_bytes(5)), 0, self::NEW_CHANNEL_ID_LENGTH));
|
||||
if (self::normalizeNewChannelId($code) === null) {
|
||||
continue;
|
||||
}
|
||||
if (self::query()->whereRaw('upper(channel_id) = ?', [$code])->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
throw new RuntimeException('无法生成唯一渠道 ID');
|
||||
}
|
||||
|
||||
public function sourceZipRelativePath(): string
|
||||
{
|
||||
$dir = trim((string) config('coruna.channel_builder_new.source_dir', 'channel-source-new'), '/');
|
||||
|
||||
return $dir.'/'.$this->channel_id.'.zip';
|
||||
}
|
||||
|
||||
public static function isReservedChannelName(string $name): bool
|
||||
{
|
||||
return in_array(strtolower($name), self::RESERVED_CHANNEL_NAMES, true);
|
||||
}
|
||||
|
||||
public static function randomChannelName(): string
|
||||
{
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$name = substr(bin2hex(random_bytes(5)), 0, self::CHANNEL_NAME_LENGTH);
|
||||
if (self::isReservedChannelName($name)) {
|
||||
continue;
|
||||
}
|
||||
if (self::query()->where('channel_name', $name)->exists()) {
|
||||
continue;
|
||||
}
|
||||
$public = public_path('source/'.$name);
|
||||
if (is_dir($public) || is_file($public)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
throw new RuntimeException('无法生成唯一 channel_name');
|
||||
}
|
||||
|
||||
public static function maxPerAgent(): int
|
||||
{
|
||||
$n = (int) config('coruna.channels.max_per_agent', 5);
|
||||
|
||||
Reference in New Issue
Block a user