
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\public-api.ts

/*
 * Public API Surface of x-framework-identity-sdk
 */
//
// Config ...
export * from './lib/config/x-api-service.config';
export * from './lib/config/x-framework-identity-sdk.config';

//
// Base ...
export * from './lib/base/x-base-api.service';

//
// Models ...
export * from './lib/models/x-user.dto';
export * from './lib/models/x-page.dto';
export * from './lib/models/x-login.dto';
export * from './lib/models/x-query.dto';
export * from './lib/models/x-string.dto';
export * from './lib/models/x-friend-dto';
export * from './lib/models/x-discovery.dto';
export * from './lib/models/x-friendship.dto';
export * from './lib/models/x-device-info.dto';
export * from './lib/models/x-registration-dto';

//
// Guards ...
export * from './lib/guards/auth.guard';
export * from './lib/guards/not-auth.guard';

//
// Services ...
export * from './lib/x-account.service';
export * from './lib/services/api-http-interceptor.service';

//
// Constants ...
export * from './lib/constants/x-account.keys';
export * from './lib/constants/x-header.enum';
export * from './lib/constants/x-api-scope.enum';

//
// Validators ...
export * from './lib/validators/api-validators';

//
// Typings ...
export * from './lib/typings/x-account.typings';
export * from './lib/typings/x-endpoint.typings';
export * from './lib/typings/x-registration.typings';

//
// Providers ...
export * from './lib/providers/x-url.encoder';

//
// Tools ...
export * from './lib/tools/x-endpoint.tools';

//
// Helpers ...
export * from './lib/helpers/x-account.helper';

//
// Token ...
export * from './lib/tokens/x-injectable-tokens';

//
// Module ...
export * from './lib/x-framework-identity-sdk.module';

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\test.ts

// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import 'zone.js';
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

declare const require: {
  context(path: string, deep?: boolean, filter?: RegExp): {
    keys(): string[];
    <T>(id: string): T;
  };
};

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\x-account.service.ts

import {
  X_API_CONFIG,
  X_FRAMEWORK_IDENTITY_SDK_CONFIG,
} from './tokens/x-injectable-tokens';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XManagerService } from 'x-framework-services';
import { XApiConfiguration } from './config/x-api-service.config';
import { XAccountFinalService } from './partial/x-account.final.service';
import { XFrameworkIdentitySDKConfig } from './config/x-framework-identity-sdk.config';

