Skip to content

Error occurring using beforeLogin for users logging in with AuthData #6871

Open
@kvnkuang

Description

@kvnkuang

Issue Description

When logging in with AuthData, an error (similar to #5998) occurs if that user has one or more files associated.

If no files associated, beforeLogin can be executed without error.

Steps to reproduce

  1. Define a beforeLogin trigger like the following:
Parse.Cloud.beforeLogin(async request => {
  const { object: user }  = request;
  if(user.get('isBanned')) {
   throw new Error('Access denied, you have been banned.')
  }
});
  1. Log in with an Auth provider. No matter if the user has isBanned set to true, the following error occurs.
UnhandledPromiseRejectionWarning: Error: Tried to encode an unsaved file.
    at encode (C:\Users\kevin\Documents\GitHub\maveregistry-parse-server\node_modules\parse\lib\node\encode.js:73:13)
    at _default (C:\Users\kevin\Documents\GitHub\maveregistry-parse-server\node_modules\parse\lib\node\encode.js:126:10)
    at ParseUser.toJSON (C:\Users\kevin\Documents\GitHub\maveregistry-parse-server\node_modules\parse\lib\node\ParseObject.js:604:42)
    at C:\Users\kevin\Documents\GitHub\maveregistry-parse-server\node_modules\parse-server\lib\triggers.js:598:81
    at error (C:\Users\kevin\Documents\GitHub\maveregistry-parse-server\node_modules\parse-server\lib\triggers.js:379:9)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Actual Outcome

I spent some time investigating this problem and found that this error was triggered by this block of code:

logTriggerSuccessBeforeHook(
triggerType,
'Parse.File',
{ ...fileObject.file.toJSON(), fileSize: fileObject.fileSize },
result,
auth
);
return result || fileObject;
} catch (error) {
logTriggerErrorBeforeHook(
triggerType,
'Parse.File',
{ ...fileObject.file.toJSON(), fileSize: fileObject.fileSize },
auth,
error
);

Specifically, when encoding a file object with toJSON(), because the object was not expanded, it has no url property and hence cause this block of code to throw an error:

  if (value instanceof ParseFile) {
    if (!value.url()) {
      throw new Error('Tried to encode an unsaved file.');
    }
    return value.toJSON();
  }

Similar to the fix introduced previously (#6001), all we need is to expand file objects before passing them to the trigger runBeforeLoginTrigger in RestWrite.js:

  // Cloud code gets a bit of extra data for its objects
  const extraData = { className: this.className };

  // PROPOSED FIX: expand file objects
  this.config.filesController.expandFilesInObject(this.config, userData)
  
  const user = triggers.inflate(extraData, userData);

  // no need to return a response
  await triggers.maybeRunTrigger(
    triggers.Types.beforeLogin,
    this.auth,
    user,
    null,
    this.config,
    this.context
  );

Environment

Server

  • Parse Server version: 4.3.0
  • Operating system: Windows
  • Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc): local

Client

  • SDK (iOS, Android, JavaScript, PHP, Unity, etc): JavaScript
  • SDK version: 2.15.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:bugImpaired feature or lacking behavior that is likely assumed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions