
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\XApiToken.cs

using System.ComponentModel.DataAnnotations.Schema;
using xCommons.Extensions;
using xModels.Base;
using xIdentityModels.Models;

namespace xIdentityModels {
    public class XApiToken : XBaseIntIDEntity {
        public string Content { get; set; }

        [NotMapped]
        public XTokenResponse Tokens {
            get { return Content.IsNullOrEmpty () ? null : Content.FromJSON<XTokenResponse> (); }
            set { Content = value.ToJSON (); }
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\XUser.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Identity;
using xIdentityModels.Constants;
using xIdentityModels.Navigations;

namespace xIdentityModels
{
    /// <summary>
    /// represnt a User of System
    /// </summary>
    public partial class XUser : IdentityUser
    {
        //
        #region Properties ...
        /// <summary>
        /// FirstName
        /// </summary>
        /// <value>user's FirstName</value>
        [Required]
        [StringLength(50)]
        public string FirstName { get; set; }
        /// <summary>
        /// LastName
        /// </summary>
        /// <value>user's LastName</value>
        [Required]
        [StringLength(100)]
        public string LastName { get; set; }
        /// <summary>
        /// User is Enabled or not
        /// </summary>
        /// <remarks>
        /// system was restrict Disabled Users access to Many Resources
        /// </remarks>
        /// <value>boolean value represent User is Enable or not</value>
        public bool IsEnable { get; set; }
        /// <summary>
        /// User is Banned or not
        /// </summary>
        /// <remarks>
        /// system was reject Banned Users access to Almost all Resources
        /// </remarks>
        /// <value>boolean value represent User is Banned or not</value>
        public bool IsBanned { get; set; }
        /// <summary>
        /// DateOfBirth
        /// </summary>
        /// <value>user's DateOfBirth</value>
        [Required]
        public DateTime DateOfBirth { get; set; }
        /// <summary>
        /// CreationDate
        /// </summary>
        /// <value>user's Creation/Registration Date</value>
        [Required]
        public DateTime CreationDate { get; set; }
        /// <summary>
        /// LastLogin
        /// </summary>
        /// <value>user's Last Successfull Login Date</value>
        public DateTime? LastLogin { get; set; }
        /// <summary>
        /// ProfileImage/Avatar
        /// </summary>
        /// <value>user's current Avatar</value>
        public string Avatar { get; set; }
        /// <summary>
        /// Gender
        /// </summary>
        /// <value>user's Gender</value>
        [Required]
        public XGender Gender { get; set; }
        /// <summary>
        /// User Biography ...
        /// </summary>
        /// <value></value>
        public string Bio { get; set; }
        /// <summary>
        /// User Bio Cover Image ...
        /// </summary>
        /// <value></value>
        public string CoverImage { get; set; }
        /// <summary>
        /// Can Discover User ...
        /// </summary>
        /// <value></value>
        public bool OpenToSearch { get; set; }
        #endregion

        //
        #region Navigation Properties ...
        /// <summary>
        /// User's Devices
        /// </summary>
        /// <typeparam name="XDevice"><see>XDevice</see></typeparam>
        /// <returns>a Collection of all assigned Devices to User</returns>
        [InverseProperty("User")]
        public virtual ICollection<XDevice> Devices { get; set; } = new HashSet<XDevice>();
        /// <summary>
        /// User's Avatars
        /// </summary>
        /// <typeparam name="XProfileImage"><see>XProfileImage</see></typeparam>
        /// <returns>a Collection of all assigned Avatars to User</returns>
        [InverseProperty("User")]
        public virtual ICollection<XProfileImage> Avatars { get; set; } = new HashSet<XProfileImage>();
        /// <summary>
        /// User's Followers
        /// </summary>
        /// <typeparam name="XFriendshipFollower"><see>XFriendshipFollower</see></typeparam>
        /// <returns>a Collection of all User's Followers</returns>
        [InverseProperty("User")]
        public virtual ICollection<XFriendshipFollower> Followers { get; set; } = new HashSet<XFriendshipFollower>();
        /// <summary>
        /// User's Followings
        /// </summary>
        /// <typeparam name="XFriendshipFollowing"><see>XFriendshipFollowing</see></typeparam>
        /// <returns>a Collection of all User's Followings</returns>
        [InverseProperty("User")]
        public virtual ICollection<XFriendshipFollowing> Followings { get; set; } = new HashSet<XFriendshipFollowing>();
        /// <summary>
        /// User's Roles
        /// </summary>
        /// <returns>a Collection of all User's Roles in System</returns>
        public virtual ICollection<IdentityUserRole<string>> Roles { get; set; } = new HashSet<IdentityUserRole<string>>();
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityConfiguration.cs

using System.Collections.Generic;
using xIdentityModels.Dtos;

namespace xIdentityModels.Configurations {
    public class XIdentityConfiguration {
        //
        // Define All Policies which can Apply to Identity Framework
        // and also create a Default instance if it's not Exists
        // in AppSetting JSON file ...
        public XIdentityPolicy Policy { get; set; }

        /// <summary>
        /// the Security Key which used to Signing JWT Tokens
        /// in Authentication Provider
        /// </summary>
        /// <value></value>
        public string IdentitySecretKey { get; set; }

        /// <summary>
        /// the Issuer and Creator of Token 
        /// </summary>
        /// <value></value>
        public string IdentityIssuer { get; set; }

        /// <summary>
        /// the Audience and Consumer of Token
        /// </summary>
        /// <value></value>
        public string IdentityAudience { get; set; }

        /// <summary>
        /// the List of Users Roles which must Provides in Identity
        /// </summary>
        /// <value></value>
        public HashSet<string> IdentityRoles { get; set; }

        /// <summary>
        /// determines All new users must Assign to which role in Registration
        /// </summary>
        /// <value></value>
        public string NewUsersRole { get; set; }

        /// <summary>
        /// determines New Registered Users Confirm Email or not
        /// </summary>
        /// <value></value>
        public bool AutoConfirmNewUsersEmail { get; set; }

        /// <summary>
        /// determines New Registered Users Confirm PhoneNumber or not
        /// </summary>
        /// <value></value>
        public bool AutoConfirmNewUsersPhoneNumber { get; set; }

        /// <summary>
        /// determines the Registration only Can be done with Invitation or not
        /// </summary>
        /// <value></value>
        public bool RegistrationJustWithInvite { get; set; }

        /// <summary>
        /// determines the Registration required confirmation with email or not 
        /// </summary>
        /// <value></value>
        public bool RequireRegistrationConfirm { get; set; }

        //
        public int MaxNumberOfVerificationCodeSend { get; set; }

        //
        public int DeleyBetweenTwoVerificationCode { get; set; }

        public int BannedDeviceTimeout { get; set; }

        /// <summary>
        /// an string Which Provide how long a action token can be valid
        /// </summary>
        /// <value></value>
        public string ActionTokenExpirationDateProvider { get; set; }

        public HashSet<XIdentityMessageDto> IdentityMessages { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicy.cs

namespace xIdentityModels.Configurations {
    /// <summary>
    /// Provide the Available Policies with their Default Values
    /// </summary>
    public class XIdentityPolicy {
        /// <summary>
        /// User Account Lock Policies
        /// </summary>
        /// <value></value>
        public XIdentityPolicyLockout Lockout { get; set; }

        /// <summary>
        /// User Password Policies
        /// </summary>
        /// <value></value>
        public XIdentityPolicyPassword Password { get; set; }

        /// <summary>
        /// the Policies for User for Allowing to SignIn 
        /// </summary>
        /// <value></value>
        public XIdentityPolicySignIn SignIn { get; set; }

        /// <summary>
        /// the Policies for User
        /// </summary>
        /// <value></value>
        public XIdentityPolicyUser User { get; set; }

        /// <summary>
        /// the policies which determines how to 
        /// populate user profile
        /// </summary>
        /// <value></value>
        public XIdentityProfile Profile { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicyLockout.cs

namespace xIdentityModels.Configurations {
    /// <summary>
    /// User Account Lock Policies
    /// </summary>
    public class XIdentityPolicyLockout {
        /// <summary>
        /// The String which Provide Time Span Delais 
        /// between Lockout and UnLock a User Account
        /// this Provided String the Parsed before Use
        /// </summary>
        /// <value></value>
        public string LockoutTimeSpanProvider { get; set; }

        /// <summary>
        /// the Number of InvalidLoginAttemps which can
        /// Happens to Lockout User Account
        /// </summary>
        /// <value></value>
        public byte MaxFailedAccessAttempts { get; set; }

        /// <summary>
        /// determines Lockout mechanism allowed for new Users or not
        /// </summary>
        /// <value></value>
        public bool AllowedForNewUsers { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicyPassword.cs

namespace xIdentityModels.Configurations {
    /// <summary>
    /// User Password Policies
    /// </summary>
    public class XIdentityPolicyPassword {
        /// <summary>
        /// determines Password must contains digits or not
        /// </summary>
        /// <value></value>
        public bool RequireDigit { get; set; }

        /// <summary>
        /// determines the minimum allowed length for a password
        /// </summary>
        /// <value></value>
        public byte RequiredLength { get; set; }

        /// <summary>
        /// determines the number of Unique Chars must be included in a Password
        /// </summary>
        /// <value></value>
        public byte RequiredUniqueChars { get; set; }

        /// <summary>
        /// determines Password must contains LowerCase chars or not
        /// </summary>
        /// <value></value>
        public bool RequireLowercase { get; set; }

        /// <summary>
        /// determines Password must contains Non-Alphabetical chars or not
        /// </summary>
        /// <value></value>
        public bool RequireNonAlphanumeric { get; set; }

        /// <summary>
        /// determines Password must contains UpperCase chars or not
        /// </summary>
        /// <value></value>
        public bool RequireUppercase { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicySignIn.cs

namespace xIdentityModels.Configurations {
    /// <summary>
    /// the Policies for User for Allowing to SignIn
    /// </summary>
    public class XIdentityPolicySignIn {
        /// <summary>
        /// determines only enabled users can SignIn
        /// </summary>
        /// <value></value>
        public bool RequiredEnabled { get; set; }

        /// <summary>
        /// determines User must Confirm the given Email Address
        /// before Login or not
        /// </summary>
        /// <value></value>
        public bool RequireConfirmedEmail { get; set; }

        /// <summary>
        /// determines User must Confirm the given Phone Number 
        /// before Login or not
        /// </summary>
        /// <value></value>
        public bool RequireConfirmedPhoneNumber { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityPolicyUser.cs

using System.Collections.Generic;

namespace xIdentityModels.Configurations {
    /// <summary>
    /// the Policies for User
    /// </summary>
    public class XIdentityPolicyUser {
        /// <summary>
        /// determines Allowed characters which can used in UserName
        /// </summary>
        /// <value></value>
        public string AllowedUserNameCharacters { get; set; }

        /// <summary>
        /// determines the Email Address of each User must be Unique or not
        /// </summary>
        /// <value></value>
        public bool RequireUniqueEmail { get; set; }

        /// <summary>
        /// minimum length of User Name
        /// </summary>
        /// <value></value>
        public byte MinLength { get; set; }

        /// <summary>
        /// maximum length of user name
        /// </summary>
        /// <value></value>
        public byte MaxLength { get; set; }

        /// <summary>
        /// Minimum Age for Registration
        /// </summary>
        /// <value></value>
        public int MinAgeForRegistration { get; set; }

        /// <summary>
        /// Maximum age for Registration
        /// </summary>
        /// <value></value>
        public int MaxAgeForRegistration { get; set; }

        /// <summary>
        /// a collection of invalid usernames
        /// </summary>
        /// <value></value>
        public ICollection<string> InvalidUserNames { get; set; } = new HashSet<string> ();
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Configurations\XIdentityProfile.cs

namespace xIdentityModels.Configurations {
    /// <summary>
    /// contains user profile configuration
    /// </summary>
    public class XIdentityProfile {
        /// <summary>
        /// determines user profile contain email or not
        /// </summary>
        /// <value></value>
        public bool ContainsEmail { get; set; }

        /// <summary>
        /// determines user profile contains phone number or not
        /// </summary>
        /// <value></value>
        public bool ContainsPhoneNumber { get; set; }

        /// <summary>
        /// determines user profile contains Roles collection or not
        /// </summary>
        /// <value></value>
        public bool ContainsRoles { get; set; }

        public bool ContainsDateOfBirth { get; set; }

        public bool ContainsLastLogin { get; set; }

        public bool ContainsCreationDate { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XAction.cs

namespace xIdentityModels.Constants {
    public enum XAction {
        Authentication,
        Invite,
        Registration,
        RequestMobileVerificationCode,
        ConfirmMobileNumber,
        RequestEmailVerificationCode,
        ConfirmEmailAddress,
        AddAccountInfo,
        AttachProfileImage,
        RequestResetPassword,
        ProfileAction,
        Finish,
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XFriendshipState.cs

namespace xIdentityModels.Constants {
    /// <summary>
    /// Represent State of Friendship between to Users
    /// </summary>
    public enum XFriendshipState {
        None,
        Pending,
        Accepted,
        Rejected,
        Blocked,
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XGender.cs

namespace xIdentityModels.Constants {
    /// <summary>
    /// Determines Available Genders
    /// </summary>
    public enum XGender {
        Male,
        Female
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\xIdentityModelsConstants.cs

namespace xIdentityModels.Constants {
    public class xIdentityModelsConstants { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Constants\XUserSelectBy.cs

namespace xIdentityModels.Constants {
    public enum XUserSelectBy {
        NotSpecified,
        ID,
        Username,
        Email,
        MobileNumber
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Descriptors\XIdentityUserDescriptor.cs

namespace xIdentityModels.Descriptors {
    /// <summary>
    /// contains default users information
    /// </summary>
    public class XIdentityUserDescriptor {
        public string Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }
        public bool EmailConfirmed { get; set; }
        public string PhoneNumber { get; set; }
        public bool PhoneNumberConfirmed { get; set; }
        public string Password { get; set; }
        public string Role { get; set; }
        public bool IsEnable { get; set; }
        public bool IsBanned { get; set; }
        public string DateOfBirth { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\DI\XDIHelperExtension.cs

namespace xIdentityModels.DI {
    public static partial class XDIHelperExtension { }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XDiscoveryDocumentDto.cs

using System.Collections.Generic;
using Newtonsoft.Json;

namespace xIdentityModels.Dtos
{
    public class XDiscoveryDocumentDto
    {
        [JsonProperty ("issuer")]
        public string Issuer { get; set; }

        [JsonProperty ("jwks_uri")]
        public string JwksUri { get; set; }

        [JsonProperty ("authorization_endpoint")]
        public string AuthorizationEndpoint { get; set; }

        [JsonProperty ("token_endpoint")]
        public string TokenEndpoint { get; set; }

        [JsonProperty ("userinfo_endpoint")]
        public string UserinfoEndpoint { get; set; }

        [JsonProperty ("end_session_endpoint")]
        public string EndSessionEndpoint { get; set; }

        [JsonProperty ("check_session_iframe")]
        public string CheckSessionIframe { get; set; }

        [JsonProperty ("revocation_endpoint")]
        public string RevocationEndpoint { get; set; }

        [JsonProperty ("introspection_endpoint")]
        public string IntrospectionEndpoint { get; set; }

        [JsonProperty ("device_authorization_endpoint")]
        public string DeviceAuthorizationEndpoint { get; set; }

        [JsonProperty ("frontchannel_logout_supported")]
        public bool FrontchannelLogoutSupported { get; set; }

        [JsonProperty ("frontchannel_logout_session_supported")]
        public bool FrontchannelLogoutSessionSupported { get; set; }

        [JsonProperty ("backchannel_logout_supported")]
        public bool BackchannelLogoutSupported { get; set; }

        [JsonProperty ("backchannel_logout_session_supported")]
        public bool BackchannelLogoutSessionSupported { get; set; }

        [JsonProperty ("scopes_supported")]
        public List<string> ScopesSupported { get; set; }

        [JsonProperty ("claims_supported")]
        public List<string> ClaimsSupported { get; set; }

        [JsonProperty ("grant_types_supported")]
        public List<string> GrantTypesSupported { get; set; }

        [JsonProperty ("response_types_supported")]
        public List<string> ResponseTypesSupported { get; set; }

        [JsonProperty ("response_modes_supported")]
        public List<string> ResponseModesSupported { get; set; }

        [JsonProperty ("token_endpoint_auth_methods_supported")]
        public List<string> TokenEndpointAuthMethodsSupported { get; set; }

        [JsonProperty ("id_token_signing_alg_values_supported")]
        public List<string> IdTokenSigningAlgValuesSupported { get; set; }

        [JsonProperty ("subject_types_supported")]
        public List<string> SubjectTypesSupported { get; set; }

        [JsonProperty ("code_challenge_methods_supported")]
        public List<string> CodeChallengeMethodsSupported { get; set; }

        [JsonProperty ("request_parameter_supported")]
        public bool RequestParameterSupported { get; set; }

        [JsonProperty ("account_api")]
        public string AccountApi { get; set; }        
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XFriendDto.cs

using xIdentityModels.Constants;
using xModels.Base;

namespace xIdentityModels.Dtos
{
    /// <summary>
    /// All Available Friendship Types ...
    /// </summary>
    public enum XFriendshipType
    {
        Follower = 0,
        Following = 1,
    }

    /// <summary>
    /// a DTO Class Which Represent a User Friends ...
    /// </summary>
    public class XFriendDto : XBaseDto
    {
        public string Avatar { get; set; }
        public string UserId { get; set; }
        public string Username { get; set; }
        public string Lastname { get; set; }
        public string Firstname { get; set; }
        public XFriendshipType Type { get; set; }
        public XFriendshipState State { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XFriendshipInfoDto.cs

using xModels.Base;
using xIdentityModels.Constants;

namespace xIdentityModels.Dtos {
    public class XFriendshipInfoDto : XBaseDto {
        public string UserId { get; set; }
        public bool IsFollower { get; set; }
        public bool IsFollowing { get; set; }
        public XFriendshipState FollowerState { get; set; }
        public XFriendshipState FollowingState { get; set; }
        public long Followers { get; set; }
        public long Followings { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XIdentityMessageDto.cs

using xModels.Base;

namespace xIdentityModels.Dtos {
    public class XIdentityMessageDto : XBaseDto {
        public string Language { get; set; }
        public string ResourceTitle { get; set; }
        public string TranslatedValue { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XOpenActionDto.cs

using System;
using xCommons.Extensions;
using xModels.Base;
using xModels.Dtos;

namespace xIdentityModels.Dtos
{
    /// <summary>
    /// a List of Available Open Actions ...
    /// </summary>
    public struct XOpenActions
    {
        public const string HandShake = "HandShake";
        public const string GetUserInfo = "GetUserInfo";
        public const string GetUserInfos = "GetUserInfos";
    }

    /// <summary>
    /// Open Actions Request Model ...
    /// </summary>
    public class XOpenActionRequestDto : XBaseDto
    {
        //
        public string Action { get; set; }
        public string Payload { get; set; }
        public string Checksum { get; set; }
        public XDeviceDto Device { get; set; }
        public string Timestamp { get; set; }

        /// <summary>
        /// Validate Model ...
        /// </summary>
        /// <returns></returns>
        public bool Validate()
        {
            //
            var result =
                !Device.IsNull() &&
                !Timestamp.IsNull() &&
                !Action.IsNullOrEmpty() &&
                (Action == XOpenActions.HandShake ||
                Action == XOpenActions.GetUserInfo ||
                Action == XOpenActions.GetUserInfos) &&
                !Int64.Parse(Timestamp).FromTimestamp().IsExPired();

            //
            return result;
        }

        /// <summary>
        /// Checksum Digest Model ...
        /// </summary>
        /// <returns></returns>
        public string ToOpenActionToken()
        {
            //
            var result = string.Empty;
            if (!Validate())
            {
                return result;
            }

            //
            var tmp = this;
            tmp.Checksum = string.Empty;

            //
            result = $"{tmp.ToJSON()}"
                .ToMd5String();
            return result;
        }

        /// <summary>
        /// Validate a Token is Correspond to Model or not ...
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool ValidateToken(string token)
        {
            //
            var result =
                Validate() &&
                !token.IsNullOrEmpty() &&
                token == ToOpenActionToken();

            //
            return result;
        }
    }

    /// <summary>
    /// aa Dto which used between Api's ...
    /// </summary>
    public class XOpenActionInnerDto : XBaseDto
    {
        public string Token { get; set; }
        public string Payload { get; set; }
    }

    /// <summary>
    /// User Info Providing in Open Actions ...
    /// </summary>
    public class XOpenActionUserInfoDto : XBaseDto
    {
        public string Username { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string Avatar { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XProfileImageDto.cs

using System;
using Newtonsoft.Json;
using xModels.Base;

namespace xIdentityModels.Dtos {
    public class XProfileImageDto : XBaseDto {
        public int Id { get; set; }

        [JsonProperty (
            "name",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string Name { get; set; }

        [JsonProperty (
            "thumb",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string Thumb { get; set; }

        [JsonProperty (
            "path",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string Path { get; set; }

        [JsonProperty (
            "thumbPath",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string ThumbPath { get; set; }

        [JsonProperty (
            "creationDate",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public DateTime CreationDate { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XUserNameIdRequest.cs

using System.Collections.Generic;
using xModels.Base;

namespace xIdentityModels.Dtos {
    public class XUserNameIdRequest : XBaseDto {
        public IEnumerable<string> Ids { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XUserNameIdResponse.cs

using xModels.Base;

namespace xIdentityModels.Dtos {
    public class XUserNameIdResponse : XBaseDto {
        public string Id { get; set; }
        public string UserName { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Dtos\XUserProfileDto.cs

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using xIdentityModels.Constants;
using xModels.Base;

namespace xIdentityModels.Dtos {
    public class XUserProfileDto : XBaseDto {
        [JsonProperty (
            "userId",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string UserId { get; set; }

        [JsonProperty (
            "userName",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string UserName { get; set; }

        [JsonProperty (
            "email",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string Email { get; set; }

        [JsonProperty (
            "emailConfirmed",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public bool EmailConfirmed { get; set; }

        [JsonProperty (
            "phoneNumber",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string PhoneNumber { get; set; }

        [JsonProperty (
            "phoneNumberConfirmed",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public bool PhoneNumberConfirmed { get; set; }

        [JsonProperty (
            "firstName",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string FirstName { get; set; }

        [JsonProperty (
            "lastName",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string LastName { get; set; }

        [JsonProperty (
            "dateOfBirth",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public DateTime? DateOfBirth { get; set; }

        [JsonProperty (
            "creationDate",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public DateTime? CreationDate { get; set; }

        [JsonProperty (
            "lastLogin",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public DateTime? LastLogin { get; set; }

        [JsonProperty (
            "avatar",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string Avatar { get; set; }

        [JsonProperty (
            "gender",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public XGender Gender { get; set; }

        [JsonProperty (
            "bio",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string Bio { get; set; }

        [JsonProperty (
            "coverImage",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string CoverImage { get; set; }

        [JsonProperty (
            "openToSearch",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public bool OpenToSearch { get; set; }

        [JsonProperty (
            "friendshipInfo",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public XFriendshipInfoDto FriendshipInfo { get; set; }

        [JsonProperty (
            "roles",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public ICollection<string> Roles { get; set; } = new HashSet<string> ();

        [JsonProperty (
            "avatars",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public ICollection<XProfileImageDto> Avatars { get; set; } = new HashSet<XProfileImageDto> ();

        [JsonProperty (
            "isEnable",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public bool IsEnable { get; set; }

        [JsonProperty (
            "isBanned",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public bool IsBanned { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\DIExtensions.cs

using Microsoft.Extensions.DependencyInjection;
using xCommons.Extensions;
using xIdentityModels.Interfaces;
using xIdentityModels.Providers;

namespace xIdentityModels.Extensions {
    public static class DIExtensions {
        /// <summary>
        /// since registering IXUserRoleHelper need to add default instance if
        /// user not provided we create this helper ...
        /// </summary>
        /// <param name="services"></param>
        public static void AddXUserRoleHandler (
            this IServiceCollection services,
            IXUserRoleHelper helper = null
        ) {
            //
            // Check if Provider is null ...
            if (helper.IsNull ()) {
                helper = services.GetRegisteredService<IXUserRoleHelper> ();
            }

            //
            // check if Provider registered or not ...
            if (helper.IsNull ()) {
                //
                // Create Default provider ...
                services.AddSingleton<IXUserRoleHelper> (new XDefaultUserRoleHelper ());
            } else {
                //
                // Register Given Helper ...
                services.AddSingleton<IXUserRoleHelper> (helper);
            }
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\XIdentityExtensions.cs

using System.Collections.Generic;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Models;

namespace xIdentityModels.Extensions {
    public static class XIdentityExtensions {
        public static XUserSelectBy GetUserSelectByType (
            this string source,
            bool forceUserSelectByParamNotEmpty = true,
            bool forceUserSelectByTypeMustSpecified = false
        ) {
            //
            // Validate Args ...
            if (source.IsNullOrEmpty () &&
                forceUserSelectByParamNotEmpty) {
                XException.InvalidArgs.Throw ();
            }

            //
            var result = XUserSelectBy.NotSpecified;
            var userSelectByParam = source.ToNormalString ();
            if (userSelectByParam.IsValidEmail ()) {
                //
                // Find User by Email ...
                result = XUserSelectBy.Email;
            } else if (userSelectByParam.IsValidMobileNumber ()) {
                //
                // Find User by Mobile Number ...
                result = XUserSelectBy.MobileNumber;
            } else if (userSelectByParam.IsGuid ()) {
                //
                // Find User By it's ID ...
                result = XUserSelectBy.ID;
            } else {
                //
                // UserName ...
                result = XUserSelectBy.Username;
            }

            //
            // Validation Result ...
            if (forceUserSelectByTypeMustSpecified &&
                result == XUserSelectBy.NotSpecified) {
                XException.InvalidData.Throw ();
            }

            //
            return result;
        }

        public static string GetUserSelectByParam (
            this XActionRequest source,
            bool forceNotNull = true,
            ICollection<XUserSelectBy> excludes = null
        ) {
            //
            // Validate Args ...
            if (source.IsNull ()) {
                XException.InvalidArgs.Throw ();
            }

            //
            var id = source.UserId;
            var userName = source.UserName;
            var email = source.Email;
            var phoneNumber = source.MobileNumber;

            //
            if (excludes != null) {
                //
                if (excludes.Contains (XUserSelectBy.ID)) {
                    id = null;
                }
                if (excludes.Contains (XUserSelectBy.Email)) {
                    email = null;
                }
                if (excludes.Contains (XUserSelectBy.MobileNumber)) {
                    phoneNumber = null;
                }
                if (excludes.Contains (XUserSelectBy.Username)) {
                    userName = null;
                }
            }

            //
            var selectByParam =
                id.IsNullOrEmpty () ?
                userName.IsNullOrEmpty () ?
                email.IsNullOrEmpty () ?
                phoneNumber.IsNullOrEmpty () ? null : phoneNumber : email : userName : id;

            //
            // Check result ...
            if (forceNotNull &&
                selectByParam.IsNullOrEmpty ()) {
                XException.InvalidData.Throw ();
            }

            //
            return selectByParam;
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\xIdentityModelsExtensions.cs

using System.Collections.Generic;
using System.Linq;
using xCommons.Extensions;
using xIdentityModels.Configurations;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;

namespace xIdentityModels.Extensions
{
    public static class xIdentityModelsExtensions
    {
        /// <summary>
        /// Converts a User Entity to Profile Dto ...
        /// </summary>
        /// <param name="source"></param>
        /// <param name="isAdmin"></param>
        /// <param name="isSameUser"></param>
        /// <param name="roles"></param>
        /// <param name="friendship"></param>
        /// <param name="profileConfig"></param>
        /// <returns></returns>
        public static XUserProfileDto ToXProfileDto(
            this XUser source,
            bool isAdmin = false,
            bool isSameUser = false,
            IEnumerable<string> roles = null,
            XFriendshipInfoDto friendship = null,
            XIdentityProfile profileConfig = null
        )
        {
            //
            XUserProfileDto result = null;

            //
            if (roles == null)
            {
                roles = new List<string>();
            }

            //
            // Prepare Dto ...
            if (!source.IsNullOrDefault())
            {
                //
                result = new XUserProfileDto
                {
                    Bio = source.Bio,
                    UserId = source.Id,
                    Email = source.Email,
                    Roles = roles.ToList(),
                    Avatar = source.Avatar,
                    IsEnable = source.IsEnable,
                    IsBanned = source.IsBanned,
                    UserName = source.UserName,
                    LastName = source.LastName,
                    FriendshipInfo = friendship,
                    FirstName = source.FirstName,
                    LastLogin = source.LastLogin,
                    CoverImage = source.CoverImage,
                    PhoneNumber = source.PhoneNumber,
                    DateOfBirth = source.DateOfBirth,
                    CreationDate = source.CreationDate,
                    OpenToSearch = source.OpenToSearch,
                    Gender = (XGender)(int)source.Gender,
                    EmailConfirmed = source.EmailConfirmed,
                    PhoneNumberConfirmed = source.PhoneNumberConfirmed,
                    Avatars = source.Avatars.Select(pfi =>
                    {
                        //
                        return new XProfileImageDto
                        {
                            Id = pfi.Id,
                            Name = pfi.Name,
                            Path = pfi.Path,
                            Thumb = pfi.Thumb,
                            ThumbPath = pfi.ThumbPath,
                            CreationDate = pfi.CreationDate
                        };
                    }).ToList(),
                };
            }

            //
            // Apply Profiling Configuration ...

            //
            bool isPassed = false;

            //
            // Handle Friendship ...
            isPassed = !isSameUser;
            if (!isPassed)
            {
                result.FriendshipInfo = null;
            }

            //
            // Handle Email Info ...
            isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsEmail);
            if (!isPassed)
            {
                result.Email = string.Empty;
                result.EmailConfirmed = false;
            }

            //
            // Handle PhoneNumber Info ...
            isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsPhoneNumber);
            if (!isPassed)
            {
                source.PhoneNumber = string.Empty;
                source.PhoneNumberConfirmed = false;
            }

            //
            // Handle Last Login ...
            isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsLastLogin);
            if (!isPassed)
            {
                result.LastLogin = null;
            }

            //
            // Handle Date Of Birth ...
            isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsDateOfBirth);
            if (!isPassed)
            {
                result.DateOfBirth = null;
            }

            //
            // Handle Creation Date ...
            isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsCreationDate);
            if (!isPassed)
            {
                result.CreationDate = null;
            }

            //
            // Handle Roles ...
            isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsRoles);
            if (!isPassed)
            {
                result.Roles = new List<string>();
            }

            //
            return result;
        }

        /// <summary>
        /// Check Specified User Has Access to Provided Roles ...
        /// </summary>
        /// <param name="source"></param>
        /// <param name="roles"></param>
        /// <returns></returns>
        public static bool HasAccess(
            this XUserClaimsInfoDto source,
            string[] roles
        )
        {
            //
            var result = 
                !source.IsNullOrDefault() &&
                source.Roles
                    .Any(r => roles
                        .Any(ar => r.ToNormalString()
                            .Contains(ar.ToNormalString())));

            //
            return result;
        }

        /// <summary>
        /// Check Specified User Contains Specified UserSelectByParam or not ...
        /// </summary>
        /// <param name="source"></param>
        /// <param name="userSelectByParam"></param>
        /// <returns></returns>
        public static bool ContainsUserSelectByParam(
            this XUser source,
            string userSelectByParam
        )
        {
            //
            var result =
                !source.IsNull() &&
                !userSelectByParam.IsNullOrEmpty() &&
                (source.Id == userSelectByParam ||
                source.Email.ToNormalString() == userSelectByParam.ToNormalString() ||
                source.UserName.ToNormalString() == userSelectByParam.ToNormalString() ||
                source.PhoneNumber.ToNormalString() == userSelectByParam.ToNormalString());

            //
            return result;
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\XModelExtensions.cs

using System;
using System.Collections.Generic;
using xCommons.Extensions;
using xIdentityModels.Descriptors;
using xIdentityModels.Models;
using xIdentityModels.Navigations;

namespace xIdentityModels.Extensions {
    public static class XModelExtensions {
        /// <summary>
        /// /// Convert XIdentityUserDescriptor instance to XUser
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XUser ToXUser (this XIdentityUserDescriptor source) {
            return new XUser {
                Id = source.Id,
                    FirstName = source.FirstName,
                    LastName = source.LastName,
                    UserName = source.UserName,
                    Email = source.Email,
                    EmailConfirmed = source.EmailConfirmed,
                    PhoneNumber = source.PhoneNumber,
                    PhoneNumberConfirmed = source.PhoneNumberConfirmed,
                    IsEnable = true,
                    IsBanned = false,
                    CreationDate = DateTime.UtcNow,
                    DateOfBirth = DateTime.Parse (source.DateOfBirth)
            };
        }

        /// <summary>
        /// Check a User is Same as Descriptor User
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <returns></returns>
        public static bool IsSameAs (this XUser source, XIdentityUserDescriptor dest) {
            //
            if (source.IsNull () ||
                dest.IsNull ()) {
                return false;
            }

            //
            var isSame = source.IsSameContent (dest, propertyWhiteList : new [] {
                    nameof (XIdentityUserDescriptor.FirstName),
                    nameof (XIdentityUserDescriptor.LastName),
                    nameof (XIdentityUserDescriptor.UserName),
                    nameof (XIdentityUserDescriptor.Email),
                    nameof (XIdentityUserDescriptor.EmailConfirmed),
                    nameof (XIdentityUserDescriptor.PhoneNumber),
                    nameof (XIdentityUserDescriptor.PhoneNumberConfirmed),
                    nameof (XIdentityUserDescriptor.IsEnable),
                    nameof (XIdentityUserDescriptor.IsBanned),
                    nameof (XIdentityUserDescriptor.DateOfBirth)
                },
                propertyValueCheckers : new [] {
                    new KeyValuePair<string, Func<XUser, XIdentityUserDescriptor, bool>> (
                        nameof (XIdentityUserDescriptor.DateOfBirth),
                        (user, descriptorUser) => {
                            //
                            var descriptorUserDateOfBirth = DateTime.Parse (descriptorUser.DateOfBirth);
                            return DateTime.Equals (user.DateOfBirth, descriptorUserDateOfBirth);
                        })
                }
            );

            //
            return isSame;
        }

        /// <summary>
        /// Check to XDevice instance to be same or not
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <returns></returns>
        public static bool IsSameAs (this XDevice source, XDevice dest) {
            //
            if (source.IsNull () ||
                dest.IsNull ()) {
                return false;
            }

            //
            var isSame = source.Os.ToNormalString () == dest.Os.ToNormalString () &&
                source.OsVersion.ToNormalString () == dest.OsVersion.ToNormalString () &&
                source.Browser.ToNormalString () == dest.Browser.ToNormalString () &&
                source.UserAgent.ToNormalString () == dest.UserAgent.ToNormalString () &&
                source.DeviceType == dest.DeviceType;

            //
            return isSame;
        }

        /// <summary>
        /// convert UserClaimsInfo to TokenResponse ...
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XTokenResponse ToXTokenResponse (this XUserClaimsInfoDto source) {
            //
            if (source.IsNull () ||
                (source.AccessToken.IsNullOrEmpty () && source.RefreshToken.IsNullOrEmpty ())) {
                return null;
            }

            //
            var result = new XTokenResponse {
                AccessToken = source.AccessToken,
                RefreshToken = source.RefreshToken,
                ExpiresAt = source.ExpiresAt
            };

            //
            return result;
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Extensions\XTokenExtensions.cs

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.IdentityModel.Tokens;
using xCommons.Constants;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Models;

namespace xIdentityModels.Extensions {
    public static class XTokenExtensions {
        //
        #region Identity Token Extensions ...
        /// <summary>
        /// Convert a SecurityToken to it's Token String
        /// </summary>
        /// <param name="source"></param>
        /// <param name="tokenHandler"></param>
        /// <returns></returns>
        public static string ToTokenString (
            this SecurityToken source,
            JwtSecurityTokenHandler tokenHandler
        ) {
            return tokenHandler.WriteToken (source);
        }

        /// <summary>
        /// Validate a Token
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tokenHandler"></param>
        /// <param name="tokenValidationParams"></param>
        /// <returns></returns>
        public static bool ValidateToken (
            this string token,
            JwtSecurityTokenHandler tokenHandler,
            TokenValidationParameters tokenValidationParams) {
            //
            if (token.IsNullOrEmpty ()) {
                return false;
            }

            //
            SecurityToken tokenObj = null;
            try {
                tokenHandler.ValidateToken (token, tokenValidationParams, out tokenObj);
            } catch {
                return false;
            }

            //
            return tokenObj != null;
        }

        /// <summary>
        /// Convert a token string to Security Token
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tokenHandler"></param>
        /// <param name="tokenValidationParams"></param>
        /// <returns></returns>
        public static SecurityToken ToSecurityToken (
            this string token,
            JwtSecurityTokenHandler tokenHandler,
            TokenValidationParameters tokenValidationParams) {
            //
            if (token.IsNullOrEmpty () ||
                !token.ValidateToken (tokenHandler, tokenValidationParams)) {
                //
                return null;
            }

            //
            // convert token from String to JWTSecurity Token ...
            try {
                return tokenHandler.ReadToken (token);
            } catch {
                return null;
            }
        }

        /// <summary>
        /// Parse Action Token and return Corresponding RegistrationRequestDto
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tokenHandler"></param>
        /// <param name="tokenValidationParams"></param>
        /// <returns></returns>
        public static XActionRequestToken ParseActionRequestToken (
            this string token,
            JwtSecurityTokenHandler tokenHandler,
            TokenValidationParameters tokenValidationParams) {
            //
            if (token.IsNullOrEmpty () ||
                !token.ValidateToken (tokenHandler, tokenValidationParams)) {
                //
                return null;
            }

            //
            // convert token from String to JWTSecurity Token ...
            JwtSecurityToken tokenObj = null;
            try {
                tokenObj = tokenHandler.ReadToken (token) as JwtSecurityToken;
            } catch {
                return null;
            }

            //
            if (tokenObj == null) {
                return null;
            }

            //
            // Extract Registered Payload Claims ...
            var mCurrentStepClaim = tokenObj.Claims
                .FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Action));
            var mContextClaim = tokenObj.Claims
                .FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Context));
            var mTokenClaim = tokenObj.Claims
                .FirstOrDefault (c => c.Type == nameof (XActionRequestToken.Token));

            //
            // Check All Claims to be NotNull ...
            if (mCurrentStepClaim == null ||
                mContextClaim == null ||
                mTokenClaim == null) {
                return null;
            }

            //
            // Reading all Claims Values ...
            var mCurrentStepStr = mCurrentStepClaim.Value;
            var mCurrentStep = 0;
            try {
                int.TryParse (mCurrentStepStr, out mCurrentStep);
            } catch { }

            //
            var mContext = mContextClaim.Value.IsNullOrEmpty () ?
                null : mContextClaim.Value.FromJSON<XActionRequestContext> ();
            var mToken = mTokenClaim.Value;

            //
            // Create Instance of UserInvite ...
            var result = new XActionRequestToken {
                Action = (XAction) mCurrentStep,
                Context = mContext,
                Token = mToken
            };

            //
            return result;
        }

        /// <summary>
        /// Check to ActionRequestContext object is same or not 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dest"></param>
        /// <returns></returns>
        public static bool IsSameAs (
            this XActionRequestContext source,
            XActionRequestContext dest
        ) {
            //
            if (source == null ||
                dest == null) {
                return false;
            }

            //
            var result = source.ToJSON () == dest.ToJSON ();

            //
            return result;
        }

        /// <summary>
        /// Convert a RegistrationRequestDto object to it's jwt token Claims
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>        
        public static Claim[] ToJwtClaims (this XActionRequestToken source) {
            //
            // Generate Required Fields ...
            var action = source.Action;
            var context = source.Context;
            var token = source.Token;

            //
            // Generate Claims Array ...
            var claims = new Claim[] {
                new Claim (nameof (XActionRequestToken.Action), ((int) action).ToString (), ClaimValueTypes.Integer),
                new Claim (nameof (XActionRequestToken.Context), context == null ? "" : context.ToJSON (), ClaimValueTypes.String),
                new Claim (nameof (XActionRequestToken.Token), token.IsNullOrEmpty () ? "" : token, ClaimValueTypes.String)
            };

            //
            // Return Result ...
            return claims;
        }

        /// <summary>
        /// Generate a SecurityToken based on RegistrationRequestDto object
        /// </summary>
        /// <param name="source"></param>
        /// <param name="tokenHandler"></param>
        /// <param name="tokenDescriptor"></param>
        /// <returns></returns>
        public static SecurityToken ToJwtToken (
            this XActionRequestToken source,
            JwtSecurityTokenHandler tokenHandler,
            SecurityTokenDescriptor tokenDescriptor) {
            //
            // Getting Claims ...
            var claims = source.ToJwtClaims ();
            tokenDescriptor.Subject = new ClaimsIdentity (claims);

            //
            // Generate Token Object ...
            var tokenObject = tokenHandler.CreateToken (tokenDescriptor);

            //
            // Return Result ...
            return tokenObject;
        }
        #endregion

        //
        #region IdentityServer Token Extensions ...
        /// <summary>
        /// Retrieve Tokens From Headers
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XTokenResponse RetrieveTokens (this HttpRequest source) {
            //
            var accessToken = source.Headers[XAuthorization.Header].ToString ();
            var refreshToken = source.Headers[XAuthorization.RefreshToken].ToString ();

            //
            var expiresAtStr = source.Headers[XAuthorization.ExpiresAt].ToString ();
            long expiresAt = expiresAtStr.ConvertTo<long> ();

            //
            if (accessToken
                .ToNormalString ()
                .Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
                accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
            }

            //
            return new XTokenResponse {
                AccessToken = accessToken,
                    RefreshToken = refreshToken,
                    ExpiresAt = expiresAt
            };
        }

        /// <summary>
        /// Retrieve Tokens From HttpContext
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static async Task<XTokenResponse> RetrieveTokens (this HttpContext source) {
            //
            var accessToken = await source.GetTokenAsync (XAuthorization.AccessToken);
            if (accessToken
                .ToNormalString ()
                .Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
                accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
            }

            var refreshToken = await source.GetTokenAsync (XAuthorization.RefreshToken);
            var expiresAtStr = await source.GetTokenAsync (XAuthorization.ExpiresAt);
            long expiresAt = expiresAtStr.ConvertTo<long> ();

            //
            var headerRequestTokens = source.Request.RetrieveTokens ();

            //
            var result = new XTokenResponse {
                AccessToken = accessToken ?? headerRequestTokens.AccessToken,
                RefreshToken = refreshToken ?? headerRequestTokens.RefreshToken,
                ExpiresAt = expiresAt != 0 ? expiresAt : headerRequestTokens.ExpiresAt
            };

            //
            return result;
        }

        /// <summary>
        /// Retrieve Tokens From ActionExecutingContext
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static async Task<XTokenResponse> RetrieveTokens (this ActionExecutingContext source) {
            //
            var result = await source.HttpContext.RetrieveTokens ();
            return result;
        }

        /// <summary>
        /// Retrieve Tokens From XUserInfo instance
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XTokenResponse RetrieveTokens (this XUserClaimsInfoDto source) {
            //
            var result = new XTokenResponse {
                AccessToken = source.AccessToken,
                RefreshToken = source.RefreshToken,
                ExpiresAt = source.ExpiresAt
            };

            //
            return result;
        }

        /// <summary>
        /// Retrieve Tokens From IHeader Dictionary 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XTokenResponse RetrieveTokens (this IHeaderDictionary source) {
            //
            var accessToken = source[XAuthorization.Header].ToString () ?? "";
            if (accessToken
                .ToNormalString ()
                .Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
                accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
            }

            //
            var refreshToken = source[XAuthorization.RefreshToken].ToString () ?? "";

            //
            var expiresAtStr = source[XAuthorization.ExpiresAt].ToString () ?? "";
            var expiresAt = expiresAtStr.ConvertTo<long> ();

            //
            var result = new XTokenResponse {
                AccessToken = accessToken,
                RefreshToken = refreshToken,
                ExpiresAt = expiresAt
            };

            //
            return result;
        }

        /// <summary>
        /// Generate XTokenResponse instance based on TokenResponse
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XLoginResponse CreateXLoginResponse (this TokenResponse source) {
            //
            if (source.IsNull () ||
                source.IsError) {
                XException.InvalidToken.Throw ();
            }

            //
            var expiresAt = new DateTimeOffset (DateTime.UtcNow)
                .ToUnixTimeSeconds () +
                source.ExpiresIn;

            //
            var result = new XLoginResponse {
                AccessToken = source.AccessToken,
                RefreshToken = source.RefreshToken,
                ExpiresAt = expiresAt
            };

            //
            return result;
        }

        /// <summary>
        /// Generate XTokenResponse instance based on TokenResponse
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XTokenResponse CreateXTokenResponse (this TokenResponse source) {
            //
            if (source.IsNull () ||
                source.IsError) {
                XException.InvalidToken.Throw ();
            }

            //
            var expiresAt = new DateTimeOffset (DateTime.UtcNow)
                .ToUnixTimeSeconds () +
                source.ExpiresIn;

            //
            var result = new XTokenResponse {
                AccessToken = source.AccessToken,
                RefreshToken = source.RefreshToken,
                ExpiresAt = expiresAt
            };

            //
            return result;
        }

        /// <summary>
        /// Convert XLoginResponse to XTokenResponse
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XTokenResponse ToXTokenResponse (this XLoginResponse source) {
            //
            if (source.IsNull ()) {
                return null;
            }

            //
            return new XTokenResponse {
                AccessToken = source.AccessToken,
                    RefreshToken = source.RefreshToken,
                    ExpiresAt = source.ExpiresAt
            };
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific IHeaderDictionary instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this IHeaderDictionary source,
            XLoginResponse model,
            string secret = null
        ) {
            //
            source.Remove (XAuthorization.Header);
            source.Remove (XAuthorization.RefreshToken);
            source.Remove (XAuthorization.ExpiresAt);
            source.Remove (XAuthorization.RevisionChecksum);

            //
            source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
            source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
            source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");

            //
            if (!secret.IsNullOrEmpty ()) {
                var revisionChecksum = model.GetRevisionChecksum (secret);
                source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
            }
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific IHeaderDictionary instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this IHeaderDictionary source,
            XTokenResponse model,
            string secret = null
        ) {
            //
            source.Remove (XAuthorization.Header);
            source.Remove (XAuthorization.RefreshToken);
            source.Remove (XAuthorization.ExpiresAt);
            source.Remove (XAuthorization.RevisionChecksum);

            //
            source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
            source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
            source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");

            //
            if (!secret.IsNullOrEmpty ()) {
                var revisionChecksum = model.GetRevisionChecksum (secret);
                source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
            }
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific IHeaderDictionary instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpRequestHeaders source,
            XLoginResponse model
        ) {
            //
            source.Remove (XAuthorization.Header);
            source.Remove (XAuthorization.RefreshToken);
            source.Remove (XAuthorization.ExpiresAt);
            source.Remove (XAuthorization.RevisionChecksum);

            //
            source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
            source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
            source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific IHeaderDictionary instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpRequestHeaders source,
            XTokenResponse model
        ) {
            //
            source.Remove (XAuthorization.Header);
            source.Remove (XAuthorization.RefreshToken);
            source.Remove (XAuthorization.ExpiresAt);
            source.Remove (XAuthorization.RevisionChecksum);

            //
            source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
            source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
            source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific HttpRequest instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpRequest source,
            XLoginResponse model
        ) {
            source.Headers.SetXAuthenticationTokens (model);
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific HttpRequest instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpRequest source,
            XTokenResponse model
        ) {
            source.Headers.SetXAuthenticationTokens (model);
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific HttpRequest instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpRequestMessage source,
            XLoginResponse model
        ) {
            source.Headers.SetXAuthenticationTokens (model);
        }

        /// <summary>
        /// Add Authorization Tokens in Headers of
        /// Specific HttpRequest instance
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpRequestMessage source,
            XTokenResponse model
        ) {
            source.Headers.SetXAuthenticationTokens (model);
        }

        /// <summary>
        /// Add ReNewed Authorization Tokens in Headers of 
        /// Specific Response.
        /// Later in HttpInterceptors we can Look for AccessToken-ReNewed
        /// header Value and Renew User Tokens based on it
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpResponse source,
            XLoginResponse model,
            string secret
        ) {
            source.Headers.SetXAuthenticationTokens (model, secret);
        }

        /// <summary>
        /// Add ReNewed Authorization Tokens in Headers of 
        /// Specific Response.
        /// Later in HttpInterceptors we can Look for AccessToken-ReNewed
        /// header Value and Renew User Tokens based on it
        /// </summary>
        /// <param name="source"></param>
        /// <param name="model"></param>
        public static void SetXAuthenticationTokens (
            this HttpResponse source,
            XTokenResponse model,
            string secret
        ) {
            source.Headers.SetXAuthenticationTokens (model, secret);
        }

        /// <summary>
        /// Determines a Token Can Refrsh or not
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsRefreshable (this XLoginResponse source) {
            //
            var containsTokenData = !source.IsNull () &&
                !source.AccessToken.IsNullOrEmpty () &&
                !source.RefreshToken.IsNullOrEmpty ();
            if (!containsTokenData) {
                return false;
            }

            //
            var current = new DateTimeOffset (DateTime.UtcNow)
                .ToUnixTimeSeconds ();

            //
            // var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
            var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;

            //
            return result;
        }

        /// <summary>
        /// Determines a Token Can Refrsh or not
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsRefreshable (this XTokenResponse source) {
            //
            var containsTokenData = !source.IsNull () &&
                !source.AccessToken.IsNullOrEmpty () &&
                !source.RefreshToken.IsNullOrEmpty ();
            if (!containsTokenData) {
                return false;
            }

            //
            var current = new DateTimeOffset (DateTime.UtcNow)
                .ToUnixTimeSeconds ();

            //
            // var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
            var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;

            //
            return result;
        }

        /// <summary>
        /// Generate a Revision Checksum for new Tokens
        /// </summary>
        /// <param name="source"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public static string GetRevisionChecksum (
            this XLoginResponse source,
            string secret
        ) {
            return (source.AccessToken +
                    secret +
                    source.RefreshToken +
                    secret +
                    source.ExpiresAt.ToString ()
                )
                .ToMd5String ();
        }

        /// <summary>
        /// Generate a Revision Checksum for new Tokens
        /// </summary>
        /// <param name="source"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public static string GetRevisionChecksum (
            this XTokenResponse source,
            string secret
        ) {
            return (source.AccessToken +
                    secret +
                    source.RefreshToken +
                    secret +
                    source.ExpiresAt.ToString ()
                )
                .ToMd5String ();
        }

        /// <summary>
        /// Check an XLoginResponse instance is Valid with it's revision
        /// </summary>
        /// <param name="source"></param>
        /// <param name="checksum"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public static bool ValidateRevisionChecksum (
            this XLoginResponse source,
            string checksum,
            string secret
        ) {
            //
            var xChecksum = source.GetRevisionChecksum (secret);
            return checksum == xChecksum;
        }

        /// <summary>
        /// Check an XTokenResponse instance is Valid with it's revision
        /// </summary>
        /// <param name="source"></param>
        /// <param name="checksum"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public static bool ValidateRevisionChecksum (
            this XTokenResponse source,
            string checksum,
            string secret
        ) {
            //
            var xChecksum = source.GetRevisionChecksum (secret);
            return checksum == xChecksum;
        }
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Interfaces\IXUserRoleHelper.cs

using xIdentityModels.Models;

namespace xIdentityModels.Interfaces {
    public interface IXUserRoleHelper {
        bool canReadCriticalData (XUserClaimsInfoDto userInfo);
        bool canDoDangerousAction (XUserClaimsInfoDto userInfo);
        bool isInRole (XUserClaimsInfoDto userInfo, string role);
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionRequest.cs

using System;
using Microsoft.AspNetCore.Http;
using xIdentityModels.Navigations;

namespace xIdentityModels.Models {
    /// <summary>
    /// represent a system wide actions
    /// </summary>
    public class XActionRequest {
        /// <summary>
        /// Client Device Locale
        /// </summary>
        /// <value>user's client device local such as en-US</value>
        public string Lang { get; set; } = null;
        /// <summary>
        /// Requested Action Token
        /// </summary>
        /// <value>a hashed content</value>
        public string ActionToken { get; set; } = null;
        /// <summary>
        /// user's device
        /// </summary>
        /// <value>an instance of <see>XDevice</see> which represent user's device</value>
        public XDevice Device { get; set; } = null;
        /// <summary>
        /// FirstName 
        /// </summary>
        /// <value>users FirstName</value>
        public string FirstName { get; set; } = null;
        /// <summary>
        /// LastName 
        /// </summary>
        /// <value>user's LastName</value>
        public string LastName { get; set; } = null;
        /// <summary>
        /// an Optional Value which represetns User's DateOfBirth
        /// </summary>
        /// <value>user's DateOfBirth</value>
        public DateTime? DateOfBirth { get; set; } = DateTime.MinValue;
        /// <summary>
        /// User's Id
        /// </summary>
        /// <value>a GUID string which represent user's Id</value>
        public string UserId { get; set; } = null;
        /// <summary>
        /// UserName
        /// </summary>
        /// <value>user's UserName</value>
        public string UserName { get; set; } = null;
        /// <summary>
        /// Email
        /// </summary>
        /// <value>user's Email address</value>
        public string Email { get; set; } = null;
        /// <summary>
        /// MobileNumber / PhoneNumber
        /// </summary>
        /// <value>user's PhoneNumber</value>
        public string MobileNumber { get; set; } = null;
        /// <summary>
        /// Password
        /// </summary>
        /// <value>user's Password</value>
        public string Password { get; set; } = null;
        /// <summary>
        /// NewPassword
        /// </summary>
        /// <value>a passwor string which used to Change/Reset password</value>
        public string NewPassword { get; set; } = null;
        /// <summary>
        /// EmailVerificationCode
        /// </summary>
        /// <value>a Verification Code which assign to user's for confirm it's Email Address</value>
        public string EmailVerificationCode { get; set; } = null;
        /// <summary>
        /// MobileVerificationCode
        /// </summary>
        /// <value>a Verification Code which assign to user's for confirm it's Phone Number</value>
        public string MobileVerificationCode { get; set; } = null;
        /// <summary>
        /// Thumbnail
        /// </summary>
        /// <value>an instance of <see>IFormFile</see> which is used as user's avatar</value>
        public IFormFile Thumbnail { get; set; }
        /// <summary>
        /// ReturnUrl
        /// </summary>
        /// <value>
        /// a url string which used in many used cases for providing a way to lead users to right places.
        /// </value>
        public string ReturnUrl { get; set; } = null;
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionRequestContext.cs

using System;
using Microsoft.AspNetCore.Http;
using xIdentityModels.Navigations;

namespace xIdentityModels.Models {
    public class XActionRequestContext {
        //
        public string Lang { get; set; }

        //
        public string UserId { get; set; }
        public string UserName { get; set; }

        //
        public string MobileNumber { get; set; }
        public string MobileVerificationCode { get; set; }
        public bool MobileVerified { get; set; }

        //
        public string Email { get; set; }
        public string EmailVerificationCode { get; set; }
        public bool EmailVerified { get; set; }

        //
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }

        //
        public XDevice Device { get; set; }
        public IFormFile Thubmnail { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionRequestToken.cs

using xCommons.Extensions;
using xIdentityModels.Constants;

namespace xIdentityModels.Models {
    public class XActionRequestToken {
        public XAction Action { get; set; }
        public XActionRequestContext Context { get; set; }
        public string Token { get; set; }

        public void Prepare (string secret) {
            Token = (Action.ToString () +
                secret +
                Context.ToJSON ()).ToMd5String ();
        }

        public bool Validate (string secret) {
            return (Action.ToString () +
                secret +
                Context.ToJSON ()).ToMd5String () == Token;
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XActionResponse.cs

using System;
using Newtonsoft.Json;

namespace xIdentityModels.Models {
    /// <summary>
    /// represent a system wide action result
    /// </summary>
    public class XActionResponse {
        /// <summary>
        /// ActionToken
        /// </summary>
        /// <value>a hashed string which carry required info for doing system actions.</value>
        [JsonProperty (
            "token",
            Required = Required.Default,
            NullValueHandling = NullValueHandling.Ignore)]
        public string Token { get; set; }

        /// <summary>
        /// ActionToken Lifetime
        /// </summary>
        /// <value>an instance of <see>DateTime</see> which represent token expiration time</value>
        [JsonProperty (
            "expiration",
            Required = Required.DisallowNull,
            NullValueHandling = NullValueHandling.Ignore)]
        public DateTime Expiration { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XBannedDevice.cs

using System;
using System.ComponentModel.DataAnnotations.Schema;
using xCommons.Extensions;
using xIdentityModels.Navigations;
using xModels.Base;

namespace xIdentityModels.Models {
    public class XBannedDevice : XBaseIntIDEntity {
        public DateTime BannedOn { get; set; }

        public string DeviceStr { get; set; }

        [NotMapped]
        public XDevice Device {
            get {
                return DeviceStr.FromJSON<XDevice> ();
            }
            set {
                DeviceStr = value.ToJSON ();
            }
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XLoginRequest.cs

using System.ComponentModel.DataAnnotations;
using xIdentityModels.Navigations;

namespace xIdentityModels.Models {
    /// <summary>
    /// Represent Requirements for Authenticationg a User
    /// </summary>
    public class XLoginRequest {
        /// <summary>
        /// how select an specific User
        /// </summary>
        /// <value>an string value which represent how system select user such as: UserName, Email Address or MobileNumber</value>
        [Required]
        public string UserSelectBy { get; set; }

        /// <summary>
        /// user's password
        /// </summary>
        /// <value>an string which represent user's pasword</value>
        [Required]
        public string Password { get; set; }

        /// <summary>
        /// user's device
        /// </summary>
        /// <value>an instance of <see>XDevice</see> which represent user's device</value>
        public XDevice Device { get; set; }

        /// <summary>
        /// user's language
        /// </summary>
        /// <value>an string which represent user's language and locale, such as: en-US</value>
        public string Language { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XLoginResponse.cs

using xIdentityModels.Dtos;

namespace xIdentityModels.Models {
    public class XLoginResponse : XTokenResponse {
        public XUserProfileDto Profile { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XProfileUpdateRequest.cs

using System;
using System.Collections.Generic;
using xIdentityModels.Constants;

namespace xIdentityModels.Models {
    public class XProfileUpdateRequest {
        public string Email { get; set; }
        public bool? EmailConfirmed { get; set; }
        public string PhoneNumber { get; set; }
        public bool? PhoneNumberConfirmed { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Avatar { get; set; }
        public DateTime? DateOfBirth { get; set; }
        public DateTime? CreationDate { get; set; }
        public DateTime? LastLogin { get; set; }
        public XGender? Gender { get; set; }
        public ICollection<string> Roles { get; set; } = new HashSet<string> ();
        public bool? IsEnable { get; set; }
        public bool? IsBanned { get; set; }
        public string Bio { get; set; }
        public string CoverImage { get; set; }
        public bool OpenToSearch { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XToken.cs

using System.ComponentModel.DataAnnotations.Schema;
using xCommons.Extensions;
using xIdentityModels.Constants;
using xIdentityModels.Navigations;
using xModels.Base;

namespace xIdentityModels.Models {
    public class XToken : XBaseIntIDEntity {
        public string Token { get; set; }
        public string Hash { get; set; }
        public string UserSelectByParam { get; set; }
        public string DeviceStr { get; set; }
        public XAction Type { get; set; }

        [NotMapped]
        public XDevice Device {
            get {
                return DeviceStr.FromJSON<XDevice> ();
            }

            set {
                DeviceStr = value.ToJSON ();
            }
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XTokenResponse.cs

using System.ComponentModel.DataAnnotations;

namespace xIdentityModels.Models {
    public class XTokenResponse {
        [Required]
        public string AccessToken { get; set; }
        public string RefreshToken { get; set; }
        public long ExpiresAt { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XUserClaimsInfoDto.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using xCommons.Constants;
using xCommons.Extensions;
using xCommons.Helpers;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xModels.Base;

namespace xIdentityModels.Models
{
    public class XUserClaimsInfoDto : XBaseDto
    {
        //
        #region Properties ...
        public string AccessToken { get; }
        public string RefreshToken { get; }
        public long ExpiresAt { get; }
        public string UserId { get; }
        public string UserName { get; }
        public string FirstName { get; }
        public string LastName { get; }
        public string Picture { get; }
        public string Email { get; }
        public string PhoneNumber { get; }
        public XGender Gender { get; }
        public bool IsBanned { get; }
        public bool IsEnabled { get; }
        public bool EmailConfirmed { get; }
        public bool PhoneNumberConfirmed { get; }
        public string Bio { get; set; }
        public string CoverImage { get; set; }
        public bool OpenToSearch { get; set; }
        public long? ExpiredOn { get; }
        public long? AuthenticatedOn { get; }
        public DateTime? BrithDate { get; }
        public IEnumerable<string> Issuers { get; } = new HashSet<string>();
        public IEnumerable<string> Audiences { get; } = new HashSet<string>();
        public IEnumerable<string> ClientIds { get; } = new HashSet<string>();
        public IEnumerable<string> Scopes { get; } = new HashSet<string>();
        public IEnumerable<string> Roles { get; } = new HashSet<string>();
        #endregion

        //
        public XUserClaimsInfoDto() { }

        public XUserClaimsInfoDto(
            string accessToken,
            string refreshToken,
            long expiresAt,
            IEnumerable<Claim> claims
        )
        {
            //
            // refreshToken.IsNullOrEmpty ()
            if (claims.IsNull() ||
                accessToken.IsNullOrEmpty())
            {
                XException.InvalidArgs.Throw();
            }

            //
            // Attach XLogin Properties ...
            AccessToken = accessToken;
            RefreshToken = refreshToken;
            ExpiresAt = expiresAt;

            //
            if (!claims.IsNull())
            {
                //
                UserId = claims.FirstOrDefault(c => c.Type == XCustomClaims.UserId)?.Value ?? "";
                UserName = claims.FirstOrDefault(c => c.Type == XCustomClaims.UserName)?.Value ?? "";
                FirstName = claims.FirstOrDefault(c => c.Type == XCustomClaims.FirstName)?.Value ?? "";
                LastName = claims.FirstOrDefault(c => c.Type == XCustomClaims.LastName)?.Value ?? "";
                Picture = claims.FirstOrDefault(c => c.Type == XCustomClaims.Picture)?.Value ?? "";
                Email = claims.FirstOrDefault(c => c.Type == XCustomClaims.Email)?.Value ?? null;
                PhoneNumber = claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumber)?.Value ?? null;

                //
                Bio = claims.FirstOrDefault(c => c.Type == XCustomClaims.Bio)?.Value ?? null;
                CoverImage = claims.FirstOrDefault(c => c.Type == XCustomClaims.CoverImage)?.Value ?? null;

                //
                var openToSearchStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.OpenToSearch)?.Value ?? null;
                if (openToSearchStr.IsNullOrEmpty())
                {
                    OpenToSearch = false;
                }
                else
                {
                    //
                    var openToSearch = false;
                    bool.TryParse(openToSearchStr, out openToSearch);

                    //
                    OpenToSearch = openToSearch;
                }

                //
                // Handle Gender ...
                var genders = ObjectHelper.ToEnumerableKeys<XGender>();
                var genderStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.Gender).Value ?? null;
                if (genderStr.IsNullOrEmpty())
                {
                    Gender = XGender.Male;
                }
                else
                {
                    Gender = genderStr.GetValue<XGender>();
                }

                //
                // Handle IsBanned ...
                var isBannedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.IsBanned).Value ?? null;
                if (isBannedStr.IsNullOrEmpty())
                {
                    IsBanned = false;
                }
                else
                {
                    //
                    var isBanned = false;
                    Boolean.TryParse(isBannedStr, out isBanned);

                    //
                    IsBanned = isBanned;
                }

                //
                // Handle IsEnabled ...
                var isEnabledStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.IsEnabled).Value ?? null;
                if (isEnabledStr.IsNullOrEmpty())
                {
                    IsEnabled = false;
                }
                else
                {
                    //
                    var isEnabled = false;
                    Boolean.TryParse(isEnabledStr, out isEnabled);

                    //
                    IsEnabled = isEnabled;
                }

                //
                // Handle Email Confirmed ...
                var emailConfirmedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.EmailVerified).Value ?? null;
                if (emailConfirmedStr.IsNullOrEmpty())
                {
                    EmailConfirmed = false;
                }
                else
                {
                    //
                    var emailConfirmed = false;
                    Boolean.TryParse(emailConfirmedStr, out emailConfirmed);

                    //
                    EmailConfirmed = emailConfirmed;
                }

                //
                // Handle PhoneNumber Confirmed ...
                var phoneNumberConfirmedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumberVerified).Value ?? null;
                if (phoneNumberConfirmedStr.IsNullOrEmpty())
                {
                    PhoneNumberConfirmed = false;
                }
                else
                {
                    //
                    var phoneNumberConfirmed = false;
                    Boolean.TryParse(phoneNumberConfirmedStr, out phoneNumberConfirmed);

                    //
                    PhoneNumberConfirmed = phoneNumberConfirmed;
                }

                //
                // Handle ExpiredOn ...
                var expiredOnStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.ExpiredOn).Value ?? null;
                if (expiredOnStr.IsNullOrEmpty())
                {
                    ExpiredOn = null;
                }
                else
                {
                    //
                    long expiredOn = 0;
                    long.TryParse(expiredOnStr, out expiredOn);

                    //
                    ExpiredOn = expiredOn;
                }

                //
                // Handle AuthenticatedOn ...
                var authenticatedOnStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.AuthenticatedOn).Value ?? null;
                if (authenticatedOnStr.IsNullOrEmpty())
                {
                    AuthenticatedOn = null;
                }
                else
                {
                    //
                    long authenticatedOn = 0;
                    long.TryParse(authenticatedOnStr, out authenticatedOn);

                    //
                    AuthenticatedOn = authenticatedOn;
                }

                //
                // Handle BrithDate ...
                var brithDateStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.BrithDate)?.Value ?? "";
                if (brithDateStr.IsNullOrEmpty())
                {
                    // BrithDate = null;
                }
                else
                {
                    //
                    DateTime bDate;
                    DateTime.TryParse(brithDateStr, out bDate);

                    //
                    BrithDate = bDate;
                }

                //
                // Collections ...
                Issuers = claims.Where(c => c.Type == XCustomClaims.Issuer)?
                    .Select(c => c.Value) ?? new HashSet<string>();
                Audiences = claims.Where(c => c.Type == XCustomClaims.Audience)?
                    .Select(c => c.Value) ?? new HashSet<string>();
                ClientIds = claims.Where(c => c.Type == XCustomClaims.ClientId)?
                    .Select(c => c.Value) ?? new HashSet<string>();
                Scopes = claims.Where(c => c.Type == XCustomClaims.Scope)?
                    .Select(c => c.Value) ?? new HashSet<string>();
                Roles = claims.Where(c => c.Type == XCustomClaims.Role)?
                    .Select(c => c.Value) ?? new HashSet<string>();
            }
        }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Models\XVerificationRequest.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using xCommons.Extensions;
using xIdentityModels.Navigations;
using xModels.Base;

namespace xIdentityModels.Models {
    public class XVerificationRequest : XBaseIntIDEntity {

        [Required]
        public string VerificationCode { get; set; }

        public int NumberOfTries { get; set; }
        public DateTime LastTryOn { get; set; }

        [NotMapped]
        public XActionRequestToken Request {
            get {
                return RequestStr.FromJSON<XActionRequestToken> ();
            }
            set {
                RequestStr = value.ToJSON ();
            }
        }

        public string RequestStr { get; set; }

        [NotMapped]
        public XDevice Device {
            get {
                return DeviceStr.FromJSON<XDevice> ();
            }
            set {
                DeviceStr = value.ToJSON ();
            }
        }

        public string DeviceStr { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XDevice.cs

using System.ComponentModel.DataAnnotations.Schema;
using xCommons.Constants;
using xModels.Base;

namespace xIdentityModels.Navigations {
    /// <summary>
    /// Represent a Client Device which used by User
    /// </summary>
    public class XDevice : XBaseIntIDEntity {
        /// <summary>
        /// Operating System
        /// </summary>
        /// <value>device operating system identifier</value>
        public string Os { get; set; }
        /// <summary>
        /// Operating System Version
        /// </summary>
        /// <value>which version of operatin system is in use</value>
        public string OsVersion { get; set; }
        /// <summary>
        /// Device Browser
        /// </summary>
        /// <value>the Browser identifier</value>
        public string Browser { get; set; }
        /// <summary>
        /// Browser Engine Agent
        /// </summary>
        /// <value>browser engine Agent</value>
        public string UserAgent { get; set; }
        /// <summary>
        /// Type of client Device
        /// </summary>
        /// <value>represent device type <see>XDeviceType</see></value>
        public XDeviceType DeviceType { get; set; }

        //
        #region User ...
        /// <summary>
        /// UserId
        /// </summary>
        /// <value>Represent this Devie belong to which User Identifier</value>
        public string UserId { get; set; }
        /// <summary>
        /// User
        /// </summary>
        /// <value>Represent Device User <see>XUser</see></value>
        [ForeignKey (nameof (UserId))]
        public virtual XUser User { get; set; }
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XFriendshipFollower.cs

using System.ComponentModel.DataAnnotations.Schema;
using xIdentityModels.Constants;
using xModels.Base;

namespace xIdentityModels.Navigations {
    /// <summary>
    /// represent a Follower of specific User
    /// </summary>
    public class XFriendshipFollower : XBaseIntIDEntity {
        /// <summary>
        /// XFriendshipState
        /// </summary>
        /// <value>state of Friendship at current moment <see>XFriendshipState</see></value>
        public XFriendshipState State { get; set; }

        //
        #region User ...
        /// <summary>
        /// UserId
        /// </summary>
        /// <value>source User's Id</value>
        public string UserId { get; set; }
        /// <summary>
        /// User
        /// </summary>
        /// <value>source User <see>XUser</see></value>
        [ForeignKey (nameof (UserId))]
        public virtual XUser User { get; set; }
        #endregion

        //
        #region Dest User ...
        /// <summary>
        /// DestId
        /// </summary>
        /// <value>destination User's Id</value>
        public string DestId { get; set; }
        /// <summary>
        /// Dest
        /// </summary>
        /// <value>dest User <see>XUser</see></value>
        [ForeignKey (nameof (DestId))]
        public virtual XUser Dest { get; set; }
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XFriendshipFollowing.cs

using System.ComponentModel.DataAnnotations.Schema;
using xIdentityModels.Constants;
using xModels.Base;

namespace xIdentityModels.Navigations {
    /// <summary>
    /// represent a Following of specific User
    /// </summary>
    public class XFriendshipFollowing : XBaseIntIDEntity {
        /// <summary>
        /// XFriendshipState
        /// </summary>
        /// <value>state of Friendship at current moment <see>XFriendshipState</see></value>
        public XFriendshipState State { get; set; }

        //
        #region User ...
        /// <summary>
        /// UserId
        /// </summary>
        /// <value>source User's Id</value>
        public string UserId { get; set; }
        /// <summary>
        /// User
        /// </summary>
        /// <value>source User <see>XUser</see></value>
        [ForeignKey (nameof (UserId))]
        public virtual XUser User { get; set; }
        #endregion

        //
        #region Dest User ...
        /// <summary>
        /// DestId
        /// </summary>
        /// <value>destination User's Id</value>
        public string DestId { get; set; }
        /// <summary>
        /// Dest
        /// </summary>
        /// <value>dest User <see>XUser</see></value>
        [ForeignKey (nameof (DestId))]
        public virtual XUser Dest { get; set; }
        #endregion
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Navigations\XProfileImage.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using xModels.Base;

namespace xIdentityModels.Navigations {
    /// <summary>
    /// Represent a User's Avatar Entity
    /// </summary>
    public class XProfileImage : XBaseIntIDEntity {
        /// <summary>
        /// UserId
        /// </summary>
        /// <value>represent current Avatar belongs to which User</value>
        public string UserId { get; set; }
        /// <summary>
        /// User
        /// </summary>
        /// <value>User instance <see>XUser</see></value>
        [ForeignKey (nameof (UserId))]
        public XUser User { get; set; }
        /// <summary>
        /// Name
        /// </summary>
        /// <value>Avatar's file name</value>
        [Required]
        [StringLength (255)]
        public string Name { get; set; }
        /// <summary>
        /// Thumb
        /// </summary>
        /// <value>Avatar's thumbnail file's name</value>
        [Required]
        [StringLength (255)]
        public string Thumb { get; set; }
        /// <summary>
        /// Path
        /// </summary>
        /// <value>Avatar's Image path on Profile Server</value>
        [Required]
        [StringLength (255)]
        public string Path { get; set; }
        /// <summary>
        /// ThumbPath
        /// </summary>
        /// <value>Avatar's Thumbnail Image path on Profile Service</value>
        [Required]
        [StringLength (255)]
        public string ThumbPath { get; set; }
        /// <summary>
        /// CreationDate
        /// </summary>
        /// <value>Upload Time</value>
        public DateTime CreationDate { get; set; }
    }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityModels\Providers\XDefaultUserRoleHelper.cs

using System.Linq;
using xCommons.Extensions;
using xIdentityModels.Models;
using xIdentityModels.Interfaces;

namespace xIdentityModels.Providers {
    public class XDefaultUserRoleHelper : IXUserRoleHelper {
        public bool canReadCriticalData (XUserClaimsInfoDto userInfo) {
            return isInRole (userInfo, "admin");
        }

        public bool canDoDangerousAction (XUserClaimsInfoDto userInfo) {
            return isInRole (userInfo, "admin");
        }

        public bool isInRole (XUserClaimsInfoDto userInfo, string role) {
            return userInfo.Roles
                .Any (r =>
                    r.ToNormalString () == role.ToNormalString ()
                );
        }
    }
}
