From 40f0aa2c111f95d3cff575bbd7fdfa7bf9868abc Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 10 Jan 2025 13:20:08 +1100 Subject: [PATCH 1/5] feat: deprecate PublicAPIRouter --- DEPRECATIONS.md | 1 + README.md | 20 ++++++++------------ src/Options/Definitions.js | 5 ++--- src/Options/docs.js | 4 ++-- src/Options/index.js | 4 ++-- src/Routers/PublicAPIRouter.js | 7 +++++++ 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index af683c2d46..8cbc603617 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -14,6 +14,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h | DEPPS8 | Login with expired 3rd party authentication token defaults to `false` | [#7079](https://github.com/parse-community/parse-server/pull/7079) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - | | DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | removed | - | | DEPPS10 | Config option `encodeParseObjectInCloudFunction` defaults to `true` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 8.0.0 (2025) | deprecated | - | +| DEPPS11 | Config option `pages.enableRouter` defaults to `true` | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | deprecated | - | [i_deprecation]: ## "The version and date of the deprecation." [i_removal]: ## "The version and date of the planned removal." diff --git a/README.md b/README.md index da5be58f50..3dbe8f57da 100644 --- a/README.md +++ b/README.md @@ -440,8 +440,6 @@ const server = ParseServer({ ## Custom Routes -**Caution, this is an experimental feature that may not be appropriate for production.** - Custom routes allow to build user flows with webpages, similar to the existing password reset and email verification features. Custom routes are defined with the `pages` option in the Parse Server configuration: ### Example @@ -451,7 +449,7 @@ const api = new ParseServer({ ...otherOptions, pages: { - enableRouter: true, // Enables the experimental feature; required for custom routes + enableRouter: true, customRoutes: [{ method: 'GET', path: 'custom_route', @@ -488,7 +486,7 @@ The following paths are already used by Parse Server's built-in features and are | Parameter | Optional | Type | Default value | Example values | Environment variable | Description | |------------------------------|----------|-----------------|---------------|-----------------------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `pages` | yes | `Object` | `undefined` | - | `PARSE_SERVER_PAGES` | The options for pages such as password reset and email verification. | -| `pages.enableRouter` | yes | `Boolean` | `false` | - | `PARSE_SERVER_PAGES_ENABLE_ROUTER` | 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.** | +| `pages.enableRouter` | yes | `Boolean` | `false` | - | `PARSE_SERVER_PAGES_ENABLE_ROUTER` | Is `true` if the pages router should be enabled; this is required for any of the pages options to take effect. | | `pages.customRoutes` | yes | `Array` | `[]` | - | `PARSE_SERVER_PAGES_CUSTOM_ROUTES` | The custom routes. The routes are added in the order they are defined here, which has to be considered since requests traverse routes in an ordered manner. Custom routes are traversed after build-in routes such as password reset and email verification. | | `pages.customRoutes.method` | | `String` | - | `GET`, `POST` | - | The HTTP method of the custom route. | | `pages.customRoutes.path` | | `String` | - | `custom_page` | - | The path of the custom route. Note that the same path can used if the `method` is different, for example a path `custom_page` can have two routes, a `GET` and `POST` route, which will be invoked depending on the HTTP request method. | @@ -611,8 +609,6 @@ Assuming the script above is named, `parse_idempotency_delete_expired_records.sh ### Pages -**Caution, this is an experimental feature that may not be appropriate for production.** - Custom pages as well as feature pages (e.g. password reset, email verification) can be localized with the `pages` option in the Parse Server configuration: ```js @@ -620,7 +616,7 @@ const api = new ParseServer({ ...otherOptions, pages: { - enableRouter: true, // Enables the experimental feature; required for localization + enableRouter: true, enableLocalization: true, } } @@ -668,7 +664,7 @@ const api = new ParseServer({ ...otherOptions, pages: { - enableRouter: true, // Enables the experimental feature; required for localization + enableRouter: true, enableLocalization: true, customUrls: { passwordReset: 'https://example.com/page.html' @@ -725,7 +721,7 @@ const api = new ParseServer({ ...otherOptions, pages: { - enableRouter: true, // Enables the experimental feature; required for localization + enableRouter: true, enableLocalization: true, localizationJsonPath: './private/localization.json', localizationFallbackLocale: 'en' @@ -750,7 +746,7 @@ const api = new ParseServer({ ...otherOptions, pages: { - enableRouter: true, // Enables the experimental feature; required for localization + enableRouter: true, placeholders: { exampleKey: 'exampleValue' } @@ -764,7 +760,7 @@ const api = new ParseServer({ ...otherOptions, pages: { - enableRouter: true, // Enables the experimental feature; required for localization + enableRouter: true, placeholders: async (params) => { const value = await doSomething(params.locale); return { @@ -784,7 +780,7 @@ The following parameter and placeholder keys are reserved because they are used | Parameter | Optional | Type | Default value | Example values | Environment variable | Description | |-------------------------------------------------|----------|---------------------------------------|----------------------------------------|------------------------------------------------------|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `pages` | yes | `Object` | `undefined` | - | `PARSE_SERVER_PAGES` | The options for pages such as password reset and email verification. | -| `pages.enableRouter` | yes | `Boolean` | `false` | - | `PARSE_SERVER_PAGES_ENABLE_ROUTER` | 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.** | +| `pages.enableRouter` | yes | `Boolean` | `false` | - | `PARSE_SERVER_PAGES_ENABLE_ROUTER` | Is `true` if the pages router should be enabled; this is required for any of the pages options to take effect. | | `pages.enableLocalization` | yes | `Boolean` | `false` | - | `PARSE_SERVER_PAGES_ENABLE_LOCALIZATION` | Is true if pages should be localized; this has no effect on custom page redirects. | | `pages.localizationJsonPath` | yes | `String` | `undefined` | `./private/translations.json` | `PARSE_SERVER_PAGES_LOCALIZATION_JSON_PATH` | The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale. | | `pages.localizationFallbackLocale` | yes | `String` | `en` | `en`, `en-GB`, `default` | `PARSE_SERVER_PAGES_LOCALIZATION_FALLBACK_LOCALE` | 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. | diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index a1da6c09a7..0fdc3b11e1 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -414,8 +414,7 @@ module.exports.ParseServerOptions = { }, 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.', + help: 'The options for pages such as password reset and email verification.', action: parsers.objectParser, type: 'PagesOptions', default: {}, @@ -698,7 +697,7 @@ module.exports.PagesOptions = { 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.', + 'Is true if the pages router should be enabled; this is required for any of the pages options to take effect.', action: parsers.booleanParser, default: false, }, diff --git a/src/Options/docs.js b/src/Options/docs.js index 4c2883adaa..a425a85591 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -75,7 +75,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 {PagesOptions} pages The options for pages such as password reset and email verification. * @property {PasswordPolicyOptions} passwordPolicy The 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. @@ -131,7 +131,7 @@ * @property {PagesRoute[]} customRoutes The custom routes. * @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} enableRouter Is true if the pages router should be enabled; this is required for any of the pages options to take effect. * @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. diff --git a/src/Options/index.js b/src/Options/index.js index 40e15afb27..3ad1919ec4 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -217,7 +217,7 @@ 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. + /* The options for pages such as password reset and email verification. :DEFAULT: {} */ pages: ?PagesOptions; /* custom pages for password validation and reset @@ -377,7 +377,7 @@ export interface SecurityOptions { } 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. + /* Is true if the pages router should be enabled; this is required for any of the pages options to take effect. :DEFAULT: false */ enableRouter: ?boolean; /* Is true if pages should be localized; this has no effect on custom page redirects. diff --git a/src/Routers/PublicAPIRouter.js b/src/Routers/PublicAPIRouter.js index ddef76a5b8..dde43897b5 100644 --- a/src/Routers/PublicAPIRouter.js +++ b/src/Routers/PublicAPIRouter.js @@ -5,11 +5,18 @@ import path from 'path'; import fs from 'fs'; import qs from 'querystring'; import { Parse } from 'parse/node'; +import Deprecator from '../Deprecator'; const public_html = path.resolve(__dirname, '../../public_html'); const views = path.resolve(__dirname, '../../views'); export class PublicAPIRouter extends PromiseRouter { + constructor() { + Deprecator.logRuntimeDeprecation({ + usage: 'PublicAPIRouter', + solution: 'pages.enableRouter' + }); + } verifyEmail(req) { const { username, token: rawToken } = req.query; const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; From 744f7a13df73fcd2078bfd9903424b012d80f0fd Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 10 Jan 2025 13:26:41 +1100 Subject: [PATCH 2/5] Update PublicAPIRouter.js --- src/Routers/PublicAPIRouter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Routers/PublicAPIRouter.js b/src/Routers/PublicAPIRouter.js index dde43897b5..aa6cf22f84 100644 --- a/src/Routers/PublicAPIRouter.js +++ b/src/Routers/PublicAPIRouter.js @@ -12,6 +12,7 @@ const views = path.resolve(__dirname, '../../views'); export class PublicAPIRouter extends PromiseRouter { constructor() { + super(); Deprecator.logRuntimeDeprecation({ usage: 'PublicAPIRouter', solution: 'pages.enableRouter' From 60b30a8b9ccfcf87d7d72d4473c8dcfee8326ec4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 10 Jan 2025 13:41:54 +1100 Subject: [PATCH 3/5] Update PublicAPIRouter.js --- src/Routers/PublicAPIRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Routers/PublicAPIRouter.js b/src/Routers/PublicAPIRouter.js index aa6cf22f84..625b3d458a 100644 --- a/src/Routers/PublicAPIRouter.js +++ b/src/Routers/PublicAPIRouter.js @@ -5,7 +5,7 @@ import path from 'path'; import fs from 'fs'; import qs from 'querystring'; import { Parse } from 'parse/node'; -import Deprecator from '../Deprecator'; +import Deprecator from '../Deprecator/Deprecator'; const public_html = path.resolve(__dirname, '../../public_html'); const views = path.resolve(__dirname, '../../views'); From f239f481747e66a6cf6d56b6c65f19fafc52a6d9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 11 Jan 2025 19:42:50 +1100 Subject: [PATCH 4/5] Update DEPRECATIONS.md --- DEPRECATIONS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index 8cbc603617..0e2062796f 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -14,7 +14,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h | DEPPS8 | Login with expired 3rd party authentication token defaults to `false` | [#7079](https://github.com/parse-community/parse-server/pull/7079) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - | | DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | removed | - | | DEPPS10 | Config option `encodeParseObjectInCloudFunction` defaults to `true` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 8.0.0 (2025) | deprecated | - | -| DEPPS11 | Config option `pages.enableRouter` defaults to `true` | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | deprecated | - | +| DEPPS11 | Remove legacy PublicAPIRouter | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | deprecated | - | [i_deprecation]: ## "The version and date of the deprecation." [i_removal]: ## "The version and date of the planned removal." From ce0ddaa307907b8bd3ac8145e919b30147b6c5a3 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Sun, 12 Jan 2025 01:49:51 +0100 Subject: [PATCH 5/5] Update DEPRECATIONS.md Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- DEPRECATIONS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index 0e2062796f..e88edf4edd 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -14,7 +14,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h | DEPPS8 | Login with expired 3rd party authentication token defaults to `false` | [#7079](https://github.com/parse-community/parse-server/pull/7079) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - | | DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | removed | - | | DEPPS10 | Config option `encodeParseObjectInCloudFunction` defaults to `true` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 8.0.0 (2025) | deprecated | - | -| DEPPS11 | Remove legacy PublicAPIRouter | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | deprecated | - | +| DEPPS11 | Replace `PublicAPIRouter` with `PagesRouter` | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | deprecated | - | [i_deprecation]: ## "The version and date of the deprecation." [i_removal]: ## "The version and date of the planned removal."