Beispiel #1
0
        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="userDto">用于注册的用户信息</param>
        /// <returns>异步获取Token的任务,如果发生异常则会返回错误信息</returns>
        public async Task <(AccessTokenResponseDto, Dictionary <string, string>)> RegisterAsync(UserRegisterRequestDto userDto)
        {
            // 如果用户不是通过浏览器在请求接口,失去焦点时验证用户名的动作就没意义
            var error = await ValidateUsernameAsync(userDto.Username);

            if (!string.IsNullOrEmpty(error))
            {
                return(null, new Dictionary <string, string>
                {
                    ["username"] = error
                });
            }

            // 验证验证码
            error = await ValidateCaptchaAsync(userDto.CaptchaId, userDto.CaptchaText);

            if (!string.IsNullOrEmpty(error))
            {
                return(null, new Dictionary <string, string>
                {
                    ["captcha"] = error
                });
            }

            try
            {
                Guid salt = Guid.NewGuid();
                var  user = new User
                {
                    Username     = userDto.Username,
                    PasswordHash = GeneratePasswordHash(userDto.Password, salt.ToString()),
                    Salt         = salt.ToString(),
                    // 默认为普通用户
                    RoleId = (int)Roles.User
                };
                _dbContext.User.Add(user);
                await _dbContext.SaveChangesAsync();

                var token = new AccessTokenResponseDto
                {
                    AccessToken  = await _tokenAuthService.GenerateAccessTokenAsync(user),
                    RefreshToken = await _tokenAuthService.GenerateRefreshTokenAsync(user)
                };
                return(token, null);
            }
            catch
            {
                // 因为是多线程,依旧可能用户名重复
                // 用户名重复会导致异常
                return(null, new Dictionary <string, string>
                {
                    ["username"] = _msg.GetMessage("E003", "用户名")
                });
            }
        }
Beispiel #2
0
        /// <summary>
        /// 创建房间
        /// </summary>
        /// <param name="uid">用户ID</param>
        /// <param name="roomDto">用户输入的用于创建房间的信息</param>
        /// <returns>表示异步创建房间的任务,如果创建失败则返回错误信息</returns>
        public async Task <ChatRoomCreateResponseDto> CreateRoomAsync(int uid, ChatRoomDto roomDto)
        {
            // 防止用户打开多个窗口创建房间
            var error = await ApplyForCreatingRoomAsync(uid);

            if (!string.IsNullOrEmpty(error))
            {
                return(new ChatRoomCreateResponseDto
                {
                    Error = error,
                    CloseModalIfError = true
                });
            }
            try
            {
                var room = new ChatRoom
                {
                    OwnerId     = uid,
                    Name        = roomDto.Name,
                    MaxUsers    = roomDto.MaxUsers,
                    IsEncrypted = roomDto.IsEncrypted,
                    IsPermanent = roomDto.IsPermanent,
                    IsHidden    = roomDto.IsHidden,
                    AllowGuest  = roomDto.AllowGuest
                };

                // 如果房间被加密
                if (roomDto.IsEncrypted)
                {
                    Guid salt = Guid.NewGuid();
                    room.Salt         = salt.ToString();
                    room.PasswordHash = PasswordHelper.GeneratePasswordHash(roomDto.Password, room.Salt);
                }

                _dbContext.ChatRoom.Add(room);
                await _dbContext.SaveChangesAsync();

                return(new ChatRoomCreateResponseDto
                {
                    RoomId = HashidsHelper.Encode(room.Id)
                });
            }
            catch (Exception)
            {
                // 因为是多线程,任然可能发生异常
                // 房间名重复
                return(new ChatRoomCreateResponseDto
                {
                    Error = _msg.GetMessage("E003", "房间名"),
                    CloseModalIfError = false
                });
            }
        }
Beispiel #3
0
        /// <summary>
        /// 更新用户密码
        /// </summary>
        /// <param name="uid">用户ID</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>用于更新密码的任务,如果成功则返回新的TOKEN</returns>
        public async Task <AccessTokenResponseDto> UpdatePasswordAsync(int uid, string newPassword)
        {
            var user = await _dbContext.User.FindAsync(uid);

            Guid salt = Guid.NewGuid();

            user.Salt         = salt.ToString();
            user.PasswordHash = PasswordHelper.GeneratePasswordHash(newPassword, user.Salt);
            _dbContext.User.Update(user);
            await _dbContext.SaveChangesAsync();

            return(new AccessTokenResponseDto
            {
                AccessToken = await _tokenAuthService.GenerateAccessTokenAsync(user),
                RefreshToken = await _tokenAuthService.GenerateRefreshTokenAsync(user)
            });
        }
Beispiel #4
0
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="roomHashid">房间哈希ID</param>
        /// <param name="message">消息</param>
        /// <returns>表示发送消息的任务</returns>
        public async Task SendMessageAsync(string roomHashid, string message)
        {
            var userHashId           = Context.User.FindFirst("uid").Value;
            var username             = HttpUtility.UrlDecode(Context.User.Identity.Name);
            var unixTimeMilliseconds = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds();

            await Clients.Group(roomHashid)
            .InvokeAsync("receiveMessage", userHashId, username, message, unixTimeMilliseconds, false);

            // 将消息保存到数据库
            var history = new ChatHistory
            {
                RoomId = HashidsHelper.Decode(roomHashid),
                UserId = HashidsHelper.Decode(userHashId),
                UnixTimeMilliseconds = unixTimeMilliseconds,
                Username             = username,
                Message = message
            };

            _dbContext.ChatHistory.Add(history);
            await _dbContext.SaveChangesAsync();
        }