/// <inheritdoc />
        public async Task <ForgotPasswordResult> StartForgotPasswordProcess(MediaBrowser.Controller.Entities.User user, bool isInNetwork)
        {
            string pin = string.Empty;

            using (var cryptoRandom = RandomNumberGenerator.Create())
            {
                byte[] bytes = new byte[4];
                cryptoRandom.GetBytes(bytes);
                pin = BitConverter.ToString(bytes);
            }

            DateTime expireTime           = DateTime.Now.AddMinutes(30);
            string   filePath             = _passwordResetFileBase + user.InternalId + ".json";
            SerializablePasswordReset spr = new SerializablePasswordReset
            {
                ExpirationDate = expireTime,
                Pin            = pin,
                PinFile        = filePath,
                UserName       = user.Name
            };

            using (FileStream fileStream = File.OpenWrite(filePath))
            {
                _jsonSerializer.SerializeToStream(spr, fileStream);
                await fileStream.FlushAsync().ConfigureAwait(false);
            }

            return(new ForgotPasswordResult
            {
                Action = ForgotPasswordAction.PinCode,
                PinExpirationDate = expireTime,
                PinFile = filePath
            });
        }
        /// <summary> Gets an option. </summary>
        /// <param name="header"> The header. </param>
        /// <param name="sortField"> The sort field. </param>
        /// <returns> The option. </returns>
        private ReportOptions <ActivityLogEntry> GetOption(HeaderMetadata header, string sortField = "")
        {
            HeaderMetadata internalHeader = header;

            ReportOptions <ActivityLogEntry> option = new ReportOptions <ActivityLogEntry>()
            {
                Header = new ReportHeader
                {
                    HeaderFieldType = ReportFieldType.String,
                    SortField       = sortField,
                    Type            = "",
                    ItemViewType    = ItemViewType.None
                }
            };

            switch (header)
            {
            case HeaderMetadata.Name:
                option.Column           = (i, r) => i.Name;
                option.Header.SortField = "";
                break;

            case HeaderMetadata.Overview:
                option.Column           = (i, r) => i.Overview;
                option.Header.SortField = "";
                option.Header.CanGroup  = false;
                break;

            case HeaderMetadata.ShortOverview:
                option.Column           = (i, r) => i.ShortOverview;
                option.Header.SortField = "";
                option.Header.CanGroup  = false;
                break;

            case HeaderMetadata.Type:
                option.Column           = (i, r) => i.Type;
                option.Header.SortField = "";
                break;

            case HeaderMetadata.Date:
                option.Column                 = (i, r) => i.Date.ToLocalTime().ToString("G");
                option.Header.SortField       = "";
                option.Header.HeaderFieldType = ReportFieldType.DateTime;
                option.Header.Type            = "";
                break;

            case HeaderMetadata.UserPrimaryImage:
                //option.Column = (i, r) => i.UserPrimaryImageTag;
                option.Header.DisplayType     = ReportDisplayType.Screen;
                option.Header.ItemViewType    = ItemViewType.UserPrimaryImage;
                option.Header.ShowHeaderLabel = false;
                internalHeader         = HeaderMetadata.User;
                option.Header.CanGroup = false;
                option.Column          = (i, r) =>
                {
                    if (!string.IsNullOrEmpty(i.UserId))
                    {
                        MediaBrowser.Controller.Entities.User user = _userManager.GetUserById(i.UserId);
                        if (user != null)
                        {
                            var dto = _userManager.GetUserDto(user);
                            return(dto.PrimaryImageTag);
                        }
                    }
                    return(string.Empty);
                };
                option.Header.SortField = "";
                break;

            case HeaderMetadata.Severity:
                option.Column           = (i, r) => i.Severity;
                option.Header.SortField = "";
                break;

            case HeaderMetadata.Item:
                option.Column           = (i, r) => i.ItemId;
                option.Header.SortField = "";
                break;

            case HeaderMetadata.User:
                option.Column = (i, r) =>
                {
                    if (!string.IsNullOrEmpty(i.UserId))
                    {
                        MediaBrowser.Controller.Entities.User user = _userManager.GetUserById(i.UserId);
                        if (user != null)
                        {
                            return(user.Name);
                        }
                    }
                    return(string.Empty);
                };
                option.Header.SortField = "";
                break;

            case HeaderMetadata.UserId:
                option.Column           = (i, r) => i.UserId;
                option.Header.SortField = "";
                break;
            }

            option.Header.Name      = GetLocalizedHeader(internalHeader);
            option.Header.FieldName = header;

            return(option);
        }
        public IAlexaSession GetSession(IAlexaRequest alexaRequest, User user = null)
        {
            // A UserEvent can only happen in an open session because sessions will always start with voice.
            if (string.Equals(alexaRequest.request.type, "Alexa.Presentation.APL.UserEvent"))
            {
                return(OpenSessions.FirstOrDefault(s => s.SessionId == alexaRequest.session.sessionId));
            }

            var context = alexaRequest.context;
            var system  = context.System;
            //var person = system.person;
            var amazonSession = alexaRequest.session;

            IAlexaRequest persistedRequestData = null;
            IAlexaSession sessionInfo          = null;

            //Room room                          = null;

            if (OpenSessions.Exists(s => s.SessionId.Equals(amazonSession.sessionId)))
            {
                sessionInfo = OpenSessions.FirstOrDefault(s => s.SessionId == amazonSession.sessionId);

                persistedRequestData = sessionInfo?.PersistedRequestData;
                //room = sessionInfo?.room;

                // ReSharper disable once ComplexConditionExpression
                //if (!(person is null) && !(sessionInfo?.person is null))
                //{
                //    if (string.Equals(sessionInfo.person.personId, person.personId))
                //    {
                //        return sessionInfo; // It is the same person speaking - return the sessionInfo.
                //    }
                //}

                // Remove the session from the "OpenSessions" List, and rebuild the session with the new data
                OpenSessions.RemoveAll(s => s.SessionId.Equals(alexaRequest.session.sessionId));
            }

            // Sync AMAZON session Id with our own.
            sessionInfo = new AlexaSession()
            {
                SessionId          = amazonSession.sessionId,
                EmbySessionId      = !(sessionInfo?.room is null) ? GetCorrespondingEmbySessionId(sessionInfo) : string.Empty,
                context            = context,
                EchoDeviceId       = system.device.deviceId,
                NowViewingBaseItem = sessionInfo?.NowViewingBaseItem,
                supportsApl        = SupportsApl(alexaRequest),
                room                 = sessionInfo?.room,
                hasRoom              = !(sessionInfo?.room is null),
                User                 = user,
                viewport             = GetCurrentViewport(alexaRequest),
                PersistedRequestData = persistedRequestData,
                paging               = new Paging {
                    pages = new Dictionary <int, Properties <MediaItem> >()
                }
            };

            OpenSessions.Add(sessionInfo);

            return(sessionInfo);
        }