@Injectable({
  providedIn: 'root',
})
export class XAccountService extends XAccountFinalService {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    config: XFrameworkIdentitySDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration,
    protected managerService: XManagerService
  ) {
    super(router, httpClient, config, apiConfig, managerService);
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\x-framework-identity-sdk.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { XFrameworkCoreModule } from 'x-framework-core';
import { HttpClientModule } from '@angular/common/http';
import { XFrameworkServicesModule } from 'x-framework-services';

@NgModule({
  declarations: [],
  imports: [
    RouterModule,
    CommonModule,
    HttpClientModule,
    XFrameworkCoreModule,
    XFrameworkServicesModule,
  ],
  exports: [
    CommonModule,
    HttpClientModule,
    XFrameworkCoreModule,
    XFrameworkServicesModule,
  ],
  providers: [],
})
export class XFrameworkIdentitySdkModule {}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\base\x-base-api.service.ts

import {
  XParam,
  XLocale,
  XHeader,
  hasChild,
  XKeyValue,
  toXString,
  XBaseService,
  XContentType,
  XExceptionIDs,
  XOneOrManyType,
  throwException,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import { Inject } from '@angular/core';
import {
  X_API_CONFIG,
  X_FRAMEWORK_IDENTITY_SDK_CONFIG,
} from '../tokens/x-injectable-tokens';
import { XQueryDto } from '../models/x-query.dto';
import { setParams } from '../tools/x-endpoint.tools';
import { XPageRequestDto } from '../models/x-page.dto';
import { XEndPoints } from '../typings/x-endpoint.typings';
import { XHttpUrlEncodingCodec } from '../providers/x-url.encoder';
import { XApiConfiguration } from '../config/x-api-service.config';
import { getAuthorizationHeaderValue } from '../constants/x-header.enum';
import { HttpHeaders, HttpClient, HttpParams } from '@angular/common/http';
import { XLoginResponseDto, XTokenResponseDto } from '../models/x-login.dto';
import { XFrameworkIdentitySDKConfig } from '../config/x-framework-identity-sdk.config';

export abstract class XBaseApiService extends XBaseService {
  //
  public readonly basePath: string;
  public readonly version: string;
  public readonly baseEndPointRoute: string;
  public readonly defaultHeaders = new HttpHeaders();
  public apiConfig = new XApiConfiguration();

  constructor(
    public readonly endPoint: XEndPoints,
    public readonly applyApiIdentifier: boolean = false,
    public readonly applyApiVersion: boolean = false,
    protected httpClient: HttpClient,
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    config: XFrameworkIdentitySDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    //
    super(config);

    //
    if (apiConfig) {
      //
      this.version = '';
      if (applyApiVersion) {
        this.version = isNullOrEmptyString(apiConfig.apiVersion)
          ? null
          : apiConfig.apiVersion.replace('/', '');
      }

      //
      let bApiPath = apiConfig.baseApiPath || config.baseUrl;
      if (isNullOrEmptyString(bApiPath)) {
        throwException(XExceptionIDs.InvalidConfiguration);
      }

      //
      bApiPath = bApiPath.endsWith('/')
        ? bApiPath.substring(0, bApiPath.length - 1)
        : bApiPath;

      //
      // Check Api Identifier ...
      if (applyApiIdentifier) {
        const apiIdentifier = config.apiIdentifier || apiConfig.apiIdentifier;
        if (!isNullOrEmptyString(apiIdentifier)) {
          bApiPath = `${bApiPath}/${apiIdentifier}`;
        }
      }

      //
      this.basePath = bApiPath.endsWith('/')
        ? bApiPath.substring(0, bApiPath.length - 1)
        : bApiPath;

      //
      this.apiConfig = apiConfig;
    }

    //
    this.baseEndPointRoute = isNullOrEmptyString(this.version)
      ? `${this.basePath}/${this.endPoint}`
      : `${this.basePath}/${this.version}/${this.endPoint}`;

    //
    if (
      isNullOrUndefined(this.basePath) ||
      isNullOrUndefined(this.baseEndPointRoute)
    ) {
      throwException(XExceptionIDs.InvalidConfiguration);
    }

    //
    // Setting XPowered in Default Headers ...
    this.defaultHeaders = this.defaultHeaders.set(
      XHeader.XPoweredBy,
      apiConfig.poweredByValue
    );

    //
    // Setting Certificate Check ...
    if (
      isNullOrUndefined(config.rejectUnauthorized) &&
      config.rejectUnauthorized === true
    ) {
      //
      this.defaultHeaders = this.defaultHeaders.set(
        XHeader.RejectUnauthorized,
        toXString(config.rejectUnauthorized)
      );
    }
  }

  //
  //#region Actions ...

  /**
   * @param consumes string[] mime-types
   * @return true: consumes contains 'multipart/form-data', false: otherwise
   */
  public canConsumeForm(consumes: string[]): boolean {
    //
    const form = 'multipart/form-data';
    for (const consume of consumes) {
      if (form === consume) {
        return true;
      }
    }

    //
    return false;
  }

  /**
   * adding Authentication & Authorization headers
   */
  public addAuthentication(
    headers: HttpHeaders,
    tokens?: XTokenResponseDto
  ): HttpHeaders;
  public addAuthentication(
    headers: HttpHeaders,
    tokens?: XLoginResponseDto
  ): HttpHeaders {
    //
    // if doesn't Provide Tokens, read and apply from Configurations ...
    if (!tokens) {
      //
      // Handle Authentication (access_token) required
      if (
        !isNullOrUndefined(this.apiConfig.apiKeys) &&
        !isNullOrEmptyString(this.apiConfig.apiKeys.Authorization)
      ) {
        headers = headers.set(
          XHeader.Authorization,
          this.apiConfig.apiKeys.Authorization
        );
      }
    }

    //
    // if Provide Tokens read and apply from it ...
    if (tokens) {
      //
      // Access Token ...
      if (!isNullOrEmptyString(tokens.accessToken)) {
        headers = headers.set(
          XHeader.Authorization,
          getAuthorizationHeaderValue(tokens.accessToken)
        );
      }

      //
      // Refresh Token ...
      if (!isNullOrEmptyString(tokens.refreshToken)) {
        headers = headers.set(XHeader.RefreshToken, tokens.refreshToken);
      }

      //
      // Expired At ...
      if (!isNullOrUndefined(tokens.expiresAt)) {
        headers = headers.set(XHeader.ExpiresAt, tokens.expiresAt.toString());
      }
    }

    //
    return headers;
  }

  /**
   * add custom header to request
   *
   * @param headers headers object
   * @param key custom header key
   * @param value custom header value
   */
  public addCustomHeader(
    headers?: HttpHeaders,
    item?: XKeyValue<XParam | XHeader | string, any>,
    forceAddDefaultHeaders = false
  ): HttpHeaders {
    //
    // Instance Headers if not Exists ...
    if (!headers) {
      headers = new HttpHeaders();
    }

    //
    // Add Default Headers if required ...
    if (
      forceAddDefaultHeaders &&
      !isNullOrUndefined(this.defaultHeaders) &&
      hasChild(this.defaultHeaders.keys())
    ) {
      //
      this.defaultHeaders.keys().forEach((dKey) => {
        //
        const dValue = this.defaultHeaders.get(dKey);
        headers = headers.set(dKey, dValue);
      });
    }

    //
    // Add Item ...
    if (
      item &&
      !isNullOrUndefined(item) &&
      !isNullOrUndefined(item.key) &&
      !isNullOrUndefined(item.value)
    ) {
      //
      headers = headers.set(item.key, toXString(item.value));
    }

    //
    return headers;
  }

  /**
   * add default accept selected to headers
   */
  public addAcceptJson(headers: HttpHeaders): HttpHeaders {
    //
    // to determine the Accept header
    const httpHeaderAccepts: string[] = [XContentType.AppJson];
    const httpHeaderAcceptSelected: string | undefined =
      this.apiConfig.selectHeaderAccept(httpHeaderAccepts);
    if (httpHeaderAcceptSelected !== undefined) {
      headers = headers.set(XHeader.Accept, httpHeaderAcceptSelected);
    }

    //
    return headers;
  }

  /**
   * adding application/octet-stream Accept in header ...
   *
   * @param headers the exists contents of header
   */
  public addAcceptOctetStream(headers: HttpHeaders): HttpHeaders {
    //
    // to determine the Accept header
    const httpHeaderAccepts: string[] = [XContentType.AppOctetStream];
    const httpHeaderAcceptSelected: string | undefined =
      this.apiConfig.selectHeaderAccept(httpHeaderAccepts);
    if (httpHeaderAcceptSelected !== undefined) {
      headers = headers.set(XHeader.Accept, httpHeaderAcceptSelected);
    }

    //
    return headers;
  }

  /**
   * add language to headers ...
   *
   * @param headers the source headers ...
   * @param language the specific language name ...
   */
  public addLanguageHeader(
    headers: HttpHeaders,
    language: XLocale | string
  ): HttpHeaders {
    //
    if (isNullOrEmptyString(language)) {
      return headers;
    }

    //
    return this.addCustomHeader(headers, {
      key: XParam.Language,
      value: language,
    });
  }

  /**
   * add ContentType  to headers
   */
  public addContentType(
    headers: HttpHeaders,
    consumes?: string[]
  ): HttpHeaders {
    //
    // to determine the Content-Type header
    if (!consumes) {
      consumes = [];
    }
    consumes = [...consumes, XContentType.AppJson];
    const httpContentTypeSelected: string | undefined =
      this.apiConfig.selectHeaderContentType(consumes);
    if (httpContentTypeSelected !== undefined) {
      headers = headers.set(XHeader.ContentType, httpContentTypeSelected);
    }

    //
    return headers;
  }

  /**
   * generate proper http params based on XQuery ...
   *
   * @param query the Qury Options ...
   */
  public generateXQueryHttpParams(query?: XQueryDto): HttpParams {
    //
    let result = new HttpParams({
      encoder: new XHttpUrlEncodingCodec(),
    });

    //
    if (query) {
      //
      // Filter ...
      if (!isNullOrEmptyString(query.filter)) {
        result = result.set(XParam.Filter, query.filter as string);
      }

      //
      // ContainsDetail ...
      if (!isNullOrUndefined(query.containsDetail)) {
        result = result.set(
          XParam.ContainsDetail,
          toXString(query.containsDetail)
        );
      }

      //
      // EnableTracking ...
      if (!isNullOrUndefined(query.enableTracking)) {
        result = result.set(
          XParam.EnableTracking,
          toXString(query.enableTracking)
        );
      }

      //
      // SortBy ...
      if (!isNullOrEmptyString(query.sortBy)) {
        result = result.set(XParam.SortBy, toXString(query.sortBy));
      }

      //
      // IsAscending ...
      if (!isNullOrUndefined(query.isAscending)) {
        result = result.set(XParam.IsAscending, toXString(query.isAscending));
      }

      //
      // Page ...
      if (!isNullOrUndefined(query.page)) {
        result = result.set(XParam.Page, toXString(query.page));
      }

      //
      // PageSize ...
      if (!isNullOrUndefined(query.pageSize)) {
        result = result.set(XParam.PageSize, toXString(query.pageSize));
      }
    }

    //
    return result;
  }

  /**
   * generate proper http params based on RequestPage ...
   *
   * @param request the RequestPage Options ...
   */
  public generateXRequestPageHttpParams(request?: XPageRequestDto): HttpParams {
    //
    let queryParameters = new HttpParams({
      encoder: new XHttpUrlEncodingCodec(),
    });

    //
    if (request) {
      //
      // First ...
      if (!isNullOrUndefined(request.first)) {
        queryParameters = queryParameters.set(
          XParam.First,
          toXString(request.first)
        );
      }

      //
      // Last ...
      if (!isNullOrUndefined(request.last)) {
        queryParameters = queryParameters.set(
          XParam.Last,
          toXString(request.last)
        );
      }

      //
      // After ...
      if (!isNullOrEmptyString(request.after)) {
        queryParameters = queryParameters.set(
          XParam.After,
          toXString(request.after)
        );
      }

      //
      // Before ...
      if (!isNullOrEmptyString(request.before)) {
        queryParameters = queryParameters.set(
          XParam.Before,
          toXString(request.before)
        );
      }

      //
      // SortBy ...
      if (!isNullOrEmptyString(request.sortBy)) {
        queryParameters = queryParameters.set(
          XParam.SortBy,
          toXString(request.sortBy)
        );
      }

      //
      // DescendingSort ...
      if (!!request.descendingSort) {
        queryParameters = queryParameters.set(
          XParam.DescendingSort,
          toXString(request.descendingSort)
        );
      }
    }

    //
    return queryParameters;
  }

  /**
   * add specific param to an existings params collection ...
   *
   * @param params the exists params ...
   * @param item the specific key value ...
   */
  public addCustomParam(
    params?: HttpParams,
    item?: XKeyValue<XParam | XHeader | string, any>
  ): HttpParams {
    //
    if (!params) {
      //
      params = new HttpParams({
        encoder: new XHttpUrlEncodingCodec(),
      });
    }

    //
    if (
      item &&
      !isNullOrUndefined(item) &&
      !isNullOrUndefined(item.key) &&
      !isNullOrUndefined(item.value)
    ) {
      //
      params = params.set(item.key, toXString(item.value));
    }

    //
    return params;
  }

  /**
   * add specific language param to an existings params collection ...
   *
   * @param params the exists params ...
   * @param language the specific language value ...
   */
  public addLanguageQueryParam(
    params?: HttpParams,
    language?: XLocale | string
  ): HttpParams {
    //
    if (!params) {
      //
      params = new HttpParams({
        encoder: new XHttpUrlEncodingCodec(),
      });
    }

    //
    if (isNullOrEmptyString(language)) {
      return params;
    }

    //
    params = params.set(XParam.Language, language);

    //
    return params;
  }

  /**
   * attach containsDetail to Query String ...
   *
   * @param params exists param ..
   * @param containsDetail the value ...
   * @returns an instance of HttpParams ...
   */
  public addContainsDetailQueryParam(
    params?: HttpParams,
    containsDetail?: boolean
  ): HttpParams {
    //
    if (!params) {
      //
      params = new HttpParams({
        encoder: new XHttpUrlEncodingCodec(),
      });
    }

    //
    if (!!containsDetail) {
      params = params.set(XParam.ContainsDetail, toXString(containsDetail));
    }

    //
    return params;
  }

  /**
   * generate containsDetail Http Param ...
   *
   * @param containsDetail the param value ...
   */
  public generateContainsDetailHttpParam(containsDetail: boolean): HttpParams {
    //
    let queryParameters = new HttpParams({
      encoder: new XHttpUrlEncodingCodec(),
    });
    if (containsDetail) {
      queryParameters = queryParameters.set(
        XParam.ContainsDetail,
        containsDetail.toString()
      );
    }

    //
    return queryParameters;
  }

  /**
   * generate and retrieve language http param ...
   *
   * @param language the specific language
   */
  public generateLanguageHttpParam(language: XLocale | string): HttpParams {
    //
    let result = new HttpParams({
      encoder: new XHttpUrlEncodingCodec(),
    });

    //
    if (!isNullOrEmptyString(language)) {
      result = result.set(XParam.Language, language);
    }

    //
    return result;
  }

  /**
   * retrieve specific Action Route
   * @param action the specified Action endpoint
   * @returns complete action route contains route params
   */
  public getActionRoute<T, TParams>(
    action: T,
    params?: XOneOrManyType<XKeyValue<TParams, string>>
  ) {
    //
    if (isNullOrEmptyString(String(action))) {
      return this.baseEndPointRoute;
    }

    //
    let result = `${this.baseEndPointRoute}/${String(action)}`;
    if (!hasChild(params)) {
      return result;
    }

    //
    result = setParams(result, params);
    return result;
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\config\x-api-service.config.ts

import {
  XApiHeader,
  getAuthorizationHeaderValue
} from '../constants/x-header.enum';
import { isNullOrUndefined } from 'x-framework-core';
import { XUserAccountInfo } from '../typings/x-account.typings';

export interface XApiConfigurationParameters {
  apiKeys?: { [key: string]: string };
  username?: string;
  password?: string;
  accessToken?: string | (() => string);
  baseApiPath?: string;
  apiVersion?: string;
  apiIdentifier?: string;
  withCredentials?: boolean;
  poweredByValue?: string;
  revisionSecretKey?: string;
}

export class XApiConfiguration {
  apiKeys?: { [key: string]: string };
  username?: string;
  password?: string;
  accessToken?: string | (() => string);
  baseApiPath?: string;
  apiVersion?: string;
  apiIdentifier?: string;
  withCredentials?: boolean;
  poweredByValue?: string;
  revisionSecretKey?: string;

  constructor(configurationParameters: XApiConfigurationParameters = {}) {
    this.apiKeys = configurationParameters.apiKeys;
    this.username = configurationParameters.username;
    this.password = configurationParameters.password;
    this.accessToken = configurationParameters.accessToken;
    this.baseApiPath = configurationParameters.baseApiPath;
    this.apiVersion = configurationParameters.apiVersion;
    this.apiIdentifier = configurationParameters.apiIdentifier;
    this.withCredentials = configurationParameters.withCredentials;
    this.poweredByValue = configurationParameters.poweredByValue;
    this.revisionSecretKey = configurationParameters.revisionSecretKey;
  }

  /**
   * Select the correct content-type to use for a request.
   * Uses {@link Configuration#isJsonMime} to determine the correct content-type.
   * If no content type is found return the first found type if the contentTypes is not empty
   * @param contentTypes - the array of content types that are available for selection
   * @returns the selected content-type or <code>undefined</code> if no selection could be made.
   */
  public selectHeaderContentType(contentTypes: string[]): string | undefined {
    if (contentTypes.length === 0) {
      return undefined;
    }

    const type = contentTypes.find(x => this.isJsonMime(x));
    if (type === undefined) {
      return contentTypes[0];
    }
    return type;
  }

  /**
   * Select the correct accept content-type to use for a request.
   * Uses {@link Configuration#isJsonMime} to determine the correct accept content-type.
   * If no content type is found return the first found type if the contentTypes is not empty
   * @param accepts - the array of content types that are available for selection.
   * @returns the selected content-type or <code>undefined</code> if no selection could be made.
   */
  public selectHeaderAccept(accepts: string[]): string | undefined {
    if (accepts.length === 0) {
      return undefined;
    }

    const type = accepts.find(x => this.isJsonMime(x));
    if (type === undefined) {
      return accepts[0];
    }
    return type;
  }

  /**
   * Check if the given MIME is a JSON MIME.
   * JSON MIME examples:
   *   application/json
   *   application/json; charset=UTF8
   *   APPLICATION/JSON
   *   application/vnd.company+json
   * @param mime - MIME (Multipurpose Internet Mail Extensions)
   * @return True if the given MIME is JSON, false otherwise.
   */
  public isJsonMime(mime: string): boolean {
    const jsonMime: RegExp = new RegExp(
      '^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$',
      'i'
    );
    return (
      mime != null &&
      (jsonMime.test(mime) ||
        mime.toLowerCase() === 'application/json-patch+json')
    );
  }

  /**
   * when a User LoggedIn, the User Info must passed to this object
   * for using to add authentication in services ...
   *
   * @param userAccount loggedIn user info
   */
  public async setUserAccount(userAccount: XUserAccountInfo): Promise<void> {
    //
    // Fill Empty Values to user Account if it' null ...
    // this is used for clearing stored data on logout event ...
    if (isNullOrUndefined(userAccount)) {
      userAccount = {
        userSelectBy: '',
        accessToken: '',
        refreshToken: '',
        expiresAt: -1,
        profile: null
      };
    }

    //
    this.accessToken = userAccount.accessToken;
    this.username = userAccount.userSelectBy;

    //
    if (!this.apiKeys) {
      this.apiKeys = {};
    }

    //
    this.apiKeys[XApiHeader.ExpiresAt] = userAccount.expiresAt
      ? userAccount.expiresAt.toString()
      : '-1';
    this.apiKeys[XApiHeader.RefreshToken] = userAccount.refreshToken;
    this.apiKeys[XApiHeader.Authorization] = getAuthorizationHeaderValue(
      userAccount.accessToken
    );
  }
}

export const COLLECTION_FORMATS = {
  csv: ',',
  tsv: '   ',
  ssv: ' ',
  pipes: '|'
};

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\config\x-framework-identity-sdk.config.ts

import { XFrameworkCoreConfig } from 'x-framework-core';
import { XFrameworkServicesConfig } from 'x-framework-services';

export type XSharedConfig = XFrameworkCoreConfig &
  XFrameworkServicesConfig & { [key: string]: any };

export interface XFrameworkIdentitySDKConfig extends XSharedConfig {
  //
  // Api Configuration ...
  baseUrl: string;
  apiVersion: string;
  poweredValue: string;
  apiIdentifier: string;

  //
  // Server SSL Check ...
  rejectUnauthorized?: boolean;

  //
  // Registration Types ...
  registrationType: string[];

  //
  // Registration Available ...
  minAvailableDateConst: number;
  maxAvailableDateConst: number;

  //
  // Debouncing async actions Time ...
  debounceTime: number;

  //
  nameMinLength: number;
  nameMaxLength: number;

  //
  registrationOnlyWithInvitation: boolean;

  //
  userNameMinLength: number;
  userNameMaxLength: number;

  //
  passwordPolicies?: {
    requireDigit?: boolean;
    requiredLength?: number;
    requiredUniqueChars?: number;
    requireLowercase?: boolean;
    requireNonAlphanumeric?: boolean;
    requireUppercase?: boolean;
  };

  //
  passwordMinLength: number;
  passwordMaxLength: number;

  //
  verificationCodeLength: number;
  delayBetweenTwoVerificationCode: number;

  //
  // Attach Pages Index to Handle in Guard Rejects ...
  Pages: any;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\constants\x-account.keys.ts

export enum XAccountStorageKeys {
  UserSelectBy = '[ACCOUNT] USER',
  DefaultUser = '[ACCOUNT] DEFAULT USER',
  UserInfos = '[ACCOUNT] USER INFO'
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\constants\x-api-scope.enum.ts

export enum XApiScope {
  Read,
  Write,
  Admin,
  Manage,
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\constants\x-header.enum.ts

export enum XApiHeader {
  ExpiresAt = 'expires_at',
  RefreshToken = 'refresh_token',
  Authorization = 'Authorization',
  AuthorizationPrefix = 'Bearer ',
}

export function getAuthorizationHeaderValue(token: string): string {
  return `${XApiHeader.AuthorizationPrefix}${token}`;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\guards\auth.guard.ts

import {
  Route,
  CanLoad,
  UrlTree,
  UrlSegment,
  CanActivate,
  CanActivateChild,
  RouterStateSnapshot,
  ActivatedRouteSnapshot,
} from '@angular/router';
import { Observable } from 'rxjs';
import { map, tap, filter } from 'rxjs/operators';
import { Injectable, Inject } from '@angular/core';
import { XManagerService } from 'x-framework-services';
import { XAccountService } from './../x-account.service';
import { XLoggable, XExceptionIDs, isNullOrUndefined } from 'x-framework-core';
import { X_FRAMEWORK_IDENTITY_SDK_CONFIG } from '../tokens/x-injectable-tokens';
import { XFrameworkIdentitySDKConfig } from '../config/x-framework-identity-sdk.config';

@Injectable({
  providedIn: 'root',
})
export class AuthGuard
  extends XLoggable
  implements CanActivate, CanActivateChild, CanLoad
{
  //
  constructor(
    private authService: XAccountService,
    private managerService: XManagerService,
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    public config: XFrameworkIdentitySDKConfig
  ) {
    super(config);
  }

  //
  //#region Actions ...
  //
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.handleGuard();
  }

  //
  canActivateChild(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.handleGuard();
  }

  //
  canLoad(
    route: Route,
    segments: UrlSegment[]
  ): Observable<boolean> | Promise<boolean> | boolean {
    return this.handleGuard();
  }
  //#endregion

  //
  //#region Private Action ...
  private handleGuard(): Observable<boolean> {
    return this.authService.state$.pipe(
      filter((state) => !isNullOrUndefined(state)),
      map((state) => state.isLoggedIn),
      tap((isPassed) => {
        //
        if (!isPassed) {
          this.handleGuardReject();
        }
      })
    );
  }

  //
  private handleGuardReject(): void {
    //
    this.managerService.notificationService.presentErrorNotification({
      exception: XExceptionIDs.NotAuthorized,
      dissmissable: true,
    });

    //
    this.managerService.navigateByPageReplace(this.config.Pages.Login);
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\guards\not-auth.guard.ts

import {
  Route,
  UrlTree,
  CanLoad,
  UrlSegment,
  CanActivate,
  CanActivateChild,
  RouterStateSnapshot,
  ActivatedRouteSnapshot,
} from '@angular/router';
import { Observable } from 'rxjs';
import { map, tap, filter } from 'rxjs/operators';
import { Injectable, Inject } from '@angular/core';
import { XManagerService } from 'x-framework-services';
import { XAccountService } from './../x-account.service';
import {
  XLoggable,
  XExceptionIDs,
  isNullOrUndefined,
  toObservable,
} from 'x-framework-core';
import { X_FRAMEWORK_IDENTITY_SDK_CONFIG } from '../tokens/x-injectable-tokens';
import { XFrameworkIdentitySDKConfig } from '../config/x-framework-identity-sdk.config';

@Injectable({
  providedIn: 'root',
})
export class NotAuthGuard
  extends XLoggable
  implements CanActivate, CanActivateChild, CanLoad
{
  //
  constructor(
    private authService: XAccountService,
    private managerService: XManagerService,
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    public config: XFrameworkIdentitySDKConfig
  ) {
    super(config);
  }

  //
  //#region Actions ...
  //
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.handleGuard();
  }

  //
  canActivateChild(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    //
    return this.handleGuard();
  }

  //
  canLoad(
    route: Route,
    segments: UrlSegment[]
  ): Observable<boolean> | Promise<boolean> | boolean {
    return this.handleGuard();
  }
  //#endregion

  //
  //#region Private Action ...
  private handleGuard(): Observable<boolean> {
    return toObservable(this.authService.isLoggedIn()).pipe(
      map((isLoggedIn) => !isLoggedIn),
      tap((isPassed) => {
        //
        if (!isPassed) {
          this.handleGuardReject();
        }
      })
    );
  }

  //
  private handleGuardReject(): void {
    //
    this.managerService.notificationService.presentErrorNotification({
      exception: XExceptionIDs.MustLogout,
      dissmissable: true,
    });

    //
    this.managerService.navigateByPageReplace(this.config.Pages.Startup);
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\helpers\x-account.helper.ts

import { XValidators } from 'x-framework-core';
import { XUserAccountInfo } from '../typings/x-account.typings';

export function validateUserAccountInfo(model: XUserAccountInfo): void {
  //
  XValidators.validateNotNull(model);
  XValidators.validateNotEmpty(
    model.userSelectBy,
    model.accessToken,
    model.refreshToken
  );
  XValidators.validateBiggerThan(0, model.expiresAt);
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-device-info.dto.ts

export interface XDeviceInfo {
  os: string;
  osVersion: string;
  browser: string;
  userAgent: string;
  deviceType: XDeviceTypes;
  userId?: number;

  identifier?: string;
  token?: string;
}

export enum XDeviceTypes {
  Unknown,
  Mobile,
  Tablet,
  Desktop
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-discovery.dto.ts

import { XBaseDto } from 'x-framework-core';

/**
 * Models the response from an OpenID Connect discovery endpoint
 */
export interface XDiscoveryDto extends XBaseDto {
  /**
   * Gets the raw response.
   */
  raw?: string;
  /**
   * Gets the response as a JObject.
   */
  json?: any;
  /**
   * Gets a value indicating whether an error occurred.
   */
  isError?: boolean;
  /**
   * Gets the status code.
   */
  statusCode?: any;
  /**
   * Gets the error.
   */
  error?: string;
  /**
   * Gets or sets the type of the error.
   */
  errorType?: any;
  /**
   * Gets the exception.
   */
  exception?: any;
  /**
   * Gets or sets the JSON web key set.
   */
  keySet?: any;
  issuer?: string;
  authorizeEndpoint?: string;
  tokenEndpoint?: string;
  userInfoEndpoint?: string;
  introspectionEndpoint?: string;
  revocationEndpoint?: string;
  deviceAuthorizationEndpoint?: string;
  jwksUri?: string;
  endSessionEndpoint?: string;
  checkSessionIframe?: string;
  registrationEndpoint?: string;
  frontChannelLogoutSupported?: boolean;
  frontChannelLogoutSessionSupported?: boolean;
  grantTypesSupported?: Array<string>;
  codeChallengeMethodsSupported?: Array<string>;
  scopesSupported?: Array<string>;
  subjectTypesSupported?: Array<string>;
  responseModesSupported?: Array<string>;
  responseTypesSupported?: Array<string>;
  claimsSupported?: Array<string>;
  tokenEndpointAuthenticationMethodsSupported?: Array<string>;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-friend-dto.ts

import {
  XBaseDto,
  isSameObject,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import { XFriendshipState } from './x-friendship.dto';

/**
 * All Available Friendship Types ...
 */
export enum XFriendshipType {
  Follower = 0,
  Following = 1,
}

/**
 * a Dto interface Which Represent a User Friend ...
 */
export interface XFriendDto extends XBaseDto {
  avatar: string;
  userId: string;
  username: string;
  lastname: string;
  firstname: string;
  type?: XFriendshipType;
  state?: XFriendshipState;
}

export const defaultFriendDto: XFriendDto = {
  avatar: '',
  userId: '',
  username: '',
  lastname: '',
  firstname: '',
  type: undefined,
  state: undefined,
};

export function prepareFriendDtoFields(model?: XFriendDto) {
  //
  if (isNullOrUndefined(model)) {
    model = {
      ...defaultFriendDto,
    };
  }

  //
  model = {
    ...defaultFriendDto,

    //
    avatar: !isNullOrEmptyString(model.avatar)
      ? model.avatar
      : defaultFriendDto.avatar,
    userId: !isNullOrEmptyString(model.userId)
      ? model.userId
      : defaultFriendDto.userId,
    username: !isNullOrEmptyString(model.username)
      ? model.username
      : defaultFriendDto.username,
    lastname: !isNullOrEmptyString(model.lastname)
      ? model.lastname
      : defaultFriendDto.lastname,
    firstname: !isNullOrEmptyString(model.firstname)
      ? model.firstname
      : defaultFriendDto.firstname,

    //
    type: !isNullOrUndefined(model.type) ? model.type : defaultFriendDto.type,
    state: !isNullOrUndefined(model.state)
      ? model.state
      : defaultFriendDto.state,
  };

  //
  return model;
}

export function isDefaultFriendDto(model: XFriendDto) {
  return isSameObject(prepareFriendDtoFields(model), defaultFriendDto);
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-friendship.dto.ts

import { XBaseDto } from 'x-framework-core';

export enum XFriendshipState {
  None,
  Pending,
  Accepted,
  Rejected,
  Blocked
}

export type XFriendshipStates = keyof typeof XFriendshipState;

export interface XFriendshipFollowerDto extends XBaseDto {
  state: XFriendshipState;
  userId: string;
  destId: string;
}

export interface XFriendshipFollowingDto extends XBaseDto {
  state: XFriendshipState;
  userId: string;
  destId: string;
}

export interface XFriendshipInfoDto {
  userId: string;
  isFollower: boolean;
  isFollowing: boolean;
  followerState: XFriendshipState;
  followingState: XFriendshipState;
  followers: number;
  followings: number;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-login.dto.ts

import { XLocale } from 'x-framework-core';
import { XUserProfileDto } from './x-user.dto';
import { XDeviceInfo } from './x-device-info.dto';
import { XBaseResponseDto, XBaseRequestDto } from 'x-framework-core';

export interface XLoginRequestDto extends XBaseRequestDto {
  userSelectBy: string;
  password: string;
  device?: XDeviceInfo;
  language?: XLocale;
}

export interface XTokenResponseDto extends XBaseResponseDto {
  accessToken: string;
  refreshToken: string;
  expiresAt: number;
}

export interface XLoginResponseDto extends XTokenResponseDto {
  profile: XUserProfileDto;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-page.dto.ts

export interface XPageRequestDto {
  first?: number;
  last?: number;
  after: string;
  before: string;
  sortBy: string;
  descendingSort: boolean;
}

export interface XPageResponseDto<T> {
  nodes: Array<T>;
  totalCount: number;
  hasNextPage: boolean;
  hasPreviousPage: boolean;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-query.dto.ts

export interface XQueryDto {
  page?: number;
  filter?: string;
  sortBy?: string;
  pageSize?: number;
  isAscending?: boolean;
  containsDetail?: boolean;
  enableTracking?: boolean;
}

export interface XQueryResultDto<T = any> {
  page?: number;
  items?: Array<T>;
  pageSize?: number;
  totalPages?: number;
  totalItems?: number;
  totalFilteredItems?: number;
  totalFilteredPages?: number;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-registration-dto.ts

import { XDeviceInfo } from './x-device-info.dto';
import { XBaseRequestDto, XBaseResponseDto } from 'x-framework-core';

export interface XActionRequestDto extends XBaseRequestDto {
  acceptTerms?: boolean;
  termsAndConditions?: string;
  lang?: string;
  actionToken?: string;
  device?: XDeviceInfo;
  firstName?: string;
  lastName?: string;
  dateOfBirth?: Date;
  userId?: string;
  userName?: string;
  email?: string;
  mobileNumber?: string;
  password?: string;
  newPassword?: string;
  emailVerificationCode?: string;
  mobileVerificationCode?: string;
  thumbnail?: string;
  returnUrl?: string;
  avatar?: File;
}

export interface XActionResponseDto extends XBaseResponseDto {
  token?: string;
  expiration?: Date;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-string.dto.ts

import {
  XLocale,
  isSameObject,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import { XBaseNumberIDDto, XBaseRequestDto } from 'x-framework-core';

export interface XStringDto extends XBaseNumberIDDto {
  language: XLocale | string;
  resourceTitle: string;
  translatedValue: string;
}

export interface XUpdateStringsRequestDto extends XBaseRequestDto {
  resources: Array<XStringDto>;
}

export const defaultStringDto: XStringDto = {
  id: 0,
  language: '',
  resourceTitle: '',
  translatedValue: '',
};

export function prepareStringDtoFields(model: XStringDto) {
  //
  if (!model) {
    model = {
      ...defaultStringDto,
    };
  }

  //
  if (isNullOrUndefined(model.id)) {
    model.id = defaultStringDto.id;
  }

  //
  if (isNullOrEmptyString(model.language)) {
    model.language = defaultStringDto.language;
  }

  //
  if (isNullOrEmptyString(model.resourceTitle)) {
    model.resourceTitle = defaultStringDto.resourceTitle;
  }

  //
  if (isNullOrEmptyString(model.translatedValue)) {
    model.translatedValue = defaultStringDto.translatedValue;
  }

  //
  return model;
}

export function isDefaultStringDto(model: XStringDto) {
  return isSameObject(prepareStringDtoFields(model), defaultStringDto);
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\models\x-user.dto.ts

import {
  fromUtcDate,
  XBaseRequestDto,
  XBaseResponseDto,
  XBaseNumberIDDto,
} from 'x-framework-core';
import { isSameObject } from 'x-framework-core';
import { XFriendshipInfoDto } from './x-friendship.dto';

export enum XGender {
  Male,
  Female,
}

export interface XUserProfileDto extends XBaseResponseDto {
  //
  userId: string;
  userName: string;

  email?: string;
  emailConfirmed?: boolean;
  phoneNumber?: string;
  phoneNumberConfirmed?: boolean;
  dateOfBirth?: Date;

  creationDate?: Date;

  firstName?: string;
  lastName?: string;
  lastLogin?: Date;
  avatar?: string;
  gender?: XGender;
  friendshipInfo?: XFriendshipInfoDto;
  roles?: Array<string>;
  avatars?: Array<XavatarDto>;

  isEnable?: boolean;
  isBanned?: boolean;
}

export const defaultUserProfileDto: XUserProfileDto = {
  //
  userId: '',
  userName: '',

  //
  email: '',
  emailConfirmed: false,

  //
  phoneNumber: '',
  phoneNumberConfirmed: false,

  //
  dateOfBirth: undefined,
  creationDate: undefined,

  //
  firstName: '',
  lastName: '',

  //
  lastLogin: undefined,
  avatar: '',

  //
  gender: XGender.Male,

  //
  roles: [],
  avatars: [],

  //
  friendshipInfo: undefined,

  //
  isEnable: false,
  isBanned: false,
};

export function prepareUserProfileDtoFields(
  model: XUserProfileDto
): XUserProfileDto {
  //
  if (!model) {
    model = {
      ...defaultUserProfileDto,
    };
  }

  //
  model = {
    ...defaultUserProfileDto,

    //
    userId: model.userId || defaultUserProfileDto.userId,
    userName: model.userName || defaultUserProfileDto.userName,

    //
    firstName: model.firstName || defaultUserProfileDto.firstName,
    lastName: model.lastName || defaultUserProfileDto.lastName,

    //
    gender: model.gender || defaultUserProfileDto.gender,

    //
    email: model.email || defaultUserProfileDto.email,
    emailConfirmed:
      model.emailConfirmed || defaultUserProfileDto.emailConfirmed,

    //
    phoneNumber: model.phoneNumber || defaultUserProfileDto.phoneNumber,
    phoneNumberConfirmed:
      model.phoneNumberConfirmed || defaultUserProfileDto.phoneNumberConfirmed,

    //
    dateOfBirth:
      fromUtcDate(model.dateOfBirth) || defaultUserProfileDto.dateOfBirth,
    creationDate:
      fromUtcDate(model.creationDate) || defaultUserProfileDto.creationDate,
    lastLogin: fromUtcDate(model.lastLogin) || defaultUserProfileDto.lastLogin,

    //
    avatar: model.avatar || defaultUserProfileDto.avatar,
    friendshipInfo:
      model.friendshipInfo || defaultUserProfileDto.friendshipInfo,
    roles: model.roles || defaultUserProfileDto.roles,
    avatars: model.avatars || defaultUserProfileDto.avatars,

    //
    isEnable: model.isEnable || defaultUserProfileDto.isEnable,
    isBanned: model.isBanned || defaultUserProfileDto.isBanned,
  };

  //
  return model;
}

export function isDefaultUserProfileDto(model: XUserProfileDto): boolean {
  return isSameObject(
    prepareUserProfileDtoFields(model),
    defaultUserProfileDto
  );
}

export interface XavatarDto extends XBaseResponseDto {
  id: number;
  name: string;
  path: string;
  thumb: string;
  thumbPath: string;
  creationDate: Date;
}

export interface XUserNameIdResponseDto extends XBaseResponseDto {
  id: string;
  userName: string;
}

export interface XUserNameIdRequestDto extends XBaseRequestDto {
  ids: string[];
}

export interface XProfileUpdateRequestDto extends XBaseRequestDto {
  email: string;
  emailConfirmed?: boolean;
  phoneNumber: string;
  phoneNumberConfirmed?: boolean;
  firstName: string;
  lastName: string;
  avatar: string;
  dateOfBirth?: Date;
  creationDate?: Date;
  lastLogin?: Date;
  gender: XGender;
  roles?: Array<string>;
  isEnable?: boolean;
  isBanned?: boolean;
}

export interface XChangeRoleRequest extends XBaseRequestDto {
  userId: string;
  newRole: string;
  bussinessRoleInfo: XBusinessOwner;
}

export interface XBusinessOwner extends XBaseNumberIDDto {
  userId: string;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.admin.service.ts

import { Observable } from 'rxjs';
import {
  XAccountEndPoint,
  XAccountEndPointParam,
} from '../typings/x-endpoint.typings';
import { XUserNameIdRequestDto } from '../models/x-user.dto';
import { HttpEvent, HttpResponse } from '@angular/common/http';
import { XAccountRegistrationService } from './x-account.registration.service';

export class XAccountAdminService extends XAccountRegistrationService {
  //
  //#region Ban ...
  /**
   * ban users access to resources
   *
   * @param body the collection of user id's
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public ban(
    body: XUserNameIdRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<string[]>;
  public ban(
    body: XUserNameIdRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<string[]>>;
  public ban(
    body: XUserNameIdRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<string[]>>;
  public ban(
    body: XUserNameIdRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Ban);

    //
    // Prepare Result ...
    return this.httpClient.post<string[]>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region UnBan ...
  /**
   * unban users access to resources
   *
   * @param body the collection of user id's
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public unBan(
    body: XUserNameIdRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<string[]>;
  public unBan(
    body: XUserNameIdRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<string[]>>;
  public unBan(
    body: XUserNameIdRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<string[]>>;
  public unBan(
    body: XUserNameIdRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.UnBan);

    //
    // Prepare Result ...
    return this.httpClient.post<string[]>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region IsBanned ...
  /**
   * check a User is Banned or not
   *
   * @param destUser the user id's which going to check Banned or not
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public isBanned(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public isBanned(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public isBanned(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public isBanned(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.IsBanned, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.authentication.service.ts

import {
  XHeader,
  fromJson,
  toPromise,
  XValidators,
  XExceptionIDs,
  throwException,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  XTokenResponseDto,
  XLoginRequestDto,
  XLoginResponseDto,
} from '../models/x-login.dto';
import { Observable, of } from 'rxjs';
import {
  XAccountEndPoint,
  XAccountEndPointParam,
} from '../typings/x-endpoint.typings';
import { map, concatMap } from 'rxjs/operators';
import { XDiscoveryDto } from '../models/x-discovery.dto';
import { XApiScope } from '../constants/x-api-scope.enum';
import { HttpResponse, HttpEvent } from '@angular/common/http';
import { XAccountBaseService } from './x-account.base.service';
import { XUserAccountInfo } from '../typings/x-account.typings';

export abstract class XAccountAuthenticationService extends XAccountBaseService {
  //
  //#region DiscoveryDocument ...
  /**
   * Retrieve Discovery Document
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public requestDiscoveryDocument(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XDiscoveryDto>;
  public requestDiscoveryDocument(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XDiscoveryDto>>;
  public requestDiscoveryDocument(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XDiscoveryDto>>;
  public requestDiscoveryDocument(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.DiscoveryDocument);

    //
    // return result ...
    return this.httpClient.get<XDiscoveryDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ScopeAccessToken ...
  /**
   * Request Specific Scope Access Token for API Actions
   *
   * @param scope the specific api scope
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public requestScopeAccessToken(
    scope: XApiScope,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTokenResponseDto>;
  public requestScopeAccessToken(
    scope: XApiScope,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTokenResponseDto>>;
  public requestScopeAccessToken(
    scope: XApiScope,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTokenResponseDto>>;
  public requestScopeAccessToken(
    scope: XApiScope,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addCustomHeader(headers, {
      key: XHeader.Scope,
      value: scope,
    });

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RequestScopeAccessToken);

    //
    // return result ...
    return this.httpClient.post<XTokenResponseDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Authenticate ...
  /**
   * Authenticate a User
   *
   * @param body an instance of XLoginRequest class which holds UserName and Password
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public authenticate(
    body: XLoginRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTokenResponseDto>;
  public authenticate(
    body: XLoginRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTokenResponseDto>>;
  public authenticate(
    body: XLoginRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTokenResponseDto>>;
  public authenticate(
    body: XLoginRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body);
    XValidators.validateNotEmpty(body.password, body.userSelectBy);

    //
    if (this.stateSnapshot && this.stateSnapshot.isLoggedIn) {
      throwException(XExceptionIDs.MustLogout);
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Authenticate);

    //
    // return result ...
    return this.httpClient.post<XTokenResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Login ...
  /**
   * Login a User
   *
   * @param body an instance of XLoginRequest class which holds UserName and Password
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public login(
    body: XLoginRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XLoginResponseDto>;
  public login(
    body: XLoginRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XLoginResponseDto>>;
  public login(
    body: XLoginRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XLoginResponseDto>>;
  public login(
    body: XLoginRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body, body.device);
    XValidators.validateNotEmpty(
      body.password,
      body.userSelectBy,
      body.language
    );

    //
    if (this.stateSnapshot && this.stateSnapshot.isLoggedIn) {
      throwException(XExceptionIDs.MustLogout);
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Login);

    //
    // return result ...
    return this.httpClient
      .post<XLoginResponseDto>(endPointPath, body, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe,
        reportProgress,
      })
      .pipe(
        concatMap((res) => {
          //
          // Convert Login Response ...
          const mResponse = fromJson<XLoginResponseDto>(res);

          //
          // Prepare XUserAccountInfo instance ...
          const mUserInfo: XUserAccountInfo = {
            ...mResponse,
            userSelectBy: body.userSelectBy,
          };

          //
          // Update User Account Info ...
          return of(
            this.addOrUpdateUserAccount(mUserInfo.userSelectBy, mUserInfo, true)
          ).pipe(map((_) => mUserInfo));
        }),
        //
        // set User Account in  API Config ...
        concatMap((res) => {
          return of(this.apiConfig.setUserAccount(res)).pipe(map((_) => res));
        })
      );
  }
  //#endregion

  //
  //#region RefreshTokens ...
  /**
   * Refresh Expired Tokens
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public refreshTokens(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTokenResponseDto>;
  public refreshTokens(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTokenResponseDto>>;
  public refreshTokens(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTokenResponseDto>>;
  public refreshTokens(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    const tokens = this.retrieveTokens();
    headers = this.addAuthentication(headers, tokens);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RefreshTokens);

    //
    // return result ...
    return this.httpClient
      .post<XTokenResponseDto>(endPointPath, null, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe,
        reportProgress,
      })
      .pipe(
        concatMap((res) => {
          //
          // Convert Login Response ...
          const mResponse = fromJson<XTokenResponseDto>(res);

          //
          // Prepare XUserAccountInfo instance ...
          const mUserInfo: XUserAccountInfo = {
            ...mResponse,
            profile: this.stateSnapshot.profile,
            userSelectBy: this.stateSnapshot.userSelectBy,
          };

          //
          // Update User Account Info ...
          return of(
            this.addOrUpdateUserAccount(mUserInfo.userSelectBy, mUserInfo, true)
          ).pipe(
            map((_) => {
              return {
                userInfo: mUserInfo,
                response: mResponse,
              };
            })
          );
        }),
        //
        // set User Account in  API Config ...
        concatMap((res) => {
          return of(this.apiConfig.setUserAccount(res.userInfo)).pipe(
            map((_) => res.response)
          );
        })
      );
  }

  /**
   * Refresh Expired Tokens
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public refreshTokensOnly(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTokenResponseDto>;
  public refreshTokensOnly(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTokenResponseDto>>;
  public refreshTokensOnly(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTokenResponseDto>>;
  public refreshTokensOnly(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    const tokens = this.retrieveTokens();
    headers = this.addAuthentication(headers, tokens);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RefreshTokens);

    //
    // return result ...
    return this.httpClient
      .post<XTokenResponseDto>(endPointPath, null, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe,
        reportProgress,
      });
  }
  //#endregion

  //
  //#region Validate ...
  /**
   * Validate Revision Checksum
   *
   * @param revision token renew Revision
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public validateRevision(
    revision: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public validateRevision(
    revision: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public validateRevision(
    revision: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public validateRevision(
    revision: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    XValidators.validateNotEmpty(revision);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Validate);

    //
    // return result ...
    return this.httpClient.post<boolean>(
      endPointPath,
      { revision },
      {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe,
        reportProgress,
      }
    );
  }
  //#endregion

  //
  //#region Logout ...
  /**
   * Logout User ...
   */
  public async logout(returnUrl?: string) {
    //
    const isLoggedIn = await this.isLoggedIn();
    if (!isLoggedIn) {
      throwException(XExceptionIDs.NotAllowed);
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Logout);

    //
    // return result ...
    try {
      //
      // Try Call Logout ...
      await toPromise(
        this.httpClient.post<void>(endPointPath, null, {
          withCredentials: this.apiConfig.withCredentials,
          headers,
        })
      );
    } catch {}

    //
    const defUserId = await this.getDefaultUserIdentifier();
    XValidators.validateNotEmpty(defUserId);

    //
    const defUser = await this.getDefaultUser();
    XValidators.validateNotNull(defUser);

    //
    await this.removeDefaultUser(true);

    //
    if (!isNullOrEmptyString(returnUrl)) {
      this.router.navigateByUrl(returnUrl);
    }
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.base.service.ts

import {
  keys,
  getKeys,
  hasChild,
  fromJson,
  getArrayOf,
  XValidators,
  toObservable,
  XExceptionIDs,
  throwException,
  toNormalString,
  getErrorException,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  XAccountState,
  XUserAccountInfo,
  XUserAccountInfoIndex,
} from '../typings/x-account.typings';
import { Inject } from '@angular/core';
import {
  X_API_CONFIG,
  X_FRAMEWORK_IDENTITY_SDK_CONFIG,
} from '../tokens/x-injectable-tokens';
import {
  XAccountEndPoint,
  XAccountEndPointParam,
} from './../typings/x-endpoint.typings';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { XManagerService } from 'x-framework-services';
import { XUserProfileDto } from '../models/x-user.dto';
import { map, concatMap, filter } from 'rxjs/operators';
import { XBaseApiService } from '../base/x-base-api.service';
import { XAccountStorageKeys } from '../constants/x-account.keys';
import { XApiConfiguration } from '../config/x-api-service.config';
import { validateUserAccountInfo } from '../helpers/x-account.helper';
import { XLoginResponseDto, XTokenResponseDto } from '../models/x-login.dto';
import { XFrameworkIdentitySDKConfig } from '../config/x-framework-identity-sdk.config';

export abstract class XAccountBaseService extends XBaseApiService {
  //
  stateSnapshot: XAccountState;
  state$ = new BehaviorSubject<XAccountState>(null);

  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    config: XFrameworkIdentitySDKConfig,
    @Inject(X_API_CONFIG) configuration: XApiConfiguration,
    protected managerService: XManagerService
  ) {
    //
    super('Account', false, false, httpClient, config, configuration);

    //
    // handle initial state
    toObservable(this.currentState())
      .pipe(
        filter(
          (state) =>
            !isNullOrUndefined(state) &&
            !isNullOrUndefined(state.profile) &&
            !isNullOrEmptyString(state.userSelectBy) &&
            !isNullOrEmptyString(state.accessToken) &&
            !isNullOrEmptyString(state.refreshToken)
        ),
        concatMap((state) => {
          return toObservable(this.isExpired()).pipe(
            map((isExpired) => {
              return {
                state,
                isExpired,
              };
            })
          );
        }),
        concatMap((info) => {
          if (!!info.isExpired) {
            return toObservable(this.refreshCurrentToken()).pipe(
              concatMap(() => {
                return toObservable(this.currentState()).pipe(
                  map((newState) => {
                    return {
                      ...info,
                      state: {
                        ...newState,
                      },
                    };
                  })
                );
              })
            );
          } else {
            return of(info);
          }
        })
      )
      .subscribe((info) => {
        this.state$.next(info.state);
      });
  }
  //#endregion

  //
  //#region Service Actions ...
  /**
   *
   * @returns string message ...
   */
  public hi(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Hi);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   *
   * @returns string message ...
   */
  public passRequireXPowered(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.PassRequireXPowered);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * API Read Scope
   * @returns string message ...
   */
  public passReadAccess(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.PassReadAccess);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * API Write Scope
   * @returns string message ...
   */
  public passWriteAccess(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.PassWriteAccess);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * API Admin Scope
   * @returns string message ...
   */
  public passAdminAccess(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.PassAdminAccess);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * API Manage Scop
   * @returns string message ...
   */
  public passManageAccess(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.PassManageAccess);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * a simple Action which returns a List of Authenticated User Claims
   * @returns string message which represent current user's claims ...
   */
  public hiClaims(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.HiClaims);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * a simple Hello User for Checking Authentication and Policy
   * @returns string message which contains authenticated user name ...
   */
  public hiUser(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.HiUser);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * a simple Hello User for Checking Authentication and Policy
   * @returns string message which contains authenticated user name ...
   */
  public hiEnabledUser(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.HiEnabledUser);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * a simple Hello User for Checking Authentication and Policy
   * @returns string message which contains authenticated user name ...
   */
  public hiAgent(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.HiAgent);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * a simple Hello User for Checking Authentication and Policy
   * @returns string message which contains authenticated user name ...
   */
  public hiEnabledAgent(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.HiEnabledAgent);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * a simple Hello User for Checking Authentication and Policy
   * @returns string message which contains authenticated user name ...
   */
  public hiAdmin(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.HiAdmin);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }

  /**
   * a simple Hello User for Checking Authentication and Policy
   * @returns string message which contains authenticated user name ...
   */
  public hiEnabledAdmin(): Observable<string> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addAuthentication(headers);

    //
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.HiEnabledAdmin);

    //
    // return result ...
    return this.httpClient
      .get<string>(endPointPath, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe: 'body',
        reportProgress: false,
      })
      .pipe(map((res) => fromJson<string>(res)));
  }
  //#endregion

  //
  //#region Account Handler ...
  /**
   * retrieve current user tokens ...
   *
   * @returns an instance of XTokenResponse
   */
  public retrieveTokens(): XTokenResponseDto {
    //
    if (isNullOrUndefined(this.stateSnapshot)) {
      return null;
    }

    //
    const result: XTokenResponseDto = {
      accessToken: this.stateSnapshot.accessToken,
      refreshToken: this.stateSnapshot.refreshToken,
      expiresAt: this.stateSnapshot.expiresAt,
    };

    //
    return result;
  }

  /**
   * reNew Account State ...
   */
  public async reNewState(state?: XAccountState): Promise<void> {
    //
    const currState = await this.currentState();
    this.state$.next({
      ...currState,
      ...state,
    });

    //
    this.apiConfig.setUserAccount(currState);
  }

  /**
   * retrieve current Account State ...
   */
  public async currentState(): Promise<XAccountState> {
    //
    let isLoggedIn = false;
    let defaultUser = await this.getDefaultUser();
    if (!defaultUser) {
      //
      // Making Default State
      defaultUser = {
        userSelectBy: '',
        accessToken: '',
        refreshToken: '',
        expiresAt: -1,
        profile: null,
      };
    } else {
      isLoggedIn = true;
    }

    //
    const mCurrentState = {
      isLoggedIn,
      ...defaultUser,
    } as XAccountState;

    //
    this.stateSnapshot = mCurrentState;
    this.apiConfig.setUserAccount(mCurrentState);

    //
    return mCurrentState;
  }

  /**
   * Validate Token Responses with recieved revision ...
   *
   * @param model the model which going to validate
   * @param revision the recieved revision
   */
  public validateLoginResponseRevision(
    model: XLoginResponseDto,
    revision: string
  ): boolean {
    //
    const source =
      model.accessToken +
      this.apiConfig.revisionSecretKey +
      model.refreshToken +
      this.apiConfig.revisionSecretKey +
      model.expiresAt.toString();

    //
    return !isNullOrUndefined(model) &&
      !isNullOrEmptyString(revision) &&
      !isNullOrEmptyString(model.accessToken) &&
      !isNullOrEmptyString(model.refreshToken) &&
      model.expiresAt > -1
      ? this.managerService.securityService.toMd5(source) === revision
      : false;
  }

  //
  //#region IsLoggedIn ...
  public async isLoggedIn(): Promise<boolean> {
    //
    const currState = await this.currentState();

    //
    return currState.isLoggedIn;
  }

  public async isExpired(): Promise<boolean> {
    //
    const defaultUser = await this.getDefaultUser();
    if (!defaultUser) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    let expiredAt = defaultUser.expiresAt;
    const currentDate = new Date().getTime();

    //
    // Fix different length ...
    const expiredAtStr = expiredAt.toString();
    const currentDateStr = currentDate.toString();
    const lengthDiff = currentDateStr.length - expiredAtStr.length;
    if (lengthDiff > 0) {
      expiredAt = expiredAt * Math.pow(10, lengthDiff);
    }

    //
    return currentDate >= expiredAt;
  }
  //#endregion

  //
  //#region Refresh ...
  /**
   * refresh expired token ...
   */
  public refreshCurrentToken() {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    const tokens = this.retrieveTokens();
    headers = this.addAuthentication(headers, tokens);

    //
    const observe: any = 'body';
    const reportProgress: boolean = false;

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RefreshTokens);

    //
    // return result ...
    return this.httpClient
      .post<XTokenResponseDto>(endPointPath, null, {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe,
        reportProgress,
      })
      .pipe(
        concatMap((res) => {
          //
          // Convert Login Response ...
          const mResponse = fromJson<XTokenResponseDto>(res);

          //
          // Prepare XUserAccountInfo instance ...
          const mUserInfo: XUserAccountInfo = {
            ...mResponse,
            profile: this.stateSnapshot.profile,
            userSelectBy: this.stateSnapshot.userSelectBy,
          };

          //
          // Update User Account Info ...
          return of(
            this.addOrUpdateUserAccount(mUserInfo.userSelectBy, mUserInfo, true)
          ).pipe(
            map((_) => {
              return {
                userInfo: mUserInfo,
                response: mResponse,
              };
            })
          );
        }),
        //
        // set User Account in  API Config ...
        concatMap((res) => {
          return of(this.apiConfig.setUserAccount(res.userInfo)).pipe(
            map((_) => res.response)
          );
        })
      );
  }
  //#endregion

  //
  //#region Account Info Handlers ...
  /**
   * check a User Accounts Exists or not ...
   *
   * @param userSelectBy user identifier
   */
  public async hasUserAccount(userSelectBy: string): Promise<boolean> {
    //
    XValidators.validateNotEmpty(userSelectBy);

    //
    userSelectBy = toNormalString(userSelectBy);

    //
    const accounts = await this.getAccounts();
    if (!accounts) {
      return false;
    }

    //
    const userIdentifiers = keys(accounts);
    if (!hasChild(userIdentifiers)) {
      return false;
    }

    //
    const result =
      userIdentifiers.findIndex((i) => toNormalString(i) === userSelectBy) > -1;

    //
    return result;
  }

  /**
   * retrieve specific user account
   *
   * @param userSelectBy user identifier
   */
  public async getUserAccount(userSelectBy: string): Promise<XUserAccountInfo> {
    //
    XValidators.validateNotEmpty(userSelectBy);

    //
    userSelectBy = toNormalString(userSelectBy);

    //
    const isExists = await this.hasUserAccount(userSelectBy);
    if (!isExists) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    const accounts = await this.getAccountsAsArray();
    if (!hasChild(accounts)) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    const result = accounts.find(
      (a) => toNormalString(a.userSelectBy) === userSelectBy
    );

    //
    return result;
  }

  /**
   * Retrieve user info by it's token's ...
   *
   * @param info the user tokens info
   */
  public async getUserByToken(
    info: XLoginResponseDto
  ): Promise<XUserAccountInfo> {
    //
    const accounts = await this.getAccountsAsArray();
    if (!hasChild(accounts)) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    const account = accounts.find(
      (a) =>
        a.accessToken === info.accessToken &&
        a.refreshToken === info.refreshToken &&
        a.expiresAt === info.expiresAt
    );
    if (!accounts) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    return account;
  }

  /**
   * add new user account ...
   *
   * @param userSelectBy user identifier
   * @param accountInfo user logged in account info
   */
  public async addUserAccount(
    userSelectBy: string,
    accountInfo: XUserAccountInfo,
    setAsDefault?: boolean
  ): Promise<void> {
    //
    XValidators.validateNotEmpty(userSelectBy);
    validateUserAccountInfo(accountInfo);

    //
    const isExists = await this.hasUserAccount(userSelectBy);
    if (isExists) {
      throwException(XExceptionIDs.Duplicate);
    }

    //
    const numOfAccounts = await this.countAccounts();
    if (numOfAccounts === 0) {
      setAsDefault = true;
    }

    //
    const accounts = await this.getAccounts();
    accounts[userSelectBy] = accountInfo;
    await this.updateAccounts(accounts);

    //
    if (setAsDefault) {
      await this.setDefaultUser(userSelectBy);
    }

    //
    await this.reNewState();
  }

  /**
   * update exists user account info ...
   *
   * @param userSelectBy user identifier
   * @param accountInfo user logged in account info
   */
  public async updateUserAccount(
    userSelectBy: string,
    accountInfo: XUserAccountInfo,
    setAsDefault?: boolean
  ): Promise<void> {
    //
    XValidators.validateNotEmpty(userSelectBy);
    validateUserAccountInfo(accountInfo);

    //
    const isExists = await this.hasUserAccount(userSelectBy);
    if (!isExists) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    const accounts = await this.getAccounts();
    accounts[userSelectBy] = accountInfo;
    await this.updateAccounts(accounts);

    //
    if (setAsDefault) {
      await this.setDefaultUser(userSelectBy);
    }

    //
    await this.reNewState();
  }

  /**
   * Update an Existing Profile to User's Storage ...
   *
   * @param profile Updated Profile to Save ...
   * @returns
   */
  public async updateUserProfile(profile: XUserProfileDto): Promise<void> {
    //
    XValidators.validateNotNull(profile);

    //
    const defaultUser = await this.getDefaultUser();
    if (
      !defaultUser ||
      (defaultUser && !defaultUser.profile) ||
      (defaultUser &&
        defaultUser.profile &&
        defaultUser.profile.userId !== profile.userId)
    ) {
      return;
    }

    //
    defaultUser.profile = profile;
    await this.addOrUpdateUserAccount(defaultUser.userSelectBy, defaultUser);
  }

  /**
   * add new/ update exists user account ...
   *
   * @param userSelectBy user identifier
   * @param accountInfo user logged in account info
   */
  public async addOrUpdateUserAccount(
    userSelectBy: string,
    accountInfo: XUserAccountInfo,
    setAsDefault?: boolean
  ): Promise<void> {
    //
    XValidators.validateNotEmpty(userSelectBy);
    validateUserAccountInfo(accountInfo);

    //
    const isExists = await this.hasUserAccount(userSelectBy);
    if (!isExists) {
      await this.addUserAccount(userSelectBy, accountInfo, setAsDefault);
    } else {
      await this.updateUserAccount(userSelectBy, accountInfo, setAsDefault);
    }

    //
    await this.reNewState();
  }

  /**
   * Update User's Refreshed Token ...
   *
   * @param oldInfo user's old token's info ...
   * @param newInfo new user's token info which returned after token refreshing ...
   */
  public async updateUserTokens(
    oldInfo: XLoginResponseDto,
    newInfo: XTokenResponseDto
  ): Promise<void>;
  public async updateUserTokens(
    oldInfo: XLoginResponseDto,
    newInfo: XLoginResponseDto
  ): Promise<void> {
    //
    const count = await this.countAccounts();
    if (count === 0) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    const accounts = await this.getAccountsAsArray();

    //
    const account = accounts.find(
      (a) =>
        a.accessToken === oldInfo.accessToken &&
        a.refreshToken === oldInfo.refreshToken &&
        a.expiresAt === oldInfo.expiresAt
    );
    if (!account) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    account.accessToken = newInfo.accessToken;
    account.refreshToken = newInfo.refreshToken;
    account.expiresAt = newInfo.expiresAt;

    //
    await this.updateUserAccount(account.userSelectBy, account);
    await this.reNewState();
  }

  /**
   * remove exists user account ...
   *
   * @param userSelectBy user identifier
   */
  public async removeUserAccount(userSelectBy: string): Promise<void> {
    //
    XValidators.validateNotEmpty(userSelectBy);

    //
    userSelectBy = toNormalString(userSelectBy);

    //
    const isExists = await this.hasUserAccount(userSelectBy);
    if (!isExists) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    const accounts = await this.getAccountsAsArray();
    const updatedAccounts = accounts.filter(
      (a) => toNormalString(a.userSelectBy) !== userSelectBy
    );

    //
    const isDefaultUser = await this.isDefaultUser(userSelectBy);
    if (isDefaultUser) {
      await this.removeDefaultUser();
      await this.reNewState();
    }

    //
    const updateAcountIndex: XUserAccountInfoIndex = {};
    updatedAccounts.forEach((a) => {
      updateAcountIndex[a.userSelectBy] = a;
    });

    //
    await this.updateAccounts(updateAcountIndex);
  }

  /**
   * Check a User Identifier is Defualt User or not
   */
  public async isDefaultUser(userSelectBy: string): Promise<boolean> {
    //
    XValidators.validateNotEmpty(userSelectBy);

    //
    userSelectBy = toNormalString(userSelectBy);

    //
    const defId = await this.getDefaultUserIdentifier();
    if (isNullOrEmptyString(defId)) {
      return false;
    }

    //
    const result = toNormalString(defId) === userSelectBy;

    //
    return result;
  }

  /**
   * read default user account identifier ...
   */
  public async getDefaultUserIdentifier(): Promise<string> {
    //
    const result = this.managerService.secureStorageService.readOfType<string>(
      XAccountStorageKeys.DefaultUser,
      false
    );

    //
    return result;
  }

  /**
   * retrieve default user account info
   */
  public async getDefaultUser(): Promise<XUserAccountInfo> {
    //
    const defaultUserIdentifier = await this.getDefaultUserIdentifier();
    if (isNullOrEmptyString(defaultUserIdentifier)) {
      return null;
    }

    //
    const result = await this.getUserAccount(defaultUserIdentifier);

    //
    return result;
  }

  public async getDefaultUserTokens(): Promise<XLoginResponseDto> {
    //
    const defaultUser = await this.getDefaultUser();
    if (!defaultUser) {
      throw getErrorException(XExceptionIDs.NotFound);
    } else {
      //
      const result: XLoginResponseDto = {
        accessToken: defaultUser.accessToken,
        refreshToken: defaultUser.refreshToken,
        expiresAt: defaultUser.expiresAt,
        profile: defaultUser.profile,
      };

      //
      return result;
    }
  }

  /**
   * set a user as default user ...
   *
   * @param userSelectBy user identifier
   */
  public async setDefaultUser(userSelectBy: string): Promise<void> {
    //
    XValidators.validateNotEmpty(userSelectBy);

    //
    const isExists = await this.hasUserAccount(userSelectBy);
    if (!isExists) {
      throwException(XExceptionIDs.NotFound);
    }

    //
    this.managerService.secureStorageService.write(
      XAccountStorageKeys.DefaultUser,
      userSelectBy,
      true
    );

    //
    await this.reNewState();
  }

  /**
   * Remove default user account
   */
  public async removeDefaultUser(forceRemoveUser?: boolean): Promise<void> {
    //
    const defId = await this.getDefaultUserIdentifier();
    if (isNullOrEmptyString(defId)) {
      return;
    }

    //
    this.managerService.secureStorageService.remove(
      XAccountStorageKeys.DefaultUser,
      false
    );

    //
    if (forceRemoveUser) {
      const isExists = await this.hasUserAccount(defId);
      if (isExists) {
        await this.removeUserAccount(defId);
      }
    }

    //
    const accounts = await this.getAccountsAsArray();
    if (hasChild(accounts)) {
      await this.setDefaultUser(accounts[0].userSelectBy);
    }

    //
    await this.reNewState();
  }

  /**
   * count all exists accounts
   */
  public async countAccounts(): Promise<number> {
    //
    const accounts = await this.getAccountsAsArray();

    //
    let result = 0;
    if (!hasChild(accounts)) {
      return result;
    }

    //
    result = accounts.length;
    return result;
  }

  /**
   * retrieve all exists accounts
   */
  public async getAccounts(): Promise<XUserAccountInfoIndex> {
    //
    const result =
      this.managerService.secureStorageService.readOfType<XUserAccountInfoIndex>(
        XAccountStorageKeys.UserInfos,
        false
      ) || {};

    //
    return result;
  }

  /**
   * update user Accounts ...
   *
   * @param model updated Accounts
   */
  public async updateAccounts(model: XUserAccountInfoIndex): Promise<void> {
    //
    XValidators.validateNotNull(model);

    //
    await this.removeAccounts();

    //
    this.managerService.secureStorageService.write(
      XAccountStorageKeys.UserInfos,
      model,
      true
    );
  }

  /**
   * get user accounts info as Array
   */
  public async getAccountsAsArray(): Promise<XUserAccountInfo[]> {
    //
    const accounts = await this.getAccounts();
    const result = getArrayOf(accounts) || [];

    //
    return result;
  }

  /**
   * Remove All user Accounts
   */
  public async removeAccounts(forceReNewState?: boolean): Promise<void> {
    //
    this.managerService.secureStorageService.remove(
      XAccountStorageKeys.UserInfos,
      false
    );

    //
    if (forceReNewState) {
      await this.reNewState();
    }
  }

  /**
   * reset All Account Infos
   */
  public async resetAccounts(): Promise<void> {
    //
    const storageKeys = getKeys(XAccountStorageKeys);

    //
    storageKeys.forEach((k) => {
      this.managerService.secureStorageService.remove(k, false);
    });

    //
    await this.reNewState();
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.final.service.ts

import { Observable, of } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { isNullOrUndefined, notValue } from 'x-framework-core';
import { XAccountSearchService } from './x-account.search.service';

export abstract class XAccountFinalService extends XAccountSearchService {
  //
  //#region Provider Actions ...
  /**
   * check a user id is same as current user id or not ...
   * @param userId dest user id's
   */
  isMe(userId?: string): Observable<boolean> {
    //
    if (!userId) {
      return of(false);
    }

    //
    return this.state$.pipe(
      filter((res) => !isNullOrUndefined(res)),
      map(
        (state) =>
          state.profile.email === userId ||
          state.profile.userId === userId ||
          state.profile.userName === userId ||
          state.profile.phoneNumber === userId
      )
    );
  }

  /**
   * check a user id is not same as current user id or not ...
   * @param userId dest user id's
   */
  isNotMe(userId: string): Observable<boolean> {
    return notValue(this.isMe(userId));
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.friendship.service.ts

import { Observable } from 'rxjs';
import {
  XFriendshipState,
  XFriendshipInfoDto,
  XFriendshipFollowerDto,
  XFriendshipFollowingDto,
} from '../models/x-friendship.dto';
import {
  XAccountEndPoint,
  XAccountEndPointParam,
} from '../typings/x-endpoint.typings';
import { XFriendDto } from '../models/x-friend-dto';
import { HttpEvent, HttpResponse } from '@angular/common/http';
import { XQueryDto, XQueryResultDto } from '../models/x-query.dto';
import { isNullOrEmptyString, XValidators } from 'x-framework-core';
import { XAccountProfileService } from './x-account.profile.service';

export abstract class XAccountFriendshipService extends XAccountProfileService {
  //
  //#region Follow ...
  /**
   * Follow a User
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public follow(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipFollowingDto>;
  public follow(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipFollowingDto>>;
  public follow(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipFollowingDto>>;
  public follow(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Follow, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return response ...
    return this.httpClient.post<XFriendshipFollowingDto>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Cancel ...
  /**
   * Cancel Following
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public cancel(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public cancel(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public cancel(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public cancel(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Cancel, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return response ...
    return this.httpClient.post<boolean>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region UnFollowFollower ...
  /**
   * Unfollow a Follower
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public unFollowFollower(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public unFollowFollower(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public unFollowFollower(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public unFollowFollower(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.UnFollowFollower, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // Result ...
    return this.httpClient.post<void>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region UnFollowFollowing ...
  /**
   * Unfollow Following
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public unFollowFollowing(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public unFollowFollowing(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public unFollowFollowing(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public unFollowFollowing(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.UnFollowFollowing, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return result ...
    return this.httpClient.post<void>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Block ...
  /**
   * Block a Follower
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public block(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipFollowingDto>;
  public block(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipFollowingDto>>;
  public block(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipFollowingDto>>;
  public block(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Block, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return response ...
    return this.httpClient.post<XFriendshipFollowingDto>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region UnBlock ...
  /**
   * Unblock a Blocked User
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public unBlock(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipFollowingDto>;
  public unBlock(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipFollowingDto>>;
  public unBlock(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipFollowingDto>>;
  public unBlock(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.UnBlock, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // Resut ...
    return this.httpClient.post<XFriendshipFollowingDto>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AcceptRequest ...
  /**
   * Accept a Following Request
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public accept(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipFollowerDto>;
  public accept(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipFollowerDto>>;
  public accept(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipFollowerDto>>;
  public accept(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.AcceptRequest, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return response ...
    return this.httpClient.post<XFriendshipFollowerDto>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RejectRequest ...
  /**
   * Reject a Following Request
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public reject(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipFollowerDto>;
  public reject(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipFollowerDto>>;
  public reject(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipFollowerDto>>;
  public reject(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RejectRequest, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // Result ...
    return this.httpClient.post<XFriendshipFollowerDto>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FriendshipInfo ...
  /**
   * Get Friendship Info Model between Specific User and Current User
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public friendshipInfo(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipInfoDto>;
  public friendshipInfo(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipInfoDto>>;
  public friendshipInfo(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipInfoDto>>;
  public friendshipInfo(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.FriendshipInfo, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<XFriendshipInfoDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region IsFollower ...
  /**
   * Check a User IsFollower of Requested User
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public isFollower(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public isFollower(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public isFollower(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public isFollower(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.IsFollower, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // Return result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FollowerState ...
  /**
   * Get Follower State of a User
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public followerState(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipState>;
  public followerState(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipState>>;
  public followerState(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipState>>;
  public followerState(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.FollowerState, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return response ...
    return this.httpClient.get<XFriendshipState>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Follower ...
  /**
   * Get Specific Follower
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public follower(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipFollowerDto>;
  public follower(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipFollowerDto>>;
  public follower(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipFollowerDto>>;
  public follower(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Follower, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return response ...
    return this.httpClient.get<XFriendshipFollowerDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Followers ...
  /**
   * Get Followers List Of Current User
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public followers(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFriendshipFollowerDto>>;
  public followers(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFriendshipFollowerDto>>>;
  public followers(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFriendshipFollowerDto>>>;
  public followers(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Followers);

    //
    // return result ...
    return this.httpClient.get<Array<XFriendshipFollowerDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AllFollowers ...
  /**
   * Get All Followers List Includes Blocked, Requested and etc  of Current User
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public allFollowers(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFriendshipFollowerDto>>;
  public allFollowers(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFriendshipFollowerDto>>>;
  public allFollowers(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFriendshipFollowerDto>>>;
  public allFollowers(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.AllFollowers);

    //
    // return response ...
    return this.httpClient.get<Array<XFriendshipFollowerDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FollowersList ...
  /**
   * Return Followers UserName&#x27;s List of Current User
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public followersList(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<string>>;
  public followersList(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<string>>>;
  public followersList(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<string>>>;
  public followersList(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.FollowersList);

    //
    // return result ...
    return this.httpClient.get<Array<string>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryFollowers ...
  /**
   * query Followers
   *
   * @param query an instance of XQuery interface which provide projectio data
   * @param destUser a User for retrieve it's Friend Info ...
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public queryFollowers(
    query?: XQueryDto,
    destUser?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XFriendDto>>;
  public queryFollowers(
    query?: XQueryDto,
    destUser?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XFriendDto>>>;
  public queryFollowers(
    query?: XQueryDto,
    destUser?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XFriendDto>>>;
  public queryFollowers(
    query?: XQueryDto,
    destUser?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    let params = this.generateXQueryHttpParams(query);

    //
    // Attach DestUser to Query Params if Provided ...
    if (!isNullOrEmptyString(destUser)) {
      params = this.addCustomParam(params, {
        key: 'destUser',
        value: destUser,
      });
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.QueryFollowers);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XFriendDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      params,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region IsFollowing ...
  /**
   * Check a User is in Followings of Current User
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public isFollowing(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public isFollowing(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public isFollowing(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public isFollowing(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.IsFollowing, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // Result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FollowingState ...
  /**
   * Get Following State Relation between Specific User  and Current User
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public followingState(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipState>;
  public followingState(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipState>>;
  public followingState(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipState>>;
  public followingState(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.FollowingState, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return result ...
    return this.httpClient.get<XFriendshipState>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Following ...
  /**
   * Get Specific Following Model
   *
   * @param destUser selected dest User
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public following(
    destUser: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFriendshipFollowingDto>;
  public following(
    destUser: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFriendshipFollowingDto>>;
  public following(
    destUser: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFriendshipFollowingDto>>;
  public following(
    destUser: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(destUser);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Following, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: destUser,
    });

    //
    // return result ...
    return this.httpClient.get<XFriendshipFollowingDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Followings ...
  /**
   * Get Followings of Current User
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public followings(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFriendshipFollowingDto>>;
  public followings(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFriendshipFollowingDto>>>;
  public followings(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFriendshipFollowingDto>>>;
  public followings(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Followings);

    //
    // return result ...
    return this.httpClient.get<Array<XFriendshipFollowingDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AllFollowings ...
  /**
   * Get All Following List Includes Blocked, Requested and etc  of Current User
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public allFollowings(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFriendshipFollowingDto>>;
  public allFollowings(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFriendshipFollowingDto>>>;
  public allFollowings(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFriendshipFollowingDto>>>;
  public allFollowings(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.AllFollowings);

    //
    // return response ...
    return this.httpClient.get<Array<XFriendshipFollowingDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FollowingsList ...
  /**
   * Return Following UserName's List of Current User
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public followingsList(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<string>>;
  public followingsList(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<string>>>;
  public followingsList(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<string>>>;
  public followingsList(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.FollowingsList);

    //
    // return result ...
    return this.httpClient.get<Array<string>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryFollowings ...
  /**
   * query Followings
   *
   * @param query an instance of XQuery interface which provide projectio data
   * @param destUser a User for retrieve it's Friend Info ...
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public queryFollowings(
    query?: XQueryDto,
    destUser?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XFriendDto>>;
  public queryFollowings(
    query?: XQueryDto,
    destUser?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XFriendDto>>>;
  public queryFollowings(
    query?: XQueryDto,
    destUser?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XFriendDto>>>;
  public queryFollowings(
    query?: XQueryDto,
    destUser?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    let params = this.generateXQueryHttpParams(query);

    //
    // Attach DestUser to Query Params if Provided ...
    if (!isNullOrEmptyString(destUser)) {
      params = this.addCustomParam(params, {
        key: 'destUser',
        value: destUser,
      });
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.QueryFollowings);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XFriendDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      params,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.profile.service.ts

import {
  XavatarDto,
  XUserProfileDto,
  XUserNameIdRequestDto,
  XUserNameIdResponseDto,
  XProfileUpdateRequestDto,
} from '../models/x-user.dto';
import { Observable } from 'rxjs';
import {
  XAccountEndPoint,
  XAccountEndPointParam,
} from '../typings/x-endpoint.typings';
import { XHeader, XValidators } from 'x-framework-core';
import { HttpResponse, HttpEvent } from '@angular/common/http';
import { XQueryDto, XQueryResultDto } from '../models/x-query.dto';
import { XAccountAuthenticationService } from './x-account.authentication.service';

export abstract class XAccountProfileService extends XAccountAuthenticationService {
  //
  //#region GetNames ...
  /**
   * Get UserName's Related to a Collection of user identifiers
   *
   * @param ids selected user identifiers
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public getNames(
    ids: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<string[]>;
  public getNames(
    ids: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<string[]>>;
  public getNames(
    ids: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<string[]>>;
  public getNames(
    ids: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotEmpty(ids);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.GetNames, {
      key: XAccountEndPointParam.XIds,
      value: ids,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<string[]>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetNameIds ...
  /**
   * Get UserName's Related to a Collection of user id's
   *
   * @param model selected user identifiers
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public getNameIds(
    model: XUserNameIdRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserNameIdResponseDto[]>;
  public getNameIds(
    model: XUserNameIdRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserNameIdResponseDto[]>>;
  public getNameIds(
    model: XUserNameIdRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserNameIdResponseDto[]>>;
  public getNameIds(
    model: XUserNameIdRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(model);
    XValidators.validateHasChilds(model.ids);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.GetNameIds);

    //
    // Prepare Result ...
    return this.httpClient.post<XUserNameIdResponseDto[]>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Profile ...
  /**
   * Get Profile Object of Specific User
   *
   * @param userSelectBy selected user identifier
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public getProfile(
    userSelectBy: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserProfileDto>;
  public getProfile(
    userSelectByParam: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserProfileDto>>;
  public getProfile(
    userSelectByParam: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserProfileDto>>;
  public getProfile(
    userSelectByParam: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotEmpty(userSelectByParam);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.Profile, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: userSelectByParam,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<XUserProfileDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryProfiles ...
  /**
   * query user profiles
   *
   * @param query an instance of XQuery interface which provide projectio data
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public queryProfiles(
    query?: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XUserProfileDto>>;
  public queryProfiles(
    query?: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XUserProfileDto>>>;
  public queryProfiles(
    query?: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XUserProfileDto>>>;
  public queryProfiles(
    query?: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    const queryParameters = this.generateXQueryHttpParams(query);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.QueryProfiles);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XUserProfileDto>>(endPointPath, {
      params: queryParameters,
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryAvatars ...
  /**
   * query specific users avatars ...
   *
   * @param userSelectByParam user identifier
   * @param query an instance of XQuery interface which provide projectio data
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public queryAvatars(
    userSelectByParam?: string,
    query?: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XavatarDto>>;
  public queryAvatars(
    userSelectByParam?: string,
    query?: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XavatarDto>>>;
  public queryAvatars(
    userSelectByParam?: string,
    query?: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XavatarDto>>>;
  public queryAvatars(
    userSelectByParam?: string,
    query?: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    const queryParameters = this.generateXQueryHttpParams(query);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.QueryAvatars, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: userSelectByParam,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XavatarDto>>(endPointPath, {
      params: queryParameters,
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ProfileUpdate ...
  /**
   * Update Specific User's Profile
   *
   * @param userSelectByParam selected user identifier
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public updateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserProfileDto>;
  public updateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserProfileDto>>;
  public updateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserProfileDto>>;
  public updateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotEmpty(userSelectByParam);
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.ProfileUpdate, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: userSelectByParam,
    });

    //
    // Prepare Result ...
    return this.httpClient.post<XUserProfileDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FullProfileUpdate ...
  /**
   * Update Specific User's Profile
   *
   * @param userSelectByParam selected user identifier
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public fullUpdateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserProfileDto>;
  public fullUpdateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserProfileDto>>;
  public fullUpdateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserProfileDto>>;
  public fullUpdateProfile(
    userSelectByParam: string,
    body: XProfileUpdateRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotEmpty(userSelectByParam);
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.FullProfileUpdate, {
      key: XAccountEndPointParam.XUserSelectByParam,
      value: userSelectByParam,
    });

    //
    // Prepare Result ...
    return this.httpClient.post<XUserProfileDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddAvatar ...
  /**
   * Add a New Profile Image
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public addAvatar(
    body: File,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserProfileDto>;
  public addAvatar(
    body: File,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserProfileDto>>;
  public addAvatar(
    body: File,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserProfileDto>>;
  public addAvatar(
    body: File,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    const formData: FormData = new FormData();
    formData.append(XHeader.File, body, body.name);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.AddAvatar);

    //
    // Prepare Result ...
    return this.httpClient.post<XUserProfileDto>(endPointPath, formData, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }

  //#endregion

  //
  //#region AddAvatars ...
  /**
   * Add a Collection of Profile Images
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public addAvatars(
    body: File[],
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserProfileDto>;
  public addAvatars(
    body: File[],
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserProfileDto>>;
  public addAvatars(
    body: File[],
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserProfileDto>>;
  public addAvatars(
    body: File[],
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateHasChilds(body);

    //
    const formData: FormData = new FormData();
    body.forEach((f) => {
      formData.append(XHeader.Files, f, f.name);
    });

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.AddAvatars);

    //
    // Prepare Result ...
    return this.httpClient.post<XUserProfileDto>(endPointPath, formData, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region SetAvatar ...
  /**
   * set Specified Profile Image as Avatar
   *
   * @param id profile image id
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public setAvatar(
    id: number,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserProfileDto>;
  public setAvatar(
    id: number,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserProfileDto>>;
  public setAvatar(
    id: number,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserProfileDto>>;
  public setAvatar(
    id: number,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(id);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.SetAvatar, {
      key: XAccountEndPointParam.XId,
      value: id.toString(),
    });

    //
    // Prepare Result ...
    return this.httpClient.post<XUserProfileDto>(endPointPath, null, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RemoveAvatars ...
  /**
   * Remove Profile Images
   *
   * @param ids profile image id's which need's to remove
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public removeAvatars(
    ids: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XUserProfileDto>;
  public removeAvatars(
    ids: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XUserProfileDto>>;
  public removeAvatars(
    ids: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XUserProfileDto>>;
  public removeAvatars(
    ids: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotEmpty(ids);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RemoveAvatars, {
      key: XAccountEndPointParam.XIds,
      value: ids,
    });

    //
    // Prepare Result ...
    return this.httpClient.delete<XUserProfileDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.registration.service.ts

import { of } from 'rxjs';
import { Observable } from 'rxjs';
import {
  XActionRequestDto,
  XActionResponseDto,
} from '../models/x-registration-dto';
import {
  XAccountEndPoint,
  XAccountEndPointParam,
} from '../typings/x-endpoint.typings';
import { HttpEvent, HttpResponse } from '@angular/common/http';
import { XHeader, XCountryCode, XValidators } from 'x-framework-core';
import { XAccountFriendshipService } from './x-account.friendship.service';

export abstract class XAccountRegistrationService extends XAccountFriendshipService {
  //
  //#region IsConfirmedEmail ...
  /**
   *  Check User is Confirmed Email or not
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public isConfirmedEmail(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public isConfirmedEmail(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public isConfirmedEmail(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public isConfirmedEmail(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.IsConfirmedEmail);

    //
    // return result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region IsConfirmedMobile ...
  /**
   *  Check User is Confirmed Mobile or not
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public isConfirmedMobile(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public isConfirmedMobile(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public isConfirmedMobile(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public isConfirmedMobile(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.IsConfirmedMobile);

    //
    // return result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region CanRegisterUserName ...
  /**
   * Check a UserName is Available For Registration or not
   *
   * @param userName an string value which represent desired username
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public canRegisterUserName(
    userName?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public canRegisterUserName(
    userName?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public canRegisterUserName(
    userName?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public canRegisterUserName(
    userName?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    try {
      XValidators.validateNotEmpty(userName);
    } catch {
      return of(false);
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.CanRegisterUserName, {
      key: XAccountEndPointParam.XUserName,
      value: userName,
    });

    //
    // return result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region CanRegisterMobileNumber ...
  /**
   * Check a Mobile Number is Available For Registration or not
   *
   * @param mobileNumber an string value which represent desired mobile number
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public canRegisterMobileNumber(
    mobileNumber?: string,
    defaultCountryCode?: XCountryCode,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public canRegisterMobileNumber(
    mobileNumber?: string,
    defaultCountryCode?: XCountryCode,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public canRegisterMobileNumber(
    mobileNumber?: string,
    defaultCountryCode?: XCountryCode,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public canRegisterMobileNumber(
    mobileNumber?: string,
    defaultCountryCode?: XCountryCode,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    try {
      XValidators.validateNotEmpty(mobileNumber);
      XValidators.validatePhoneNumber(
        mobileNumber,
        defaultCountryCode || this.config.defaultCountryCode
      );
    } catch {
      return of(false);
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.CanRegisterMobileNumber, {
      key: XAccountEndPointParam.XMobileNumber,
      value: mobileNumber,
    });

    //
    // return result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region CanRegisterEmail ...
  /**
   * Check a Email Address is Available For Registration or not
   *
   * @param email an string value which represent desired email address
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public canRegisterEmail(
    email?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public canRegisterEmail(
    email?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public canRegisterEmail(
    email?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public canRegisterEmail(
    email?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    try {
      XValidators.validateNotEmpty(email);
      XValidators.validateEmailAddress(email);
    } catch {
      return of(false);
    }

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.CanRegisterEmail, {
      key: XAccountEndPointParam.XEmail,
      value: email,
    });

    //
    // return result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RequestConfirmEmail ...
  /**
   * Request For Email Address Change/ Confirm
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public requestConfirmEmail(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public requestConfirmEmail(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public requestConfirmEmail(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public requestConfirmEmail(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RequestConfirmEmail);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RequestConfirmMobile ...
  /**
   * Request For Mobile Number Change/ Confirm
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public requestConfirmMobile(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public requestConfirmMobile(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public requestConfirmMobile(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public requestConfirmMobile(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RequestConfirmMobile);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RequestResetPassword ...
  /**
   * Request Reset Password Action
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public requestResetPassword(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public requestResetPassword(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public requestResetPassword(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public requestResetPassword(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RequestResetPassword);

    //
    // Prepare Result ...
    return this.httpClient.post<Blob>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RequestConfirmRegistration ...
  /**
   * Request Registration Confirm
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public requestConfirmRegistration(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public requestConfirmRegistration(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public requestConfirmRegistration(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public requestConfirmRegistration(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RequestConfirmRegistration);

    //
    // Prepare Result ...
    return this.httpClient.post<Blob>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ConfirmRegistration ...
  /**
   * Confirm Registration ...
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public confirmRegistration(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public confirmRegistration(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public confirmRegistration(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public confirmRegistration(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.ConfirmRegistration);

    //
    // Prepare Result ...
    return this.httpClient.post<Blob>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ConfirmEmailAddress ...
  /**
   * Confirm Email Address
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public confirmEmail(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public confirmEmail(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public confirmEmail(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public confirmEmail(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.ConfirmEmailAddress);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ConfirmMobileNumber ...
  /**
   * Confirm Mobile Number
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public confirmMobile(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public confirmMobile(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public confirmMobile(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public confirmMobile(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.ConfirmMobileNumber);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region InviteUser ...
  /**
   * Invite a User to Register on Dashboard
   *
   * @param body action request object
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public invite(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public invite(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public invite(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public invite(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.InviteUser);

    //
    // return result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RequestRegistration ...
  /**
   * Recieve some Basic Informations and Start Registration Proccess if they Valid   Registration Proccess Starts with Invoking this Action
   *
   * @param body action request object
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public requestRegistration(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public requestRegistration(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public requestRegistration(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public requestRegistration(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.RequestRegistration);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddAccountInfo ...
  /**
   * Add User Account Informations
   *
   * @param body action request object
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public addAccountInfo(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public addAccountInfo(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public addAccountInfo(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public addAccountInfo(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.AddAccountInfo);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AttachProfileImage ...
  /**
   * Upload and Attach a Profile Image for User
   *
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public attachProfileImage(
    body: File,
    actionToken: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public attachProfileImage(
    body: File,
    actionToken: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public attachProfileImage(
    body: File,
    actionToken: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public attachProfileImage(
    body: File,
    actionToken: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);
    XValidators.validateNotEmpty(actionToken);

    //
    const formData: FormData = new FormData();
    formData.append(XHeader.File, body, body.name);
    formData.append(XHeader.ActionToken, actionToken);

    //
    // Instantiiate Headers from Default Headers ...
    const headers = this.defaultHeaders;

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.AttachProfileImage);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, formData, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FinishRegistration ...
  /**
   * Finish Registrationn Proccess
   *
   * @param body action request object
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public finishRegistration(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public finishRegistration(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public finishRegistration(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public finishRegistration(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.FinishRegistration);

    //
    // Prepare Result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ChangePassword ...
  /**
   * Change a User's Password
   *
   * @param body an instance of XActionRequestDto class which provider requirement for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public changePassword(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XActionResponseDto>;
  public changePassword(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XActionResponseDto>>;
  public changePassword(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XActionResponseDto>>;
  public changePassword(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body, body.device);
    XValidators.validateNotEmpty(
      body.lang,
      body.password,
      body.newPassword,
      body.returnUrl
    );

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.ChangePassword);

    //
    // return result ...
    return this.httpClient.post<XActionResponseDto>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ResetPassword ...
  /**
   * Reset Password
   *
   * @param body request for action
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public resetPassword(
    body: XActionRequestDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public resetPassword(
    body: XActionRequestDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public resetPassword(
    body: XActionRequestDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public resetPassword(
    body: XActionRequestDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate ARgs ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.ResetPassword);

    //
    // Prepare Result ...
    return this.httpClient.post<Blob>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\partial\x-account.search.service.ts

import { Observable } from 'rxjs';
import {
  XAccountEndPoint,
  XAccountEndPointParam,
} from '../typings/x-endpoint.typings';
import { XUserProfileDto } from '../models/x-user.dto';
import { HttpEvent, HttpResponse } from '@angular/common/http';
import { XAccountAdminService } from './x-account.admin.service';
import { XQueryDto, XQueryResultDto } from '../models/x-query.dto';

export abstract class XAccountSearchService extends XAccountAdminService {
  //
  //#region QueryOpenToSearchProfiles ...
  /**
   * query user profiles
   *
   * @param query an instance of XQuery interface which provide projectio data
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  public queryOpenToSearchProfiles(
    query?: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XUserProfileDto>>;
  public queryOpenToSearchProfiles(
    query?: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XUserProfileDto>>>;
  public queryOpenToSearchProfiles(
    query?: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XUserProfileDto>>>;
  public queryOpenToSearchProfiles(
    query?: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    const queryParameters = this.generateXQueryHttpParams(query);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XAccountEndPoint,
      XAccountEndPointParam
    >(XAccountEndPoint.QueryOpenToSearchProfiles);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XUserProfileDto>>(endPointPath, {
      params: queryParameters,
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\providers\x-url.encoder.ts

import { HttpUrlEncodingCodec } from '@angular/common/http';

export class XHttpUrlEncodingCodec extends HttpUrlEncodingCodec {
  encodeKey(k: string): string {
    k = super.encodeKey(k);
    return k.replace(/\+/gi, '%2B');
  }
  encodeValue(v: string): string {
    v = super.encodeValue(v);
    return v.replace(/\+/gi, '%2B');
  }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\services\api-http-interceptor.service.ts

import {
  XHeader,
  isObject,
  countChild,
  findAllIndex,
  toObservable,
  XBaseService,
  XExceptionIDs,
  getErrorException,
  XStringPlaceHolder,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  HttpEvent,
  HttpRequest,
  HttpHandler,
  HttpEventType,
  HttpInterceptor,
  HttpErrorResponse,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { Injectable, Inject } from '@angular/core';
import { XManagerService } from 'x-framework-services';
import { XAccountService } from './../x-account.service';
import { XLoginResponseDto } from '../models/x-login.dto';
import { finalize, catchError, concatMap, map } from 'rxjs/operators';
import { X_FRAMEWORK_IDENTITY_SDK_CONFIG } from '../tokens/x-injectable-tokens';
import { XFrameworkIdentitySDKConfig } from '../config/x-framework-identity-sdk.config';

@Injectable({
  providedIn: 'root',
})
export class ApiHttpInterceptorService
  extends XBaseService
  implements HttpInterceptor
{
  //
  private isRefreshing = false;

  //
  constructor(
    private authService: XAccountService,
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    config: XFrameworkIdentitySDKConfig,
    private managerService: XManagerService
  ) {
    super(config);
  }

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return this.handleInterceptRequest(req, next);
  }

  handleInterceptRequest(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    //
    // Adding Identifier ...
    req = this.applyHeadersToRequest(req);

    //
    // Apply RefreshToken Handler ...
    const handledRefreshToken = !this.isRefreshing
      ? this.applyRefreshTokenHandler(next.handle(req), req, next)
      : next.handle(req);
    // const handledRefreshToken = next.handle(req);

    //
    // Apply Response Headers Handler ...
    const handledResponseHeaders =
      this.applyResponseHandler(handledRefreshToken);

    //
    // Apply Error Handler ...
    const handledErrors = this.applyErrorHandler(handledResponseHeaders);

    //
    // Apply Finally Handler ...
    const handledFinally = this.applyFinally(handledErrors);

    //
    // Final Level ...
    const result = handledFinally;

    //
    return result;
  }

  //
  //#region Actions / Handlers ...
  applyHeadersToRequest(request: HttpRequest<any>): HttpRequest<any> {
    return request.clone({
      setHeaders: {
        XRegisteredTo: `${this.config.poweredValue}`,
      },
    });
  }

  applyFinally(
    current: Observable<HttpEvent<any>>
  ): Observable<HttpEvent<any>> {
    //
    return current.pipe(
      finalize(() => {
        //
        // Collection of instructions after finish or error ...
        this.isRefreshing = false;
        this.managerService.loading = false;
      })
    );
  }

  applyRefreshTokenHandler(
    current: Observable<HttpEvent<any>>,
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    //
    return current.pipe(
      catchError((error) => {
        //
        if (error instanceof HttpErrorResponse && error.status === 401) {
          this.logError('401 => ', error);

          //
          const isExpired$ = toObservable(this.authService.isExpired());

          //
          return isExpired$.pipe(
            concatMap((isExpired) => {
              if (isExpired) {
                return this.handleRefreshToken(req, next);
              } else {
                return throwError(error);
              }
            })
          );
        } else {
          return throwError(error);
        }
      })
    );
  }

  applyResponseHandler(
    current: Observable<HttpEvent<any>>
  ): Observable<HttpEvent<any>> {
    //
    return current.pipe(
      map((event: HttpEvent<any>) => {
        // this.handleResponseHeaders(event);
        return event;
      })
    );
  }

  applyErrorHandler(
    current: Observable<HttpEvent<any>>
  ): Observable<HttpEvent<any>> {
    return current.pipe(
      catchError((error: HttpErrorResponse) => {
        //
        this.managerService.loading = false;
        const mException = getErrorException(error.error);

        //
        // Check mException contains string formatter place holder or not ...
        if (mException.message.includes(XStringPlaceHolder)) {
          //
          // try to retrieve place holder contents ...
          const placeHolderIndexes = findAllIndex(
            mException.message,
            XStringPlaceHolder
          );
          const countOfPlaceHolders = countChild(placeHolderIndexes);

          //
          // retrieve place holder content from message ...
          const placeHolderContents: string[] = [];
          let placeHolderContent =
            error.error && isObject(error.error)
              ? (error.error.message as string)
              : '';
          if (
            !isNullOrEmptyString(placeHolderContent) &&
            placeHolderContent.includes(':')
          ) {
            //
            placeHolderContent = placeHolderContent
              .substring(placeHolderContent.indexOf(':') + 1)
              .trim();

            //
            if (countOfPlaceHolders > 1 && placeHolderContent.includes(',')) {
              placeHolderContents.push(...placeHolderContent.split(','));
            } else {
              placeHolderContents.push(placeHolderContent);
            }
          }

          //
          // now we can fix and add place holder params to message of mException using stringFormatter function ...
          mException.payload = [...placeHolderContents];
        }

        //
        this.managerService.error = mException;

        //
        this.logError('HttpInterceptor: ', error, mException);

        //
        return throwError(mException);
      })
    );
  }

  handleRefreshToken(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    //
    if (!this.isRefreshing) {
      this.isRefreshing = true;

      //
      return this.authService.state$.pipe(
        concatMap((accountState) => {
          return this.authService.refreshTokens().pipe(
            map((loginResponse) => {
              return {
                accountState,
                loginResponse,
              };
            })
          );
        }),
        concatMap((accountInfo) => {
          //
          this.logWarn('Login Refresh Response: ', accountInfo.loginResponse);

          //
          let headers = this.authService.defaultHeaders;
          headers = this.authService.addAuthentication(
            headers,
            accountInfo.loginResponse
          );
          headers = Object.assign(req.headers, headers);

          //
          req = req.clone({
            headers,
          });

          //
          // Update User Account ...
          const updateAccount$ = toObservable(
            this.authService.updateUserTokens(
              accountInfo.accountState,
              accountInfo.loginResponse
            )
          );

          //
          return updateAccount$.pipe(
            concatMap(() => {
              return next
                .handle(req)
                .pipe(finalize(() => (this.isRefreshing = false)));
            })
          );
        })
      );
    } else {
      return this.handleRefreshToken(req, next);
    }
  }

  async handleResponseHeaders(event: HttpEvent<any>): Promise<void> {
    //
    if (event.type === HttpEventType.Response) {
      //
      const headers = event.headers;

      //
      const isContainsNewAuthentication =
        headers.has(XHeader.Authorization) &&
        headers.has(XHeader.RefreshToken) &&
        headers.has(XHeader.ExpiresAt) &&
        headers.has(XHeader.RevisionChecksum);

      //
      if (isContainsNewAuthentication) {
        //
        const oldTokens = await this.authService.getDefaultUserTokens();

        //
        const accessToken = headers
          .get(XHeader.Authorization)
          .replace(XHeader.AuthorizationPrefix, '');
        const refreshToken = headers.get(XHeader.RefreshToken);
        const expiresAt = +headers.get(XHeader.ExpiresAt);
        const revisionChecksum = headers.get(XHeader.RevisionChecksum);

        //
        const profile = oldTokens.profile;

        //
        const newTokens: XLoginResponseDto = {
          accessToken,
          refreshToken,
          expiresAt,
          profile,
        };

        //
        const isValid = this.authService.validateLoginResponseRevision(
          newTokens,
          revisionChecksum
        );

        //
        if (isValid) {
          await this.authService.updateUserTokens(oldTokens, newTokens);
        } else {
          //
          this.managerService.notificationService.presentErrorNotification({
            exception: XExceptionIDs.InvalidToken,
            dissmissable: true,
          });

          //
          await this.authService.logout();
        }
      }
    }
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\tokens\x-injectable-tokens.ts

import { InjectionToken } from '@angular/core';
import { XApiConfiguration } from '../config/x-api-service.config';
import { XFrameworkIdentitySDKConfig } from '../config/x-framework-identity-sdk.config';

export const X_FRAMEWORK_IDENTITY_SDK_CONFIG = new InjectionToken<XFrameworkIdentitySDKConfig>(
  'x_config'
);

export const X_API_CONFIG = new InjectionToken<XApiConfiguration>(
  'apiConfiguration'
);

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\tools\x-endpoint.tools.ts

import {
  values,
  toArray,
  hasChild,
  XKeyValue,
  XOneOrManyType,
  isNullOrEmptyString,
} from 'x-framework-core';
import { XAccountEndPointParam } from '../typings/x-endpoint.typings';

export function isContainsParams(
  route: string,
  params?: XOneOrManyType<XKeyValue<any, string>>
) {
  //
  // Validate Args ...
  if (isNullOrEmptyString(route)) {
    return false;
  }

  //
  const paramValues = values(XAccountEndPointParam) as Array<string>;
  if (!hasChild(paramValues)) {
    return false;
  }

  //
  let result = paramValues.some((param) => route.includes(param));
  if (!result) {
    //
    const paramsArr = toArray(params).map((p) => p.key) as Array<string>;
    if (!hasChild(paramsArr)) {
      return false;
    }

    //
    result = paramsArr.some((param) => route.includes(param));
  }

  //
  return result;
}

export function setParams<TParams>(
  route: string,
  params?: XOneOrManyType<XKeyValue<TParams, string>>
) {
  //
  // Validate Args ...
  if (
    !hasChild(params) ||
    !isContainsParams(route, params) ||
    isNullOrEmptyString(route)
  ) {
    return route;
  }

  //
  // Do Actions ...
  toArray(params).forEach((paramKeyValue) => {
    //
    route = route.replace(
      String(paramKeyValue.key),
      encodeURIComponent(String(paramKeyValue.value))
    );
  });

  //
  return route;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\typings\x-account.typings.ts

import { XLoginResponseDto } from '../models/x-login.dto';

export interface XUserAccountInfo extends XLoginResponseDto {
  userSelectBy: string;
}

export interface XUserAccountInfoIndex {
  [userSelectBy: string]: XUserAccountInfo;
}

export interface XAccountState extends XUserAccountInfo {
  isLoggedIn: boolean;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\typings\x-endpoint.typings.ts

export enum XEndPoint {
  Account,
}

export type XEndPoints = keyof typeof XEndPoint | string;

/**
 * prepare all Route Params which used in Account Services Endpoints ...
 */
export enum XAccountEndPointParam {
  XId = '{xId}',
  XIds = '{xIds}',
  XEmail = '{xEmail}',
  XUserName = '{xUserName}',
  XMobileNumber = '{xMobileNumber}',
  XUserSelectByParam = '{xUserSelectByParam}',
}

export type XAccountEndPointParams = keyof typeof XAccountEndPointParam;

export enum XAccountEndPoint {
  //
  //#region Test ...
  Hi = 'Test/Hi',
  PassReadAccess = 'Test/PassReadAccess',
  PassWriteAccess = 'Test/PassWriteAccess',
  PassAdminAccess = 'Test/PassAdminAccess',
  PassManageAccess = 'Test/PassManageAccess',
  PassRequireXPowered = 'Test/PassRequireXPowered',
  HiClaims = 'Test/HiClaims',
  HiUser = 'Test/HiUser',
  HiEnabledUser = 'Test/HiEnabledUser',
  HiColleague = 'Test/HiColleague',
  HiEnabledColleague = 'Test/HiEnabledColleague',
  HiAgent = 'Test/HiAgent',
  HiEnabledAgent = 'Test/HiEnabledAdmingent',
  HiAdmin = 'Test/HiAdmin',
  HiEnabledAdmin = 'Test/HiEnabledAdmin',
  //#endregion

  //
  //#region Admin ...
  Ban = 'Ban',
  UnBan = 'UnBan',
  IsBanned = 'IsBanned/{xUserSelectByParam}',
  //#endregion

  //
  //#region Authentication ...
  DiscoveryDocument = 'DiscoveryDocument',
  RequestScopeAccessToken = 'RequestScopeAccessToken',
  Login = 'Login',
  Logout = 'Logout',
  Authenticate = 'Authenticate',
  RefreshTokens = 'RefreshTokens',
  Validate = 'Validate',
  //#endregion

  //
  //#region Registration ...
  IsConfirmedEmail = 'IsConfirmedEmail',
  IsConfirmedMobile = 'IsConfirmedMobile',
  CanRegisterUserName = 'CanRegisterUserName/{xUserName}',
  CanRegisterMobileNumber = 'CanRegisterMobileNumber/{xMobileNumber}',
  CanRegisterEmail = 'CanRegisterEmail/{xEmail}',
  RequestConfirmEmail = 'RequestConfirmEmail',
  RequestConfirmMobile = 'RequestConfirmMobile',
  RequestResetPassword = 'RequestResetPassword',
  RequestConfirmRegistration = 'RequestConfirmRegistration',
  ChangePassword = 'ChangePassword',
  ResetPassword = 'ResetPassword',
  ConfirmRegistration = 'ConfirmRegistration',
  ConfirmEmailAddress = 'ConfirmEmailAddress',
  ConfirmMobileNumber = 'ConfirmMobileNumber',
  InviteUser = 'InviteUser',
  RequestRegistration = 'RequestRegistration',
  AddAccountInfo = 'AddAccountInfo',
  AttachProfileImage = 'AttachProfileImage',
  FinishRegistration = 'FinishRegistration',
  //#endregion

  //
  //#region Friendship ...
  Follow = 'Friendship/{xUserSelectByParam}/Follow',
  Cancel = 'Friendship/{xUserSelectByParam}/Cancel',
  UnFollowFollower = 'Friendship/{xUserSelectByParam}/UnFollowFollower',
  UnFollowFollowing = 'Friendship/{xUserSelectByParam}/UnFollowFollowing',
  Block = 'Friendship/{xUserSelectByParam}/Block',
  UnBlock = 'Friendship/{xUserSelectByParam}/UnBlock',
  AcceptRequest = 'Friendship/{xUserSelectByParam}/AcceptRequest',
  RejectRequest = 'Friendship/{xUserSelectByParam}/RejectRequest',
  FriendshipInfo = 'Friendship/{xUserSelectByParam}/FriendshipInfo',
  IsFollower = 'Friendship/{xUserSelectByParam}/IsFollower',
  Follower = 'Friendship/{xUserSelectByParam}/Follower',
  FollowerState = 'Friendship/{xUserSelectByParam}/FollowerState',
  Followers = 'Friendship/Followers',
  AllFollowers = 'Friendship/AllFollowers',
  FollowersList = 'Friendship/FollowersList',
  QueryFollowers = 'Friendship/QueryFollowers',
  IsFollowing = 'Friendship/{xUserSelectByParam}/IsFollowing',
  Following = 'Friendship/{xUserSelectByParam}/Following',
  FollowingState = 'Friendship/{xUserSelectByParam}/FollowingState',
  Followings = 'Friendship/Followings',
  AllFollowings = 'Friendship/AllFollowings',
  FollowingsList = 'Friendship/FollowingsList',
  QueryFollowings = 'Friendship/QueryFollowings',
  //#endregion

  //
  //#region Profile ...
  GetNames = 'Profile/{xIds}/GetNames',
  GetNameIds = 'Profile/GetNameIds',
  Profile = 'Profile/{xUserSelectByParam}',
  QueryProfiles = 'Profile/Query',
  QueryAvatars = 'Profile/Avatars/Query/{xUserSelectByParam}',
  ProfileUpdate = 'Profile/Update/{xUserSelectByParam}',
  FullProfileUpdate = 'Profile/{xUserSelectByParam}',
  AddAvatar = 'Profile/Avatar',
  AddAvatars = 'Profile/Avatars',
  SetAvatar = 'Profile/Avatars/{xId}/Set',
  RemoveAvatars = 'Profile/Avatars/{xIds}',
  //#endregion

  //
  //#region Search ...
  QueryOpenToSearchProfiles = 'OpenToSearch/Query',
  //#endregion
}

export type XAccountEndPoints = keyof typeof XAccountEndPoint;

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\typings\x-registration.typings.ts

export enum RegistrationStep {
  Terms = 'terms',
  Info = 'info',
  MobileConfirmation = 'mobile_confirmation',
  EmailConfirmation = 'email_confirmation',
  Avatar = 'avatar',
  Finish = 'finish'
}

export type RegistrationStepIdentifier = RegistrationStep | string;

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkIdentitySDKHolder\projects\x-framework-identity-sdk\src\lib\validators\api-validators.ts

import {
  tap,
  concatMap,
  debounceTime,
  distinctUntilChanged,
} from 'rxjs/operators';
import {
  ValidatorFn,
  AbstractControl,
  AsyncValidatorFn,
  ValidationErrors,
} from '@angular/forms';
import {
  applyLocale,
  XResourceIDs,
  XCountryCode,
  hasUniqueChar,
  stringFormatter,
  isNullOrEmptyString,
  normalizePhoneNumber,
} from 'x-framework-core';
import { Subject, of, Observable } from 'rxjs';
import { Injectable, Inject } from '@angular/core';
import { XAccountService } from '../x-account.service';
import { XLocalizationService } from 'x-framework-services';
import { X_FRAMEWORK_IDENTITY_SDK_CONFIG } from '../tokens/x-injectable-tokens';
import { XFrameworkIdentitySDKConfig } from '../config/x-framework-identity-sdk.config';

export interface XPasswordValidationErrorObject {
  //
  requireDigit?: boolean;
  requireDigitErr?: boolean;

  //
  requiredLength?: number;
  requiredLengthErr?: boolean;

  //
  requiredUniqueChars?: number;
  requiredUniqueCharsErr?: boolean;

  //
  requireLowercase?: boolean;
  requireLowercaseErr?: boolean;

  //
  requireNonAlphanumeric?: boolean;
  requireNonAlphanumericErr?: boolean;

  //
  requireUppercase?: boolean;
  requireUppercaseErr?: boolean;
}

export interface XPasswordValidatorError {
  xPasswordValidator: XPasswordValidationErrorObject | null;
}

@Injectable({
  providedIn: 'root',
})
export class ApiValidators {
  //
  //#region Props ...
  //
  private userNameErrorObject = {
    userNameValidator: true,
  };

  //
  private emailErrorObject = {
    emailValidator: true,
  };

  //
  private mobileErrorObject = {
    mobileValidator: true,
  };

  //
  private passwordErrorObject: XPasswordValidatorError = {
    xPasswordValidator: {
      //
      requireDigit: true,
      requireDigitErr: false,

      //
      requiredLength: 0,
      requiredLengthErr: false,

      //
      requiredUniqueChars: 0,
      requiredUniqueCharsErr: false,

      //
      requireLowercase: true,
      requireLowercaseErr: false,

      //
      requireNonAlphanumeric: true,
      requireNonAlphanumericErr: false,

      //
      requireUppercase: true,
      requireUppercaseErr: false,
    },
  };

  //
  public loading$ = new Subject<boolean>();
  //#endregion

  //
  //#region Constructor ...
  constructor(
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    private config: XFrameworkIdentitySDKConfig,
    private accountService: XAccountService,
    private localizationService: XLocalizationService
  ) {}
  //#endregion

  //
  //#region Validators ...
  passwordValidator(): ValidatorFn {
    //
    const validatorFn = (control: AbstractControl): ValidationErrors | null => {
      //
      // Check Password Configs ...
      if (!this.config || !this.config.passwordPolicies) {
        return null;
      }

      //
      const pswPolicies = this.config.passwordPolicies;

      //
      const errObj: XPasswordValidatorError = {
        ...this.passwordErrorObject,
        xPasswordValidator: {
          ...this.passwordErrorObject.xPasswordValidator,
          ...pswPolicies,
        },
      };

      //
      const value = control && control.value ? (control.value as string) : null;

      //
      // Required Length ...
      if (pswPolicies.requiredLength) {
        //
        const isLengthPassed =
          value && value.length >= pswPolicies.requiredLength;

        //
        if (!isLengthPassed) {
          //
          errObj.xPasswordValidator.requiredLengthErr = true;

          //
          return errObj;
        }
      }

      //
      // Required Digit ...
      if (pswPolicies.requireDigit) {
        //
        const containsDigitRegExp = new RegExp('(?=.*[0-9])');
        const isRequiredDigitPassed = containsDigitRegExp.test(value);

        //
        if (!isRequiredDigitPassed) {
          //
          errObj.xPasswordValidator.requireDigitErr = true;

          //
          return errObj;
        }
      }

      //
      // Required LowerCase ...
      if (pswPolicies.requireLowercase) {
        //
        const containsLowerCaseRegExp = new RegExp('(?=.*[a-z])');
        const isRequiredLowercasePassed = containsLowerCaseRegExp.test(value);

        //
        if (!isRequiredLowercasePassed) {
          //
          errObj.xPasswordValidator.requireLowercaseErr = true;

          //
          return errObj;
        }
      }

      //
      // Required UpperCase ...
      if (pswPolicies.requireUppercase) {
        //
        const containsUpperCaseRegExp = new RegExp('(?=.*[A-Z])');
        const isRequiredUppercasePassed = containsUpperCaseRegExp.test(value);

        //
        if (!isRequiredUppercasePassed) {
          //
          errObj.xPasswordValidator.requireUppercaseErr = true;

          //
          return errObj;
        }
      }

      //
      // Required NonAlphabet/Special Char ...
      if (pswPolicies.requireNonAlphanumeric) {
        //
        const containsSpecialCharsRegExp = new RegExp('(?=.*[!@#$%^&*])');
        const isRequiredSpecialCharsPassed =
          containsSpecialCharsRegExp.test(value);

        //
        if (!isRequiredSpecialCharsPassed) {
          //
          errObj.xPasswordValidator.requireNonAlphanumericErr = true;

          //
          return errObj;
        }
      }

      //
      // Required Unique Char ...
      if (pswPolicies.requiredUniqueChars) {
        //
        const isRequiredUniqueCharPassed = hasUniqueChar(value);

        //
        if (!isRequiredUniqueCharPassed) {
          //
          errObj.xPasswordValidator.requiredUniqueCharsErr = true;

          //
          return errObj;
        }
      }

      //
      return null;
    };

    //
    return validatorFn;
  }

  emailValidator(): AsyncValidatorFn {
    //
    const validatorFn = (
      control: AbstractControl
    ): Observable<ValidationErrors | null> => {
      //
      const value = control && control.value ? (control.value as string) : null;

      //
      return of(null).pipe(
        tap((_) => this.loading$.next(true)),
        debounceTime(this.config.debounceTime),
        distinctUntilChanged(),
        concatMap((_) => this.accountService.canRegisterEmail(value)),
        concatMap((canRegister) =>
          canRegister ? of(null) : of(this.emailErrorObject)
        ),
        tap((_) => this.loading$.next(false))
      );
    };

    //
    return validatorFn;
  }

  mobileNumberValidator(defaultCountryCode?: XCountryCode): AsyncValidatorFn {
    //
    const validatorFn = (
      control: AbstractControl
    ): Observable<ValidationErrors | null> => {
      //
      const value = control && control.value ? (control.value as string) : null;
      const normalValue = normalizePhoneNumber(value, defaultCountryCode);

      //
      return of(null).pipe(
        tap((_) => this.loading$.next(true)),
        debounceTime(this.config.debounceTime),
        distinctUntilChanged(),
        concatMap((_) =>
          this.accountService.canRegisterMobileNumber(normalValue.toString())
        ),
        concatMap((canRegister) =>
          canRegister ? of(null) : of(this.mobileErrorObject)
        ),
        tap((_) => this.loading$.next(false))
      );
    };

    //
    return validatorFn;
  }

  userNameValidator(): AsyncValidatorFn {
    //
    const validatorFn = (
      control: AbstractControl
    ): Observable<ValidationErrors | null> => {
      //
      const value = control && control.value ? (control.value as string) : null;

      //
      return of(null).pipe(
        tap((_) => this.loading$.next(true)),
        debounceTime(this.config.debounceTime),
        distinctUntilChanged(),
        concatMap((_) => this.accountService.canRegisterUserName(value)),
        concatMap((canRegister) =>
          canRegister ? of(null) : of(this.userNameErrorObject)
        ),
        tap((_) => this.loading$.next(false))
      );
    };

    //
    return validatorFn;
  }
  //#endregion

  //
  //#region Data Providers ...
  /**
   * generate error message for password validation ...
   *
   * @param error the XPasswordValidationError instance ...
   */
  generatePasswordValidationError(error: XPasswordValidationErrorObject) {
    //
    if (!error) {
      return '';
    }

    //
    let errorMessage = '';

    //
    // Handle Required Length ...
    if (error.requiredLength > 0 && error.requiredLengthErr) {
      //
      errorMessage += !isNullOrEmptyString(errorMessage) ? '\n' : '';
      errorMessage += `${this.getRequiredLengthError(error.requiredLength)}`;
    }

    //
    // Handle Required UniqueChars ...
    else if (error.requiredUniqueChars > 0 && error.requiredUniqueCharsErr) {
      //
      errorMessage += !isNullOrEmptyString(errorMessage) ? '\n' : '';
      errorMessage += `${this.getRequiredUniqueChanrsError(
        error.requiredUniqueChars
      )}`;
    }

    //
    // Handle Required Digits ...
    else if (error.requireDigit && error.requireDigitErr) {
      //
      errorMessage += !isNullOrEmptyString(errorMessage) ? '\n' : '';
      errorMessage += `${this.getRequiredDigitsError()}`;
    }

    //
    // Handle Required LowerCase ...
    else if (error.requireLowercase && error.requireLowercaseErr) {
      //
      errorMessage += !isNullOrEmptyString(errorMessage) ? '\n' : '';
      errorMessage += `${this.getRequiredLowercaseError()}`;
    }

    //
    // Handle Required UpperCase ...
    else if (error.requireUppercase && error.requireUppercaseErr) {
      //
      errorMessage += !isNullOrEmptyString(errorMessage) ? '\n' : '';
      errorMessage += `${this.getRequiredUppercaseError()}`;
    }

    //
    // Handle Required NonAlphanumeric ...
    else if (error.requireNonAlphanumeric && error.requireNonAlphanumericErr) {
      //
      errorMessage += !isNullOrEmptyString(errorMessage) ? '\n' : '';
      errorMessage += `${this.getRequiredNonAlphanumericError()}`;
    }

    //
    return errorMessage;
  }
  //#endregion

  //
  //#region Private ...
  private getRequiredLengthError(length: number) {
    //
    const error = this.localizationService.getValue(
      XResourceIDs.required_length
    );

    //
    if (!error) {
      return '';
    }

    //
    return applyLocale(
      stringFormatter(error, length),
      this.localizationService.locale
    );
  }

  private getRequiredUniqueChanrsError(length: number) {
    //
    const error = this.localizationService.getValue(
      XResourceIDs.required_unique_chars
    );

    //
    if (!error) {
      return '';
    }

    //
    return applyLocale(
      stringFormatter(error, length),
      this.localizationService.locale
    );
  }

  private getRequiredDigitsError() {
    return this.localizationService.getValue(XResourceIDs.require_digit);
  }

  private getRequiredLowercaseError() {
    return this.localizationService.getValue(XResourceIDs.require_lowercase);
  }

  private getRequiredUppercaseError() {
    return this.localizationService.getValue(XResourceIDs.require_uppercase);
  }

  private getRequiredNonAlphanumericError() {
    return this.localizationService.getValue(
      XResourceIDs.require_non_alphanumeric
    );
  }
  //#endregion
}
