Home > front end >  Google Apps Script WebApp with Simultaneous Users Overrides User Recognition
Google Apps Script WebApp with Simultaneous Users Overrides User Recognition

Time:11-20

I have a project that lets users send forms that contains only a few details. I used to use Session class of google but that messes everything up when multiple accounts are logged in or some other reason that I couldn't fix for weeks. So I decided to try another approach and cut google auth altogether and get user verification from my LMS' POST data and set it as a UserProperty. Everything worked perfectly without the Google Auth and I did a mass test today. As a result, since my script has to run as "Me", the said user is the script owner account which in turn makes UserProperty kind of ScriptProperty for all users and they start to override eachother's user details.

For example, a second user that opens the WebApp from their LMS overrides the first user's user details, since the first user's details got overridden by the second user, all submissions appear to be sent by the second user. Code below;

  function doPost(e) {
  var postContents = e.postData.contents.split("&");
  var postSplit = postContents[16].split("=");
  var activeUserEmail = postSplit[1].replace("@", "@");
  userProperties.setProperty('activeUserEmail', activeUserEmail);

  if (activeUserEmail[2] == "s" || activeUserEmail[2] == ".") {
    console.log("Redirecting to Student: "   activeUserEmail);
    return HtmlService.createTemplateFromFile('student_form')
      .evaluate()
      .addMetaTag('viewport', 'width=device-width, initial-scale=1')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  } 

This function gets called by the a user on the html page via google.script.run with successhandler and passed back to the page after some more proccessing on a spreadsheet and Drive.

function getData() {
  var activeUserEmail = userProperties.getProperty('activeUserEmail');
  console.log("getData User: "   activeUserEmail);
  try {
    if (activeUserEmail != "") {
      var userResults = teachersSheet.filter(function (row) { return row[0] == activeUserEmail; });
    } else {
      var userResults = "No User Email"
    }
    var userDepartment = userResults[0][2];

    if (userDepartment == "Admin") {
      var data = questionsSheet.getDisplayValues().filter(function (row) { return row[1] != "" && row[0] != "ID"; });
    }
    else {
      var data = questionsSheet.getDisplayValues().filter(function (row) { return row[3] == userDepartment && row[9] == "FALSE" && row[1] != ""; });
    };

    var data = [userResults, data];
    console.log(data);
    return data;
  } catch (e) {
    console.log(e);
  }
}

Code might be a little messy but that's hopefully enough.

I couldn't figure out how to keep a persistent user detail information in a variable or property that wouldn't get overridden by a second script runner. Any ideas?

CodePudding user response:

State can be maintained by storing a unique id in

  • user properties and
  • client Javascript variable
const id = Utilities.getUuid()
userProperties.setProperty(String(id), activeUserEmail);

The student_form html also needs to be evaluated with this id. The id, once on the client side should be sent with every request to the server.

google.script.run.getData(id)
function getData(id) {
  var activeUserEmail = userProperties.getProperty(String(id));
  console.log("getData User: "   activeUserEmail);
  //stuff
  • Related