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:
@@ -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',
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
* @property {String} mountPath Mount path for the server, defaults to /parse
|
||||
* @property {Boolean} mountPlayground Mounts the GraphQL Playground - never use this option in production
|
||||
* @property {Number} objectIdSize Sets the number of characters in generated object id's, default 10
|
||||
* @property {PagesOptions} pages The options for pages such as password reset and email verification. Caution, this is an experimental feature that may not be appropriate for production.
|
||||
* @property {PasswordPolicyOptions} passwordPolicy Password policy for enforcing password related rules
|
||||
* @property {String} playgroundPath Mount path for the GraphQL Playground, defaults to /playground
|
||||
* @property {Number} port The port to run the ParseServer, defaults to 1337.
|
||||
@@ -79,10 +80,37 @@
|
||||
* @property {String} webhookKey Key sent with outgoing webhook calls
|
||||
*/
|
||||
|
||||
/**
|
||||
* @interface PagesOptions
|
||||
* @property {PagesCustomUrlsOptions} customUrls The URLs to the custom pages.
|
||||
* @property {Boolean} enableLocalization Is true if pages should be localized; this has no effect on custom page redirects.
|
||||
* @property {Boolean} enableRouter 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.
|
||||
* @property {Boolean} forceRedirect 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).
|
||||
* @property {String} localizationFallbackLocale 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.
|
||||
* @property {String} localizationJsonPath The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale.
|
||||
* @property {String} pagesEndpoint The API endpoint for the pages. Default is 'apps'.
|
||||
* @property {String} pagesPath The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory.
|
||||
* @property {Object} placeholders The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @interface PagesCustomUrlsOptions
|
||||
* @property {String} emailVerificationLinkExpired The URL to the custom page for email verification -> link expired.
|
||||
* @property {String} emailVerificationLinkInvalid The URL to the custom page for email verification -> link invalid.
|
||||
* @property {String} emailVerificationSendFail The URL to the custom page for email verification -> link send fail.
|
||||
* @property {String} emailVerificationSendSuccess The URL to the custom page for email verification -> resend link -> success.
|
||||
* @property {String} emailVerificationSuccess The URL to the custom page for email verification -> success.
|
||||
* @property {String} passwordReset The URL to the custom page for password reset.
|
||||
* @property {String} passwordResetLinkInvalid The URL to the custom page for password reset -> link invalid.
|
||||
* @property {String} passwordResetSuccess The URL to the custom page for password reset -> success.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @interface CustomPagesOptions
|
||||
* @property {String} choosePassword choose password page path
|
||||
* @property {String} expiredVerificationLink expired verification link page path
|
||||
* @property {String} invalidLink invalid link page path
|
||||
* @property {String} invalidPasswordResetLink invalid password reset link page path
|
||||
* @property {String} invalidVerificationLink invalid verification link page path
|
||||
* @property {String} linkSendFail verification link send fail page path
|
||||
* @property {String} linkSendSuccess verification link send success page path
|
||||
|
||||
@@ -138,6 +138,9 @@ export interface ParseServerOptions {
|
||||
/* Public URL to your parse server with http:// or https://.
|
||||
:ENV: PARSE_PUBLIC_SERVER_URL */
|
||||
publicServerURL: ?string;
|
||||
/* The options for pages such as password reset and email verification. Caution, this is an experimental feature that may not be appropriate for production.
|
||||
:DEFAULT: {} */
|
||||
pages: ?PagesOptions;
|
||||
/* custom pages for password validation and reset
|
||||
:DEFAULT: {} */
|
||||
customPages: ?CustomPagesOptions;
|
||||
@@ -226,21 +229,73 @@ export interface ParseServerOptions {
|
||||
serverCloseComplete: ?() => void;
|
||||
}
|
||||
|
||||
export interface PagesOptions {
|
||||
/* 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.
|
||||
:DEFAULT: false */
|
||||
enableRouter: ?boolean;
|
||||
/* Is true if pages should be localized; this has no effect on custom page redirects.
|
||||
:DEFAULT: false */
|
||||
enableLocalization: ?boolean;
|
||||
/* The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale. */
|
||||
localizationJsonPath: ?string;
|
||||
/* 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 */
|
||||
localizationFallbackLocale: ?string;
|
||||
/* The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function.
|
||||
:DEFAULT: {} */
|
||||
placeholders: ?Object;
|
||||
/* 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).
|
||||
:DEFAULT: false */
|
||||
forceRedirect: ?boolean;
|
||||
/* The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory.
|
||||
:DEFAULT: ./public */
|
||||
pagesPath: ?string;
|
||||
/* The API endpoint for the pages. Default is 'apps'.
|
||||
:DEFAULT: apps */
|
||||
pagesEndpoint: ?string;
|
||||
/* The URLs to the custom pages.
|
||||
:DEFAULT: {} */
|
||||
customUrls: ?PagesCustomUrlsOptions;
|
||||
}
|
||||
|
||||
export interface PagesCustomUrlsOptions {
|
||||
/* The URL to the custom page for password reset. */
|
||||
passwordReset: ?string;
|
||||
/* The URL to the custom page for password reset -> link invalid. */
|
||||
passwordResetLinkInvalid: ?string;
|
||||
/* The URL to the custom page for password reset -> success. */
|
||||
passwordResetSuccess: ?string;
|
||||
/* The URL to the custom page for email verification -> success. */
|
||||
emailVerificationSuccess: ?string;
|
||||
/* The URL to the custom page for email verification -> link send fail. */
|
||||
emailVerificationSendFail: ?string;
|
||||
/* The URL to the custom page for email verification -> resend link -> success. */
|
||||
emailVerificationSendSuccess: ?string;
|
||||
/* The URL to the custom page for email verification -> link invalid. */
|
||||
emailVerificationLinkInvalid: ?string;
|
||||
/* The URL to the custom page for email verification -> link expired. */
|
||||
emailVerificationLinkExpired: ?string;
|
||||
}
|
||||
|
||||
export interface CustomPagesOptions {
|
||||
/* invalid link page path */
|
||||
invalidLink: ?string;
|
||||
/* verify email success page path */
|
||||
verifyEmailSuccess: ?string;
|
||||
/* invalid verification link page path */
|
||||
invalidVerificationLink: ?string;
|
||||
/* verification link send success page path */
|
||||
linkSendSuccess: ?string;
|
||||
/* verification link send fail page path */
|
||||
linkSendFail: ?string;
|
||||
/* choose password page path */
|
||||
choosePassword: ?string;
|
||||
/* verification link send success page path */
|
||||
linkSendSuccess: ?string;
|
||||
/* verify email success page path */
|
||||
verifyEmailSuccess: ?string;
|
||||
/* password reset success page path */
|
||||
passwordResetSuccess: ?string;
|
||||
/* invalid verification link page path */
|
||||
invalidVerificationLink: ?string;
|
||||
/* expired verification link page path */
|
||||
expiredVerificationLink: ?string;
|
||||
/* invalid password reset link page path */
|
||||
invalidPasswordResetLink: ?string;
|
||||
/* for masking user-facing pages */
|
||||
parseFrameURL: ?string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user