Search code examples
netlify

How to access form submissions from Netlify for logged in users (with certain roles) only


I have a question about getting form submissions, but only for registered users with a certain role in my application.

My first failed attempt:

I have tried to create a lambda function which accesses form submissions using the access_token received from a succesfull (invite-user) login on my client. However, I am only getting an empty response.

My second attempt:

Instead of using the user's access_token, I created a new Personal access token, stored it as an environment variable in my application on Netlify, and I use the token in my lambda function using process.env.ACCESS_TOKEN. Using this approach is valid, and I received all form submissions.

Here is my lambda function, test.js:

const request = require('request');
exports.handler = function(event, context, callback) {
  let ACCESS_TOKEN = process.env.ACCESS_TOKEN; // when using my personal API token created in Netlify. Does work
  let ACCESS_TOKEN = event["queryStringParameters"]['access_token']; // passing the user's `access_token` from the client in request url. Does not work.
  const options={
    url: "https://api.netlify.com/api/v1/sites/MY_SITE_ID/forms/MY_FORM_ID/submissions",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${ACCESS_TOKEN}`
    }
  }
  request(options, (error, response, body) => {
    console.log("access_token", ACCESS_TOKEN); // I know the ACCESS_TOKEN is present in both of my scenarios.
    callback(null, {
      headers: { "Access-Control-Allow-Origin": "http://localhost:4200","Access-Control-Allow-Headers": "Content-Type"},
      statusCode: 200,
      body: body
    });
  });
}

My request url from the client looks like this: https://MY_DOMAIN.com/.netlify/functions/test?access_token=ACCESS_TOKEN.

I am wondering how I can get form submissions for users with certain roles only. What am I doing wrong? What is the best practice for my scenario?


Solution

  • I sent my question to the team at Netlify, and they were able to help me out. It seems that the acces_token I was sending to the lamdba function was a JWT (json web token). All I needed to do was to decode and verify the JWT in order to access my data. I could then use the user object decoded from the JWT to read the roles. I ended up using code similar to this:

    const request = require('request');
    const jwt = require('jsonwebtoken');
    exports.handler = function(event, context, callback) {
      const JWT_SECRET = "MY SECRET"; // secret used to verify the signature of the jwt
      let ACCESS_TOKEN;
      let user;
      if (event && event.queryStringParameters && event.queryStringParameters.access_token) {
        const jwt_token = event.queryStringParameters.access_token;
        jwt.verify(jwt_token, JWT_SECRET,
         (err, decoded) => {
           user = decoded;
         });
      }
      if(user && user.app_metadata && user.app_metadata.roles &&
        (user.app_metadata.roles.includes("admin") || user.app_metadata.roles.includes("editor"))){
        if(process.env && process.env.ACCESS_TOKEN){
          ACCESS_TOKEN = process.env.ACCESS_TOKEN;
        }
      }
      const options={
        url: "https://api.netlify.com/api/v1/sites/SITE_ID/forms/FORM_ID/submissions",
        headers: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${ACCESS_TOKEN}`
        }
      };
      request(options, (error, response, body) => {
        callback(null, {
          headers: { "Access-Control-Allow-Origin": "http://localhost:4200","Access-Control-Allow-Headers": "Content-Type"},
          statusCode: 200,
          body: body
        });
      });
    }