c.server.on(auth.ServerEvents.clientReady, (ev) => {
    ev.reply(
      loadTokensFromStore(api, ipc)
     ? auth.ClientEvents.loggedIn
      : auth.ClientEvents.loggedOut
    );
  });

  ipc.server.on(auth.ServerEvents.tryLogIn, (ev) => {
    if (loadTokensFromStore(api, ipc)) {
      ev.reply(auth.ClientEvents.loggedIn);
      return;
    }

    // Create child window to show authorise URL
    const authoriseURL = api.createAuthorizeURL(scopes, state);
    const child = new BrowserWindow({
      width: 600,
      height: 800,
      show: false,
      resizable: false,
      parent: window,
    });
    child.loadURL(authoriseURL);
    child.on('ready-to-show', () => {
      child.show();
      child.focus();
    });

    ev.reply(auth.ClientEvents.authoriseURL, JSON.stringify({ authoriseURL }));
  });

  ipc.server.on(auth.ServerEvents.tryLogOut, (ev) => {
    clearTokens(api);
    ev.reply(auth.ClientEvents.loggedOut);
  });

  ipc.server.on(auth.ServerEvents.authCodeReceived, (payload) => {
    const { code } = JSON.parse(payload);
    localConsole.info(`Received code: ${code}`);

    api.authorizationCodeGrant(code)
     .then(({ body }) => {

        const accessToken = body.access_token;
        const refreshToken = body.refresh_token;
        const expiresIn = body.expires_in;

        setAccessToken(api, accessToken);
        setRefreshToken(api, refreshToken);
        setExpiresIn(ipc, { seconds: expiresIn });

        ipc.client.send(auth.ClientEvents.loggedIn);
      })
     .catch(error => {
        localConsole.error(`Error at AuthCodeGrant: ${error}`);
        ipc.client.send(auth.ClientEvents.error, JSON.stringify({
          message: 'Please log in again',
        }));
      });
  });

  ipc.server.on(auth.ServerEvents.playbackError, (failedEvent, ev) => {
    localConsole.info(`Failed event: ${failedEvent}`);
    api.refreshAccessToken()
     .then(({ body }) => {
        localConsole.info('Access token refreshed');

        const accessToken = body[keys.accessToken];
        setAccessToken(api, accessToken);

        const seconds = body.expires_in
        const nowInMillis = Date.now();
        const deltaInMillis = seconds * 1000;
        const expiryInMillis = nowInMillis + deltaInMillis;
        setExpiresIn(ipc, expiryInMillis);

        if (failedEvent!== undefined) {
          ipc.server.emit(failedEvent, ev, true);
        }
      })
     .catch(error => {
        localConsole.error(error);
        ipc.client.send(auth.ClientEvents.error, JSON.stringify({
          message: 'Please log in again',
        }));
      });
  });

  ipc.server.on(auth.ServerEvents.fatalError, () => {
    ipc.client.send(auth.ClientEvents.error, JSON.stringify({
      message: 'Please log in again',
    }));
  });

  localConsole.info('Initialised');
}

function loadTokensFromStore(
  /** @type {SpotifyWebApi} */ api,
  /** @type {IPC}           */ ipc,
) {
  const accessToken = authStore.get(keys.accessToken);
  const refreshToken = authStore.get(keys.refreshToken);
  const expiresIn = authStore.get(keys.expiresIn);

  if (accessToken === undefined || refreshToken === undefined || expiresIn === undefined) {
    localConsole.info('No credentials in store');
    return false;
  }

  localConsole.info('Credentials in store');

  setAccessToken(api, accessToken);
  setRefreshToken(api, refreshToken);
  setExpiresIn(ipc, expiresIn);

  return true;
}

function setAccessToken(
  /** @type {SpotifyWebApi} */ api,
  /** @type {string}        */ token,
) {
  api.setAccessToken(token);

  authStore.set(keys.accessToken, token);
}

function setRefreshToken(
  /** @type {SpotifyWebApi} */ api,
  /** @type {string}        */ token,
) {
  api.setRefreshToken(token);

  authStore.set(keys.refreshToken, token);
}

function setExpiresIn(
  /** @type {IPC}    */ ipc,
  /** @type {number} */ expiryInMillis,
) { 
  const nowInMillis = Date.now();
  authStore.set(keys.expiresIn, expiryInMillis);

  const deltaInMillis = Math.max(expiryInMillis - nowInMillis, 0);
  localConsole.info(`Access token expires in (${deltaInMillis}): ${new Date(expiryInMillis).toUTCString()}`);
  clearTimeout(refreshHandle);

  refreshHandle = setTimeout(() => {
    ipc.server.emit(auth.ServerEvents.playbackError);
  }, deltaInMillis + 1);
}

function clearTokens(
  /** @type {SpotifyWebApi} */ api,
) {
  authStore.delete(keys.accessToken);
  authStore.delete(keys.refreshToken);
  authStore.delete(keys.expiresIn);
}

module.exports = handleAuthentication;Over the internet slot machine game model matches are actually characterized by quite confidential, competing, and also enjoyment persons. This approach conditional on your online internet casino of entirely, but yet most casinos have many bonuses for both of those current along with different participants. After you have excitement nearly all of the internets casino property video game titles, you will have to know the principles on the xbox game in advance of beginning. This approach led to an extra develop the true selection of people and then the public attention towards via the internet gambling. Any casino’s group of table game consists of 14 products and solutions, among them Caribbean roulette, Real real spanish roulette, pontoon, 3D-baccarat, and then Superior 6. Men and women will appreciate non-standard forms of gameplay headings several of these when Big event Roulette, Electrical a digital Roulette, Baronial Black-jack, Ti Roulette.
Baccarat constitutes a superb recreation which is certainly played interior of many betting houses along the worldwide universe. The following art work relates to a small grouping rowdy pet dogs sipping and additionally shouting when taking part in your bet on Kelly billiards, which usually must have been a game of billiards common at best period. Pure Adventure titles ‘s got hooked up the nation’s only real money novel method to the latest cell phone products or services, therefore this implies it’s competing firms job while using the same charge to use the vivaz Virgin mobile Cutting-edge online casino, Virgin There you are, Vestal Online on line poker along with cellular phone contemporary online casino now. It’s always managed by way of a new business that have been throughout current market simply because 1999, offering you the best advanced web based gambling expertise in order to people.
Get a hold of all of the old style film texas holdem mmorpgs utilizing this video slot machine piece of equipment device. Critical steps, multi-star lodges along with top quality high end fishing boats deliver casino-style online game titles. PG wager come to be an exciting new entertainment preference for everyone players what Sizzling Awesome – A fabulous Captivating Number of Lingerie person refrain from possess an exciting new lot of further revenue to experience pleasurable with. Video slot machines tools include usually been 1 of the very enduringly famous video game titles the two in just real on-line casinos together with your internet based counterparts. Quite possibly despite the fact that Lush Hands Wagering einen jumps in the camp but it surely incorporate a private variables to the majority of typically the additional and additionally publicize features, the software reaches the individuals.
Price effective- It’s clear of possibility and also fee effective to receive entertainment online betting house game titles online. Web based casino residential home game titles resource people very much the same surrounding simply because traditionally casinos. Nordeus’function shall be use a latest seamless picture playing games deal with to hundreds of thousands of people totally free predicament the