3 Commits

Author SHA1 Message Date
semantic-release-bot
97de70a017 chore(release): 9.3.0-alpha.2 [skip ci]
# [9.3.0-alpha.2](https://github.com/parse-community/parse-server/compare/9.3.0-alpha.1...9.3.0-alpha.2) (2026-02-06)

### Bug Fixes

* Default HTML pages for password reset, email verification not found ([#10041](https://github.com/parse-community/parse-server/issues/10041)) ([a4265bb](a4265bb124))
2026-02-06 16:31:03 +00:00
Manuel
a4265bb124 fix: Default HTML pages for password reset, email verification not found (#10041) 2026-02-06 16:30:13 +00:00
dependabot[bot]
c1f1800cad refactor: Bump commander from 14.0.2 to 14.0.3 (#10039) 2026-02-06 15:19:51 +00:00
8 changed files with 53 additions and 22 deletions

View File

@@ -1,3 +1,10 @@
# [9.3.0-alpha.2](https://github.com/parse-community/parse-server/compare/9.3.0-alpha.1...9.3.0-alpha.2) (2026-02-06)
### Bug Fixes
* Default HTML pages for password reset, email verification not found ([#10041](https://github.com/parse-community/parse-server/issues/10041)) ([a4265bb](https://github.com/parse-community/parse-server/commit/a4265bb1241551b7147e8aee08c36e1f8ab09ba4))
# [9.3.0-alpha.1](https://github.com/parse-community/parse-server/compare/9.2.1-alpha.2...9.3.0-alpha.1) (2026-02-06)

18
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "parse-server",
"version": "9.3.0-alpha.1",
"version": "9.3.0-alpha.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "parse-server",
"version": "9.3.0-alpha.1",
"version": "9.3.0-alpha.2",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -18,7 +18,7 @@
"@parse/fs-files-adapter": "3.0.0",
"@parse/push-adapter": "8.2.0",
"bcryptjs": "3.0.3",
"commander": "14.0.2",
"commander": "14.0.3",
"cors": "2.8.6",
"deepcopy": "2.1.0",
"express": "5.2.1",
@@ -8555,9 +8555,9 @@
}
},
"node_modules/commander": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz",
"integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==",
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
"engines": {
"node": ">=20"
}
@@ -28403,9 +28403,9 @@
}
},
"commander": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz",
"integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="
},
"commondir": {
"version": "1.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "parse-server",
"version": "9.3.0-alpha.1",
"version": "9.3.0-alpha.2",
"description": "An express module providing a Parse-compatible API server",
"main": "lib/index.js",
"repository": {
@@ -28,7 +28,7 @@
"@parse/fs-files-adapter": "3.0.0",
"@parse/push-adapter": "8.2.0",
"bcryptjs": "3.0.3",
"commander": "14.0.2",
"commander": "14.0.3",
"cors": "2.8.6",
"deepcopy": "2.1.0",
"express": "5.2.1",

View File

@@ -225,9 +225,7 @@ describe('Pages Router', () => {
expect(Config.get(Parse.applicationId).pages.forceRedirect).toBe(
Definitions.PagesOptions.forceRedirect.default
);
expect(Config.get(Parse.applicationId).pages.pagesPath).toBe(
Definitions.PagesOptions.pagesPath.default
);
expect(Config.get(Parse.applicationId).pages.pagesPath).toBeUndefined();
expect(Config.get(Parse.applicationId).pages.pagesEndpoint).toBe(
Definitions.PagesOptions.pagesEndpoint.default
);
@@ -1236,6 +1234,36 @@ describe('Pages Router', () => {
});
});
describe('pagesPath resolution', () => {
it('should serve pages when current working directory differs from module directory', async () => {
const originalCwd = process.cwd();
const os = require('os');
process.chdir(os.tmpdir());
try {
await reconfigureServer({
appId: 'test',
appName: 'exampleAppname',
publicServerURL: 'http://localhost:8378/1',
pages: { enableRouter: true },
});
// Request the password reset page with an invalid token;
// even with an invalid token, the server should serve the
// "invalid link" page (200), not a 404. A 404 indicates the
// HTML template files could not be found because pagesPath
// resolved to the wrong directory.
const response = await request({
url: 'http://localhost:8378/1/apps/test/request_password_reset?token=invalidToken',
}).catch(e => e);
expect(response.status).toBe(200);
expect(response.text).toContain('Invalid password reset link');
} finally {
process.chdir(originalCwd);
}
});
});
describe('XSS Protection', () => {
beforeEach(async () => {
await reconfigureServer({

View File

@@ -326,9 +326,7 @@ export class Config {
} else if (!isBoolean(pages.forceRedirect)) {
throw 'Parse Server option pages.forceRedirect must be a boolean.';
}
if (pages.pagesPath === undefined) {
pages.pagesPath = PagesOptions.pagesPath.default;
} else if (!isString(pages.pagesPath)) {
if (pages.pagesPath !== undefined && !isString(pages.pagesPath)) {
throw 'Parse Server option pages.pagesPath must be a string.';
}
if (pages.pagesEndpoint === undefined) {

View File

@@ -772,8 +772,7 @@ module.exports.PagesOptions = {
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',
"The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory of the parse-server module.",
},
placeholders: {
env: 'PARSE_SERVER_PAGES_PLACEHOLDERS',

View File

@@ -142,7 +142,7 @@
* @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 {String} pagesPath The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory of the parse-server module.
* @property {Object} placeholders The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function.
*/

View File

@@ -437,8 +437,7 @@ export interface PagesOptions {
/* 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 */
/* The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory of the parse-server module. */
pagesPath: ?string;
/* The API endpoint for the pages. Default is 'apps'.
:DEFAULT: apps */