'boolean', 'use_totp' => 'boolean', 'gravatar' => 'boolean', ]; /** * @var array */ protected $dates = ['totp_authenticated_at']; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = ['password', 'remember_token', 'totp_secret', 'totp_authenticated_at']; /** * Default values for specific fields in the database. * * @var array */ protected $attributes = [ 'external_id' => null, 'root_admin' => false, 'language' => 'en', 'use_totp' => false, 'totp_secret' => null, ]; /** * Rules verifying that the data being stored matches the expectations of the database. */ public static array $validationRules = [ 'uuid' => 'required|string|size:36|unique:users,uuid', 'email' => 'required|email|between:1,191|unique:users,email', 'external_id' => 'sometimes|nullable|string|max:191|unique:users,external_id', 'username' => 'required|between:1,191|unique:users,username', 'password' => 'sometimes|nullable|string', 'admin_role_id' => 'sometimes|nullable|exists:admin_roles,id', 'root_admin' => 'boolean', 'language' => 'string', 'use_totp' => 'boolean', 'totp_secret' => 'nullable|string', ]; /** * Implement language verification by overriding Eloquence's gather * rules function. */ public static function getRules() { $rules = parent::getRules(); //$rules['language'][] = new In(array_keys((new self())->getAvailableLanguages())); $rules['username'][] = new Username(); return $rules; } /** * Return the user model in a format that can be passed over to Vue templates. */ public function toReactObject(): array { $object = (new Collection($this->toArray()))->except(['id', 'external_id'])->toArray(); $object['avatar_url'] = $this->avatarURL(); $object['role_name'] = $this->adminRoleName(); return $object; } /** * Send the password reset notification. * * @param string $token */ public function sendPasswordResetNotification($token) { $this->notify(new ResetPasswordNotification($token)); } /** * Store the username as a lowercase string. */ public function setUsernameAttribute(string $value) { $this->attributes['username'] = mb_strtolower($value); } /** * Gets the avatar url for the user. */ public function avatarURL(): string { return 'https://www.gravatar.com/avatar/' . md5($this->email) . '.jpg'; } /** * Gets the name of the role assigned to a user. */ public function adminRoleName(): ?string { $role = $this->adminRole; if (is_null($role)) { return $this->root_admin ? 'None' : null; } return $role->name; } public function adminRole(): HasOne { return $this->hasOne(AdminRole::class, 'id', 'admin_role_id'); } public function servers(): HasMany { return $this->hasMany(Server::class, 'owner_id'); } public function sshKeys(): HasMany { return $this->hasMany(UserSSHKey::class); } public function recoveryTokens(): HasMany { return $this->hasMany(RecoveryToken::class); } public function securityKeys(): HasMany { return $this->hasMany(SecurityKey::class); } /** * Returns all of the servers that a user can access by way of being the owner of the * server, or because they are assigned as a subuser for that server. */ public function accessibleServers(): Builder { return Server::query() ->select('servers.*') ->leftJoin('subusers', 'subusers.server_id', '=', 'servers.id') ->where(function (Builder $builder) { $builder->where('servers.owner_id', $this->id)->orWhere('subusers.user_id', $this->id); }) ->groupBy('servers.id'); } /** * @return \Webauthn\PublicKeyCredentialUserEntity */ public function toPublicKeyCredentialEntity(): PublicKeyCredentialUserEntity { return new PublicKeyCredentialUserEntity($this->username, $this->uuid, $this->email, null); } }