create([ 'name' => $name, 'email' => $email, 'password' => $plainTextPassword ? Hash::make($plainTextPassword) : '', 'is_admin' => $isAdmin, 'sso_id' => $ssoId, 'sso_provider' => $ssoProvider, 'avatar' => $avatar ? $this->createNewAvatar($avatar) : null, ]); } public function createOrUpdateUserFromSSO(SSOUser $ssoUser): User { License::requirePlus(); $existingUser = $this->repository->findOneBySSO($ssoUser); if ($existingUser) { $existingUser->update([ 'avatar' => $existingUser->has_custom_avatar ? $existingUser->avatar : $ssoUser->avatar, 'sso_id' => $ssoUser->id, 'sso_provider' => $ssoUser->provider, ]); return $existingUser; } return $this->createUser( name: $ssoUser->name, email: $ssoUser->email, plainTextPassword: '', isAdmin: false, avatar: $ssoUser->avatar, ssoId: $ssoUser->id, ssoProvider: $ssoUser->provider, ); } public function updateUser( User $user, string $name, string $email, ?string $password = null, ?bool $isAdmin = null, ?string $avatar = null ): User { throw_if($user->is_prospect, new UserProspectUpdateDeniedException()); if ($user->sso_provider) { // An SSO profile is largely managed by the SSO provider $user->update([ 'is_admin' => $isAdmin ?? $user->is_admin, 'name' => $name, 'avatar' => $avatar ? $this->createNewAvatar($avatar, $user) : null, ]); } else { $user->update([ 'name' => $name, 'email' => $email, 'password' => $password ? Hash::make($password) : $user->password, 'is_admin' => $isAdmin ?? $user->is_admin, 'avatar' => $avatar ? $this->createNewAvatar($avatar, $user) : null, ]); } return $user; } /** * @param string $avatar Either the URL of the avatar or image data */ private function createNewAvatar(string $avatar, ?User $user = null): string { if (Str::startsWith($avatar, ['http://', 'https://'])) { return $avatar; } $path = self::generateUserAvatarPath(); $this->imageWriter->write($path, $avatar, ['max_width' => 480]); optional($user?->getRawOriginal('avatar'), static fn (string $oldAvatar) => File::delete($oldAvatar)); return basename($path); } public function deleteUser(User $user): void { $user->delete(); } public function savePreference(User $user, string $key, mixed $value): void { $user->preferences = $user->preferences->set($key, $value); $user->save(); } private static function generateUserAvatarPath(): string { return user_avatar_path(sprintf('%s.webp', sha1(Str::uuid()))); } }