Apollo & Graphcool: `Insufficient permissions for this mutation` - HowTo best set connectionParams?

857 Views Asked by At

So, and after setting the Delete permissions of my Graphcool Comments schema to Authenticated (See image), I'm receiving the above mentioned error (See image) when attempting to delete a post comment.

A user receives a token after signing in as follows:

const Login = React.createClass({
  
  signinUser: function(emailID, passwordID) {

    const email = emailID;
    const password = passwordID;

    this.props.client.mutate({
      mutation: signinUser_Mutation,
      variables: {
        email,
        password,
      },
      options: {
        cachePolicy: 'offline-critical', 
        fetchPolicy: 'cache-first',
      },
    })
    .then(this.updateStateLoginDetails)
    .catch(this.handleSubmitError);
  },

  updateStateLoginDetails: function({data}) {
    localForage.setItem('graphcoolToken', data.signinUser.token);
  },

  handleSubmitError: function(err) {
    console.error(err.message);
  },

  handleSubmit: function(e) {
    e.preventDefault();
    this.signinUser(this.refs.email.value, this.refs.password.value);
    this.refs.loginForm.reset();
    this.refs.email.focus();
  },
  render: function() {

    return (
      <div className="comments">

        <form onSubmit={this.handleSubmit} ref="loginForm" className="comment-form">
          <input type="text" ref="email" placeholder="email"/>
          <input type="text" ref="password" placeholder="password"/>
          <input type="submit" hidden/>
        </form>
      </div>
    );
  }
});

Login.propTypes = {
  client: React.PropTypes.instanceOf(ApolloClient).isRequired,
}
const LoginWithApollo = withApollo(Login);

export default LoginWithApollo;

and the authorisation header is then set in my ApolloClient.js as follows:

const logErrors = {
  applyAfterware({ response }, next) {
    if (!response.ok) {
      response.clone().text().then((bodyText) => {
        console.log('...', `Network Error: ${response.status} (${response.statusText}) - ${bodyText}`);
        next();
      });
    } else {
      response.clone().json().then(({ errors }) => {
        if (errors) {
          console.log('...', 'GraphQL Errors:', errors.map(e => e.message));
        }
        next();
      });
    }
  },
};

// Create WebSocket client
const wsClient = new SubscriptionClient(SubscriptionClient_URL, {
  reconnect: true,
  connectionParams: {
    Authorization: Best way to read in graphcoolToken here?
  }
});

const networkInterface = createNetworkInterface({ 
  uri: networkInterface_URL,
  opts: {
    credentials: 'include',
  }
});

networkInterface.use([{
  async applyMiddleware(req, next) {
    if (!req.options.headers) {
      req.options.headers = {};  // Create the header object if needed.
    }
    
    // get the authentication token from local storage if it exists
    localForage.getItem('graphcoolToken', function (err, value) {
      req.options.headers.Authorization = value ? `Bearer ${value}` : null;

      // This is where next should have been placed
      next();
    });
  
    // next was incorrectly placed here
    next()
  },
}]);

if (process.env.NODE_ENV !== 'production') {
  networkInterface.useAfter([logErrors]);
}

// Extend the network interface with the WebSocket
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
  networkInterface,
  wsClient
);

const client = new ApolloClient({
  networkInterface: networkInterfaceWithSubscriptions,
  dataIdFromObject: (o) => o.id,
  addTypeName: true,
  shouldBatch: true,
});

export default client;

The mutation to remove a comment is:

export const Remove_Comment_MutationOLD = gql`
  mutation removeComment ($id: ID!, $cid: ID!) {
    removeFromPostsOnComments (postsPostsId: $id, commentsCommentsId: $cid) {
      postsPosts {
        __typename
        id
        comments {
          __typename
          id
          text
          user
          deleted
          posts {
            __typename
            id
          }
        }
      }
    }

    deleteComments(id: $cid) {
      id
    }
  }
`;

So my question is, after setting the req.options.headers.authorization header, what is the best way to set Authorization in connectionParams, as mentioned in the following article: https://www.graph.cool/forum/t/authentication-issues-with-subscriptions/45/2

enter image description here

enter image description here

enter image description here

0

There are 0 best solutions below