Skip to content

Commit 16f2568

Browse files
mtrezzadplewis
authored andcommitted
Add page localization (#7128)
* added localized pages; added refactored page templates; adapted test cases; introduced localization test cases * added changelog entry * fixed test description typo * fixed bug in PromiseRouter where headers are not added for text reponse * added page parameters in page headers for programmatic use * refactored tests for PublicAPIRouter * added mustache lib for template rendering * fixed fs.promises module reference * fixed template placeholder typo * changed redirect response to provide headers instead of query parameters * fix lint * fixed syntax errors and typos in html templates * removed obsolete URI encoding * added locale inferring from request body and header * added end-to-end localizaton test * added server option validation; refactored pages server option * fixed invalid redirect URL for no locale matching file * added end-to-end localizaton tests * adapted tests to new response content * re-added PublicAPIRouter; added PagesRouter as experimental feature * refactored PagesRouter test structure * added configuration option for custom path to pages * added configuration option for custom endpoint to pages * fixed lint * added tests * added a distinct page for invalid password reset link * renamed generic page invalidLink to expiredVerificationLink * improved HTML files documentation * improved HTML files documentation * changed changelog entry for experimental feature * improved file naming to make it more descriptive * fixed file naming and env parameter naming * added readme entry * fixed readme TOC - hasn't been updated in a while * added localization with JSON resource * added JSON localization to feature pages (password reset, email verification) * updated readme * updated readme * optimized JSON localization for feature pages; added e2e test case * fixed readme typo * minor refactoring of existing tests * fixed bug where Object type was not recognized as config key type * added feature config placeholders * prettier * added passing locale to page config placeholder callback * refactored passing locale to placeholder to pass test * added config placeholder feature to README * fixed typo in README
1 parent 7591be2 commit 16f2568

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4332
-2900
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
__BREAKING CHANGES:__
77
- NEW: Added file upload restriction. File upload is now only allowed for authenticated users by default for improved security. To allow file upload also for Anonymous Users or Public, set the `fileUpload` parameter in the [Parse Server Options](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html). [#7071](https://github.com/parse-community/parse-server/pull/7071). Thanks to [dblythy](https://github.com/dblythy), [Manuel Trezza](https://github.com/mtrezza).
88
___
9-
- NEW: Added convenience method Parse.Cloud.sendEmail(...) to send email via email adapter in Cloud Code. [#7089](https://github.com/parse-community/parse-server/pull/7089). Thanks to [dblythy](https://github.com/dblythy)
9+
- NEW (EXPERIMENTAL): Added new page router with placeholder rendering and localization of custom and feature pages such as password reset and email verification. **Caution, this is an experimental feature that may not be appropriate for production.** [#6891](https://github.com/parse-community/parse-server/issues/6891). Thanks to [Manuel Trezza](https://github.com/mtrezza).
10+
- NEW: Added convenience method `Parse.Cloud.sendEmail(...)` to send email via email adapter in Cloud Code. [#7089](https://github.com/parse-community/parse-server/pull/7089). Thanks to [dblythy](https://github.com/dblythy)
1011
- NEW: LiveQuery support for $and, $nor, $containedBy, $geoWithin, $geoIntersects queries [#7113](https://github.com/parse-community/parse-server/pull/7113). Thanks to [dplewis](https://github.com/dplewis)
1112
- NEW: Supporting patterns in LiveQuery server's config parameter `classNames` [#7131](https://github.com/parse-community/parse-server/pull/7131). Thanks to [Nes-si](https://github.com/Nes-si)
1213
- IMPROVE: Added new account lockout policy option `accountLockout.unlockOnPasswordReset` to automatically unlock account on password reset. [#7146](https://github.com/parse-community/parse-server/pull/7146). Thanks to [Manuel Trezza](https://github.com/mtrezza).

README.md

+256-45
Large diffs are not rendered by default.

package-lock.json

+1,286-2,838
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"lru-cache": "5.1.1",
4848
"mime": "2.5.0",
4949
"mongodb": "3.6.3",
50+
"mustache": "4.1.0",
5051
"parse": "2.19.0",
5152
"pg-promise": "10.9.1",
5253
"pluralize": "8.0.0",

public/custom_json.html

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page demonstrates how to localize using a JSON file that contains the
4+
translations for each placeholder.
5+
-->
6+
<html>
7+
8+
<head>
9+
<title>{{title}}</title>
10+
</head>
11+
12+
<body>
13+
<h1>{{heading}}</h1>
14+
<p>{{body}}</p>
15+
</body>
16+
17+
</html>

public/custom_json.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"en": {
3+
"translation": {
4+
"title": "Hello!",
5+
"heading": "Welcome to {{appName}}!",
6+
"body": "We are delighted to welcome you on board."
7+
}
8+
},
9+
"de": {
10+
"translation": {
11+
"title": "Hallo!",
12+
"heading": "Willkommen bei {{appName}}!",
13+
"body": "Wir freuen uns, dich begrüßen zu dürfen."
14+
}
15+
},
16+
"de-AT": {
17+
"translation": {
18+
"title": "Servus!",
19+
"heading": "Willkommen bei {{appName}}!",
20+
"body": "Wir freuen uns, dich begrüßen zu dürfen."
21+
}
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with a security
4+
token that is expired or incorrect. This can either mean the user has clicked
5+
on a stale link (i.e. re-clicked on the link) or this could be a sign of a
6+
malicious user trying to tamper with your app.
7+
-->
8+
<html>
9+
10+
<head>
11+
<title>Email Verification</title>
12+
</head>
13+
14+
<body>
15+
<h1>{{appName}}</h1>
16+
<h1>Expired verification link!</h1>
17+
<form method="POST" action="{{{publicServerUrl}}}/apps/{{{appId}}}/resend_verification_email">
18+
<input name="username" type="hidden" value="{{{username}}}">
19+
<input name="locale" type="hidden" value="{{{locale}}}">
20+
<button type="submit">Resend Link</button>
21+
</form>
22+
</body>
23+
24+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with parameters
4+
that are missing or incorrect. This can either mean the user has incorrectly
5+
entered a link or this could be a sign of a malicious user trying to tamper
6+
with your app.
7+
If the link contains an expired security token (or the email has already
8+
been verified), this page is not displayed, there is another page for that.
9+
-->
10+
<html>
11+
12+
<head>
13+
<title>Email Verification</title>
14+
</head>
15+
16+
<body>
17+
<h1>{{appName}}</h1>
18+
<h1>Invalid verification link!</h1>
19+
</body>
20+
21+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with a security
4+
token that is expired or incorrect, then requests to receive another link,
5+
but it fails because the username is invalid or the email has already been
6+
verified. This can either mean the user has previously verified the email
7+
or this could be a sign of a malicious user trying to tamper with your app.
8+
-->
9+
<html>
10+
11+
<head>
12+
<title>Email Verification</title>
13+
</head>
14+
15+
<body>
16+
<h1>{{appName}}</h1>
17+
<h1>Invalid link!</h1>
18+
<p>No link sent. User not found or email already verified.</p>
19+
</body>
20+
21+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with a
4+
security token that is expired, then requests to receive another email
5+
with a new link and the email is sent successfully.
6+
-->
7+
<html>
8+
9+
<head>
10+
<title>Email Verification</title>
11+
</head>
12+
13+
<body>
14+
<h1>{{appName}}</h1>
15+
<h1>Link sent!</h1>
16+
<p>A new link has been sent. Check your email.</p>
17+
</body>
18+
19+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link and the
4+
email gets verified successfully.
5+
-->
6+
<html>
7+
8+
<head>
9+
<title>Email Verification</title>
10+
</head>
11+
12+
<body>
13+
<h1>{{appName}}</h1>
14+
<h1>Email verified!</h1>
15+
<p>Successfully verified your email for account: {{username}}.</p>
16+
</body>
17+
18+
</html>

public/de-AT/password_reset.html

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when someone clicks a valid 'reset password' link.
4+
Users should feel free to add to this page (i.e. branding or security widgets)
5+
but should be sure not to delete any of the form inputs or the javascript from the
6+
template file. This javascript is what adds the necessary values to authenticate
7+
this session with Parse.
8+
The query params 'username' and 'app' hold the friendly names for your current user and
9+
your app. You should feel free to incorporate their values to make the page more personal.
10+
If you are missing form parameters in your POST, Parse will navigate back to this page and
11+
add an 'error' query parameter.
12+
-->
13+
<html>
14+
15+
<head>
16+
<title>Password Reset</title>
17+
</head>
18+
19+
<body>
20+
<h1>{{appName}}</h1>
21+
<h1>Reset Your Password</h1>
22+
<noscript><p>We apologize, but resetting your password requires javascript</p></noscript>
23+
<p>You can set a new Password for your account: {{username}}</p>
24+
<br />
25+
<p>{{error}}</p>
26+
<form id='form' action='{{{publicServerUrl}}}/apps/{{{appId}}}/request_password_reset' method='POST'>
27+
<input name='utf-8' type='hidden' value='' />
28+
<input name="username" type="hidden" id="username" value="{{{username}}}" />
29+
<input name="token" type="hidden" id="token" value="{{{token}}}" />
30+
<input name="locale" type="hidden" id="locale" value="{{{locale}}}" />
31+
32+
<p>New Password</p>
33+
<input name="new_password" type="password" id="password" />
34+
<p>Confirm New Password</p>
35+
<input name="confirm_new_password" type="password" id="password_confirm" />
36+
<br />
37+
<p id="password_match_info"></p>
38+
<br />
39+
<button id="change_password">Change Password</button>
40+
</form>
41+
42+
<script>
43+
window.onload = function() {
44+
document.getElementById("password").oninput = validatePassword;
45+
document.getElementById("password_confirm").oninput = validatePassword;
46+
document.getElementById("change_password").disabled = true;
47+
48+
function validatePassword() {
49+
var pass2 = document.getElementById("password").value;
50+
var pass1 = document.getElementById("password_confirm").value;
51+
if(pass1 !== pass2) {
52+
if(document.getElementById("password_confirm").value) {
53+
document.getElementById("change_password").disabled = true;
54+
document.getElementById("password_match_info").innerHTML = "Must match the previous entry";
55+
}
56+
} else {
57+
document.getElementById("change_password").disabled = false;
58+
document.getElementById("password_match_info").innerHTML = "";
59+
}
60+
}
61+
}
62+
</script>
63+
</body>
64+
65+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a password reset link with parameters
4+
that are missing or incorrect. This can either mean the user has incorrectly
5+
entered a link or this could be a sign of a malicious user trying to tamper
6+
with your app.
7+
-->
8+
<html>
9+
10+
<head>
11+
<title>Password Reset</title>
12+
</head>
13+
14+
<body>
15+
<h1>{{appName}}</h1>
16+
<h1>Invalid password reset link!</h1>
17+
</body>
18+
19+
</html>
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a reset password link, then submits
4+
the form with a new password and the password gets updated successfully.
5+
-->
6+
<html>
7+
8+
<head>
9+
<title>Password Reset</title>
10+
</head>
11+
12+
<body>
13+
<h1>{{appName}}</h1>
14+
<h1>Success!</h1>
15+
<p>Your password has been updated.</p>
16+
</body>
17+
18+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with a security
4+
token that is expired or incorrect. This can either mean the user has clicked
5+
on a stale link (i.e. re-clicked on the link) or this could be a sign of a
6+
malicious user trying to tamper with your app.
7+
-->
8+
<html>
9+
10+
<head>
11+
<title>Email Verification</title>
12+
</head>
13+
14+
<body>
15+
<h1>{{appName}}</h1>
16+
<h1>Expired verification link!</h1>
17+
<form method="POST" action="{{{publicServerUrl}}}/apps/{{{appId}}}/resend_verification_email">
18+
<input name="username" type="hidden" value="{{{username}}}">
19+
<input name="locale" type="hidden" value="{{{locale}}}">
20+
<button type="submit">Resend Link</button>
21+
</form>
22+
</body>
23+
24+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with parameters
4+
that are missing or incorrect. This can either mean the user has incorrectly
5+
entered a link or this could be a sign of a malicious user trying to tamper
6+
with your app.
7+
If the link contains an expired security token (or the email has already
8+
been verified), this page is not displayed, there is another page for that.
9+
-->
10+
<html>
11+
12+
<head>
13+
<title>Email Verification</title>
14+
</head>
15+
16+
<body>
17+
<h1>{{appName}}</h1>
18+
<h1>Invalid verification link!</h1>
19+
</body>
20+
21+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with a security
4+
token that is expired or incorrect, then requests to receive another link,
5+
but it fails because the username is invalid or the email has already been
6+
verified. This can either mean the user has previously verified the email
7+
or this could be a sign of a malicious user trying to tamper with your app.
8+
-->
9+
<html>
10+
11+
<head>
12+
<title>Email Verification</title>
13+
</head>
14+
15+
<body>
16+
<h1>{{appName}}</h1>
17+
<h1>Invalid link!</h1>
18+
<p>No link sent. User not found or email already verified.</p>
19+
</body>
20+
21+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link with a
4+
security token that is expired, then requests to receive another email
5+
with a new link and the email is sent successfully.
6+
-->
7+
<html>
8+
9+
<head>
10+
<title>Email Verification</title>
11+
</head>
12+
13+
<body>
14+
<h1>{{appName}}</h1>
15+
<h1>Link sent!</h1>
16+
<p>A new link has been sent. Check your email.</p>
17+
</body>
18+
19+
</html>
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<!--
3+
This page is displayed when a user opens a verify email link and the
4+
email gets verified successfully.
5+
-->
6+
<html>
7+
8+
<head>
9+
<title>Email Verification</title>
10+
</head>
11+
12+
<body>
13+
<h1>{{appName}}</h1>
14+
<h1>Email verified!</h1>
15+
<p>Successfully verified your email for account: {{username}}.</p>
16+
</body>
17+
18+
</html>

0 commit comments

Comments
 (0)