Logout user with expired session

Do you know id “axios” can be used on back4app servers? I tried to use the original example but it throws an error

Failed running cloud function extendSession for user Yei2sPx5OW with:
Input: {}
Error: {“message”:“req is not defined”,“code”:141}

I guess I need to declare that req somehow. Is it http request, would anyone know?

Parse.Cloud.define("extendSessionToken", function(request, response)
{
    req({
        method: 'GET',
        url: process.env.SERVER_URL + "/sessions/me",
        headers:
        {
            'X-Parse-Application-Id': process.env.APP_ID,
            'X-Parse-REST-API-Key': process.env.REST_API_KEY,
            'X-Parse-Session-Token': request.headers["x-parse-session-token"],
            'X-Parse-Master-Key' : process.env.MASTER_KEY
        }        
    }, function (error, httpResponse, body) 
    {...

Thank you!

@lsmilek1 req is request library I guess. You can use built in fetch for that.

Parse.Cloud.define("extendSessionToken", request => {
  return await fetch(`${process.env.SERVER_URL}/sessions/me`, {
    method: 'GET',
    headers: {
      'X-Parse-Application-Id': process.env.APP_ID,
      'X-Parse-REST-API-Key': process.env.REST_API_KEY,
      'X-Parse-Session-Token': request.headers["x-parse-session-token"],
      'X-Parse-Master-Key' : process.env.MASTER_KEY
    } 
  });
});

Thank you for great help! I was able to refactor it into following:

//Extend current token till end of the next month
Parse.Cloud.define("extendSession", async (request) => {
    const mySessionToken = request.headers["x-parse-session-token"];
    let mySessionID;
    // get current session ID
    try {
        let response = await fetch(`${process.env.SERVER_URL}/sessions/me`, {
            method: 'GET',
            headers: {
              'X-Parse-Application-Id': process.env.APP_ID,
              'X-Parse-REST-API-Key': process.env.REST_API_KEY,
              'X-Parse-Session-Token': mySessionToken,
              'X-Parse-Master-Key' : process.env.MASTER_KEY
            }
        });
        mySessionID = response.data.objectId;
    } catch (err) {
        request.log.error(`error fetching session ${err}`);
        return null;
    }      
    // change expiration Date 
    const dateNow = new Date(); 
    //last day of next month (setting day 0 of month after next one)
    const newDate = new Date(dateNow.getFullYear(), dateNow.getMonth() + 2, 0);
    let newSessionPayload = {
        expiresAt: {"__type": "Date", "iso": newDate.toISOString()}
    }
    //save new payload
    try {
        await fetch(`${process.env.SERVER_URL}/sessions/${mySessionID}`, {
            method: 'PUT',
            headers: {
              'X-Parse-Application-Id': process.env.APP_ID,
              'X-Parse-REST-API-Key': process.env.REST_API_KEY,
              'X-Parse-Session-Token': mySessionToken,
              'X-Parse-Master-Key' : process.env.MASTER_KEY
            },
            body: newSessionPayload
        });
    } catch (err) {
        request.log.error(`error saving extended session ${err}`);
        return null;
    }
    return newDate;    
});

But I think I missed to declare something as it throws error for the first try:

  1. 2021-09-08T07:45:32.866Z - error fetching session ReferenceError: fetch is not defined

Adding import fetch from "node-fetch"; above the function case the following error:

  1. 2021-09-08T07:56:05.915Z - Parse error: Invalid function: “extendSession”

probably due to following system error:

Error loading your cloud code:
/usr/src/app/data/cloud/main.js:8
import fetch from “node-fetch”;
^^^^^^

Does it needs to be declared in package.json? Then I could import perhaps even axios and use the original posted code.

1 Like

Maybe es6 syntax doesn’t supported in cloud code.
You can import node-fetch like this:

const fetch = require('node-fetch');

If error still exists then try to add package.json

Edit: If you are using back4app, then you should add your package name to your package.json file.

See: https://help.back4app.com/hc/en-us/articles/360002038772-How-to-install-an-NPM-module-at-Back4App-

Ah, great! Did not need to add it into package.json for back4app. Sadly, this moved me to other error with the fetch:

error fetching session TypeError: Only absolute URLs are supported

I see that in the original post on stackOverflow were non-absolute URLs used, but above with the axios example it seems so.

Does this mean I should hardcode the server URL in the cloud code? Or is there any other “convert to string” trick?

if you are using back4app, then you can replace the process.env.SERVER_URL with this:
https://parseapi.back4app.com/

All back4app clients use same base url.

Thanks for tremendous help! As I adjusted it with the hard coded url it seems to move again a bit further, but my guess is that all the headers should be hard coded because the response is as follows:

{“code”:141, “error”:{ “size”:0, “timeout”:0 }}

Therefore it can’t extract the mySessionID = response.data.objectId;

Parse.Cloud.define("extendSession", async (request) => {

    const mySessionToken = request.headers["x-parse-session-token"];
    const serverUrl = `https://parseapi.back4app.com/`;
    let mySessionID;

    // get current session ID
    try {
        let response = await fetch(serverUrl + `sessions/me`, {
            method: 'GET',
            headers: {
              'X-Parse-Application-Id': process.env.APP_ID,
              'X-Parse-REST-API-Key': process.env.REST_API_KEY,
              'X-Parse-Session-Token': mySessionToken,
              'X-Parse-Master-Key' : process.env.MASTER_KEY
            }
        });
        mySessionID = response.data.objectId;
    } catch (err) {
        request.log.error(`error fetching session ${err}`);
        throw err;
    }  
...

seems that process.env is undefined:

  1. error fetching session [object Response]APP_ID undefined, REST_API_KEY undefined, mySessionToken r:94cfc5035b951bb4b346fab0c69328f1, MASTER_KEY undefined, SERVER_URL undefined

Actually you don’t need to fetch user session again. Session token should be avalable with request.user.getSessionToken();

Can you try this:

Parse.Cloud.define("extendSession", async (request) => {
  const getSession = new Parse.Query(Parse.Session);
  getSession.equalTo('sessionToken', request.user.getSessionToken());
  const session = await getSession.first({useMasterKey: true});

  // change expiration Date 
  const dateNow = new Date(); 
  //last day of next month (setting day 0 of month after next one)
  const newDate = new Date(dateNow.getFullYear(), dateNow.getMonth() + 2, 0);
  let newSessionPayload = {
      expiresAt: {"__type": "Date", "iso": newDate.toISOString()}
  }
  //save new payload
  try {
      await fetch(`${Parse.serverURL}/sessions/${session.id}`, {
          method: 'PUT',
          headers: {
            'X-Parse-Application-Id': Parse.applicationId,
            'X-Parse-Master-Key' : Parse.masterKey,
          },
          body: JSON.stringify(newSessionPayload)
      });
  } catch (err) {
      request.log.error(`error saving extended session ${err}`);
      return null;
  }
  return newDate;    
});
2 Likes

:open_mouth:

Works out of the box!!!

I believe you could post that as and another answer on stackOverflow!

Thanks a LOT!

You are welcome. Glad it worked.