Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parseFrameURL for masking user-facing pages #3267

Merged
merged 14 commits into from
Jan 8, 2017

Conversation

lenart
Copy link
Contributor

@lenart lenart commented Dec 21, 2016

Allow users to specify a different address which is used to mask parse requests for verifying email and resetting password. This is how Parse.com used to allow customers to gain control over page content, styling etc.

On the destination page javascript is used to check the link in the request and embed the parse server page using IFRAME.

This is a clone of a closed PR (#3091) because I reorganized git branches. Thanks to @jure for adding tests.

lenart and others added 12 commits November 21, 2016 23:34
Allow users to specify a different address which is used to mask parse
requests for verifying email and resetting password. This is how Parse.com
used to allow customers to gain control over page content, styling etc.

On the destination page javascript is used to check the link in the request
and embed the parse server page using IFRAME.
Allow users to specify a different address which is used to mask parse
requests for verifying email and resetting password. This is how Parse.com
used to allow customers to gain control over page content, styling etc.

On the destination page javascript is used to check the link in the request
and embed the parse server page using IFRAME.
@jure
Copy link

jure commented Dec 21, 2016

Looks like there is a failing spec:

/home/travis/build/ParsePlatform/parse-server/spec/ValidationAndPasswordsReset.spec.js:317
        expect(response.statusCode).toEqual(302);
                       ^
TypeError: Cannot read property 'statusCode' of undefined
    at Request._callback (/home/travis/build/ParsePlatform/parse-server/spec/ValidationAndPasswordsReset.spec.js:303:16)
    at self.callback (/home/travis/build/ParsePlatform/parse-server/node_modules/request/request.js:186:22)
    at emitOne (events.js:77:13)
    at Request.emit (events.js:169:7)

I tried running the specs locally and for some reason, when the entire suite is run, this test fails, but if you just run ValidationAndPasswordsReset spec, it passes. So it could be some cross-test issue.

Update: Yeah it's definitely something I do in UserController.spec.js that causes ValidationAndPasswordsReset.spec.js to fail. Fun :)

Update 2: Ah, dooh. It's the Object.assign to defaultConfiguration (which is actually a global, one quickly forgets). I'll send a PR to your branch, @lenart.

Update 3: @lenart done lenart#2

Don't Object.assign to defaultConfiguration global
@facebook-github-bot
Copy link

@lenart updated the pull request - view changes

@jure
Copy link

jure commented Dec 22, 2016

Cool, thanks for merging the patch for those cross-test issues, @lenart. All checks passing now 👍

@jure
Copy link

jure commented Dec 22, 2016

@flovilmart Based on your comment in #3091 we added tests, to verify that the email link is built as it was before, without the parseFrameURL option. They don't specifically test the buildEmailLink function, but verifies that the links in the resulting emails are correct. It felt weird to test buildEmailLink directly, especially since it's a private function hidden in the UserController's closure.

@acinader acinader merged commit 5d9dbea into parse-community:master Jan 8, 2017
@jure
Copy link

jure commented Jan 9, 2017

Yay, 🎉, good job @lenart. Thanks for merging, @acinader!

@lenart
Copy link
Contributor Author

lenart commented Jan 9, 2017

Thank you all. We wouldn't have a merge if it wasn't for @jure's tests ;)

@lenart lenart deleted the frame-url branch January 9, 2017 15:02
@natanrolnik
Copy link
Contributor

@lenart @jure 2.3.2 was released a few minutes ago with your feature!

@fishandphil
Copy link

thanks for adding this.is there any documentation or example for the .html?

@lenart
Copy link
Contributor Author

lenart commented Jan 24, 2017

Thanks for bringing this up - a sample file should be placed somewhere for reference. I think this should work (this is the same as sample provided by parse.com). You'll obviously need to change the base variable. Other variables might also need small adjustments.

<!DOCTYPE html>
<html>
  <head>
  <title>Password Reset</title>
</head>
<body>
  <h1>Reset Your Password<span id='app'></span></h1>
  <noscript>We apologize, but resetting your password requires javascript</noscript>
  <div class='error' id='error'></div>
  <form id='form' action='#' method='POST'>
    <label>New Password for <span id='username_label'></span></label>
    <input name="new_password" type="password" />
    <input name='utf-8' type='hidden' value='' />
    <input name="username" id="username" type="hidden" />
    <input name="token" id="token" type="hidden" />
    <button>Change Password</button>
  </form>

<script language='javascript' type='text/javascript'>
  <!--
  window.onload = function() {
    var urlParams = {};
    (function () {
        var pair, // Really a match. Index 0 is the full match; 1 & 2 are the key & val.
            tokenize = /([^&=]+)=?([^&]*)/g,
            // decodeURIComponents escapes everything but will leave +s that should be ' '
            re_space = function (s) { return decodeURIComponent(s.replace(/\+/g, " ")); },
            // Substring to cut off the leading '?'
            querystring = window.location.search.substring(1);

        while (pair = tokenize.exec(querystring))
           urlParams[re_space(pair[1])] = re_space(pair[2]);
    })();

    var base = 'https://www.parse.com';
    var id = urlParams['id'];
    document.getElementById('form').setAttribute('action', base + '/apps/' + id + '/request_password_reset');
    document.getElementById('username').value = urlParams['username'];
    document.getElementById('username_label').appendChild(document.createTextNode(urlParams['username']));

    document.getElementById('token').value = urlParams['token'];
    if (urlParams['error']) {
      document.getElementById('error').appendChild(document.createTextNode(urlParams['error']));
    }
    if (urlParams['app']) {
      document.getElementById('app').appendChild(document.createTextNode(' for ' + urlParams['app']));
    }
  }
  //-->
</script>
</body>

@fishandphil
Copy link

@lenart is that the file that is supposed to be associated with "parseFrameURL" (once the base changed) because it looks what you posted looks a lot like the "choosePassword" template.

@lenart
Copy link
Contributor Author

lenart commented Feb 1, 2017

@fishandphil yeah sorry for the confusion. I think the documentation needs to be improved and also this part of the code probably needs some more love. I never tested verifying emails as I didn't need it and thus only followed the existing patterns and config variables.

The setup I currently use is the following (not caring about email verification).

  1. http://www.mysite.com/forgot-password contains the content of the gist (https://gist.github.com/lenart/e3bd2abe179606108998f444f8e1b282)
  2. parseFrameURL is set to http://www.mysite.com/forgot-password
  3. when a request for password reset is sent to parse server (with username) it sends out an email linking to http://www.mysite.com/forgot-password?link=xxx&token=xxx&username=xxx (parseFrameURL plus three attributes)
  4. with Javascript you extract the token, username and link and change form's action so that it submits those attributes (along with new password) to http://www.my-parse-server.com/1/apps/my-parse-app-id/request_password_reset
  5. if the password update succeeds it will redirect user to passwordResetSuccess. If it doesn't it will redirect to invalidLink.

I haven't tested this with verifyEmailSuccess. I'm currently not sure what the request looks like when email verification link is sent. I believe the right way to use this config variables is so that parseFrameURL checks the input parameters and decide if we need to display a forgot password page or confirm email page. But as I said I had to rush forward with the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants