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
This commit is contained in:
Manuel
2021-02-09 14:03:57 +01:00
committed by GitHub
parent e3ed6e4600
commit 7f47b0427e
41 changed files with 4335 additions and 2903 deletions

View File

@@ -289,6 +289,13 @@ module.exports.ParseServerOptions = {
action: parsers.numberParser('objectIdSize'),
default: 10,
},
pages: {
env: 'PARSE_SERVER_PAGES',
help:
'The options for pages such as password reset and email verification. Caution, this is an experimental feature that may not be appropriate for production.',
action: parsers.objectParser,
default: {},
},
passwordPolicy: {
env: 'PARSE_SERVER_PASSWORD_POLICY',
help: 'Password policy for enforcing password related rules',
@@ -417,15 +424,114 @@ module.exports.ParseServerOptions = {
help: 'Key sent with outgoing webhook calls',
},
};
module.exports.PagesOptions = {
customUrls: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URLS',
help: 'The URLs to the custom pages.',
action: parsers.objectParser,
default: {},
},
enableLocalization: {
env: 'PARSE_SERVER_PAGES_ENABLE_LOCALIZATION',
help: 'Is true if pages should be localized; this has no effect on custom page redirects.',
action: parsers.booleanParser,
default: false,
},
enableRouter: {
env: 'PARSE_SERVER_PAGES_ENABLE_ROUTER',
help:
'Is true if the pages router should be enabled; this is required for any of the pages options to take effect. Caution, this is an experimental feature that may not be appropriate for production.',
action: parsers.booleanParser,
default: false,
},
forceRedirect: {
env: 'PARSE_SERVER_PAGES_FORCE_REDIRECT',
help:
'Is true if responses should always be redirects and never content, false if the response type should depend on the request type (GET request -> content response; POST request -> redirect response).',
action: parsers.booleanParser,
default: false,
},
localizationFallbackLocale: {
env: 'PARSE_SERVER_PAGES_LOCALIZATION_FALLBACK_LOCALE',
help:
'The fallback locale for localization if no matching translation is provided for the given locale. This is only relevant when providing translation resources via JSON file.',
default: 'en',
},
localizationJsonPath: {
env: 'PARSE_SERVER_PAGES_LOCALIZATION_JSON_PATH',
help:
'The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale.',
},
pagesEndpoint: {
env: 'PARSE_SERVER_PAGES_PAGES_ENDPOINT',
help: "The API endpoint for the pages. Default is 'apps'.",
default: 'apps',
},
pagesPath: {
env: 'PARSE_SERVER_PAGES_PAGES_PATH',
help:
"The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory.",
default: './public',
},
placeholders: {
env: 'PARSE_SERVER_PAGES_PLACEHOLDERS',
help:
'The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function.',
action: parsers.objectParser,
default: {},
},
};
module.exports.PagesCustomUrlsOptions = {
emailVerificationLinkExpired: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_EXPIRED',
help: 'The URL to the custom page for email verification -> link expired.',
},
emailVerificationLinkInvalid: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_INVALID',
help: 'The URL to the custom page for email verification -> link invalid.',
},
emailVerificationSendFail: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_FAIL',
help: 'The URL to the custom page for email verification -> link send fail.',
},
emailVerificationSendSuccess: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_SUCCESS',
help: 'The URL to the custom page for email verification -> resend link -> success.',
},
emailVerificationSuccess: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SUCCESS',
help: 'The URL to the custom page for email verification -> success.',
},
passwordReset: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET',
help: 'The URL to the custom page for password reset.',
},
passwordResetLinkInvalid: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_LINK_INVALID',
help: 'The URL to the custom page for password reset -> link invalid.',
},
passwordResetSuccess: {
env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_SUCCESS',
help: 'The URL to the custom page for password reset -> success.',
},
};
module.exports.CustomPagesOptions = {
choosePassword: {
env: 'PARSE_SERVER_CUSTOM_PAGES_CHOOSE_PASSWORD',
help: 'choose password page path',
},
expiredVerificationLink: {
env: 'PARSE_SERVER_CUSTOM_PAGES_EXPIRED_VERIFICATION_LINK',
help: 'expired verification link page path',
},
invalidLink: {
env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_LINK',
help: 'invalid link page path',
},
invalidPasswordResetLink: {
env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_PASSWORD_RESET_LINK',
help: 'invalid password reset link page path',
},
invalidVerificationLink: {
env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_VERIFICATION_LINK',
help: 'invalid verification link page path',