build: Release (#9905)
This commit is contained in:
26
.github/workflows/ci.yml
vendored
26
.github/workflows/ci.yml
vendored
@@ -8,7 +8,7 @@ on:
|
|||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**/**.md'
|
- '**/**.md'
|
||||||
env:
|
env:
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
PARSE_SERVER_TEST_TIMEOUT: 20000
|
PARSE_SERVER_TEST_TIMEOUT: 20000
|
||||||
permissions:
|
permissions:
|
||||||
actions: write
|
actions: write
|
||||||
@@ -156,20 +156,20 @@ jobs:
|
|||||||
- name: MongoDB 6, ReplicaSet
|
- name: MongoDB 6, ReplicaSet
|
||||||
MONGODB_VERSION: 6.0.19
|
MONGODB_VERSION: 6.0.19
|
||||||
MONGODB_TOPOLOGY: replset
|
MONGODB_TOPOLOGY: replset
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: MongoDB 7, ReplicaSet
|
- name: MongoDB 7, ReplicaSet
|
||||||
MONGODB_VERSION: 7.0.16
|
MONGODB_VERSION: 7.0.16
|
||||||
MONGODB_TOPOLOGY: replset
|
MONGODB_TOPOLOGY: replset
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: MongoDB 8, ReplicaSet
|
- name: MongoDB 8, ReplicaSet
|
||||||
MONGODB_VERSION: 8.0.4
|
MONGODB_VERSION: 8.0.4
|
||||||
MONGODB_TOPOLOGY: replset
|
MONGODB_TOPOLOGY: replset
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: Redis Cache
|
- name: Redis Cache
|
||||||
PARSE_SERVER_TEST_CACHE: redis
|
PARSE_SERVER_TEST_CACHE: redis
|
||||||
MONGODB_VERSION: 8.0.4
|
MONGODB_VERSION: 8.0.4
|
||||||
MONGODB_TOPOLOGY: standalone
|
MONGODB_TOPOLOGY: standalone
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: Node 20
|
- name: Node 20
|
||||||
MONGODB_VERSION: 8.0.4
|
MONGODB_VERSION: 8.0.4
|
||||||
MONGODB_TOPOLOGY: standalone
|
MONGODB_TOPOLOGY: standalone
|
||||||
@@ -178,6 +178,10 @@ jobs:
|
|||||||
MONGODB_VERSION: 8.0.4
|
MONGODB_VERSION: 8.0.4
|
||||||
MONGODB_TOPOLOGY: standalone
|
MONGODB_TOPOLOGY: standalone
|
||||||
NODE_VERSION: 18.20.4
|
NODE_VERSION: 18.20.4
|
||||||
|
- name: Node 22
|
||||||
|
MONGODB_VERSION: 8.0.4
|
||||||
|
MONGODB_TOPOLOGY: standalone
|
||||||
|
NODE_VERSION: 22.12.0
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
@@ -225,22 +229,22 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- name: PostgreSQL 15, PostGIS 3.3
|
- name: PostgreSQL 15, PostGIS 3.3
|
||||||
POSTGRES_IMAGE: postgis/postgis:15-3.3
|
POSTGRES_IMAGE: postgis/postgis:15-3.3
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: PostgreSQL 15, PostGIS 3.4
|
- name: PostgreSQL 15, PostGIS 3.4
|
||||||
POSTGRES_IMAGE: postgis/postgis:15-3.4
|
POSTGRES_IMAGE: postgis/postgis:15-3.4
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: PostgreSQL 15, PostGIS 3.5
|
- name: PostgreSQL 15, PostGIS 3.5
|
||||||
POSTGRES_IMAGE: postgis/postgis:15-3.5
|
POSTGRES_IMAGE: postgis/postgis:15-3.5
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: PostgreSQL 16, PostGIS 3.5
|
- name: PostgreSQL 16, PostGIS 3.5
|
||||||
POSTGRES_IMAGE: postgis/postgis:16-3.5
|
POSTGRES_IMAGE: postgis/postgis:16-3.5
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: PostgreSQL 17, PostGIS 3.5
|
- name: PostgreSQL 17, PostGIS 3.5
|
||||||
POSTGRES_IMAGE: postgis/postgis:17-3.5
|
POSTGRES_IMAGE: postgis/postgis:17-3.5
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
- name: PostgreSQL 18, PostGIS 3.6
|
- name: PostgreSQL 18, PostGIS 3.6
|
||||||
POSTGRES_IMAGE: postgis/postgis:18-3.6
|
POSTGRES_IMAGE: postgis/postgis:18-3.6
|
||||||
NODE_VERSION: 22.12.0
|
NODE_VERSION: 24.11.0
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
|
|||||||
44
.github/workflows/release-manual-docs.yml
vendored
Normal file
44
.github/workflows/release-manual-docs.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Trigger this workflow only to manually create a docs release; this should only be used
|
||||||
|
# in extraordinary circumstances, as docs releases are normally created automatically as
|
||||||
|
# part of the automated release workflow.
|
||||||
|
|
||||||
|
name: release-manual-docs
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
ref:
|
||||||
|
default: ''
|
||||||
|
description: 'Reference (tag / SHA):'
|
||||||
|
required: true
|
||||||
|
jobs:
|
||||||
|
docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.inputs.ref }}
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18.20.4
|
||||||
|
- name: Cache Node.js modules
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
- name: Generate Docs
|
||||||
|
run: |
|
||||||
|
echo $SOURCE_TAG
|
||||||
|
npm ci
|
||||||
|
./release_docs.sh
|
||||||
|
env:
|
||||||
|
SOURCE_TAG: ${{ github.event.inputs.ref }}
|
||||||
|
- name: Deploy
|
||||||
|
uses: peaceiris/actions-gh-pages@v3.7.3
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
publish_dir: ./docs
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
[](https://app.codecov.io/github/parse-community/parse-server/tree/alpha)
|
[](https://app.codecov.io/github/parse-community/parse-server/tree/alpha)
|
||||||
[](https://github.com/parse-community/parse-dashboard/releases)
|
[](https://github.com/parse-community/parse-dashboard/releases)
|
||||||
|
|
||||||
[](https://nodejs.org)
|
[](https://nodejs.org)
|
||||||
[](https://www.mongodb.com)
|
[](https://www.mongodb.com)
|
||||||
[](https://www.postgresql.org)
|
[](https://www.postgresql.org)
|
||||||
|
|
||||||
@@ -130,6 +130,7 @@ Parse Server is continuously tested with the most recent releases of Node.js to
|
|||||||
| Node.js 18 | 18.20.4 | April 2025 | <= 8.x (2025) |
|
| Node.js 18 | 18.20.4 | April 2025 | <= 8.x (2025) |
|
||||||
| Node.js 20 | 20.18.0 | April 2026 | <= 9.x (2026) |
|
| Node.js 20 | 20.18.0 | April 2026 | <= 9.x (2026) |
|
||||||
| Node.js 22 | 22.12.0 | April 2027 | <= 10.x (2027) |
|
| Node.js 22 | 22.12.0 | April 2027 | <= 10.x (2027) |
|
||||||
|
| Node.js 24 | 24.11.0 | April 2028 | <= 11.x (2028) |
|
||||||
|
|
||||||
#### MongoDB
|
#### MongoDB
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,24 @@
|
|||||||
|
# [8.4.0-alpha.2](https://github.com/parse-community/parse-server/compare/8.4.0-alpha.1...8.4.0-alpha.2) (2025-11-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Uploading a file by providing an origin URL allows for Server-Side Request Forgery (SSRF); fixes vulnerability [GHSA-x4qj-2f4q-r4rx](https://github.com/parse-community/parse-server/security/advisories/GHSA-x4qj-2f4q-r4rx) ([#9903](https://github.com/parse-community/parse-server/issues/9903)) ([9776386](https://github.com/parse-community/parse-server/commit/97763863b72689a29ad7a311dfb590c3e3c50585))
|
||||||
|
|
||||||
|
# [8.4.0-alpha.1](https://github.com/parse-community/parse-server/compare/8.3.1-alpha.1...8.4.0-alpha.1) (2025-11-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add support for Node 24 ([#9901](https://github.com/parse-community/parse-server/issues/9901)) ([25dfe19](https://github.com/parse-community/parse-server/commit/25dfe19fef02fd44224e4a6d198584a694a1aa52))
|
||||||
|
|
||||||
|
## [8.3.1-alpha.1](https://github.com/parse-community/parse-server/compare/8.3.0...8.3.1-alpha.1) (2025-11-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Add problematic MIME types to default value of Parse Server option `fileUpload.fileExtensions` ([#9902](https://github.com/parse-community/parse-server/issues/9902)) ([fa245cb](https://github.com/parse-community/parse-server/commit/fa245cbb5f5b7a0dad962b2ce0524fa4dafcb5f7))
|
||||||
|
|
||||||
# [8.3.0-alpha.14](https://github.com/parse-community/parse-server/compare/8.3.0-alpha.13...8.3.0-alpha.14) (2025-11-01)
|
# [8.3.0-alpha.14](https://github.com/parse-community/parse-server/compare/8.3.0-alpha.13...8.3.0-alpha.14) (2025-11-01)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
"source": {
|
"source": {
|
||||||
"include": [
|
"include": [
|
||||||
"README.md",
|
"README.md",
|
||||||
"./src/cloud-code",
|
"./lib/cloud-code",
|
||||||
"./src/Options/docs.js",
|
"./lib/Options/docs.js",
|
||||||
"./src/ParseServer.js",
|
"./lib/ParseServer.js",
|
||||||
"./src/Adapters"
|
"./lib/Adapters"
|
||||||
],
|
],
|
||||||
"excludePattern": "(^|\\/|\\\\)_"
|
"excludePattern": "(^|\\/|\\\\)_"
|
||||||
},
|
},
|
||||||
|
|||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "parse-server",
|
"name": "parse-server",
|
||||||
"version": "8.3.0",
|
"version": "8.4.0-alpha.2",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "parse-server",
|
"name": "parse-server",
|
||||||
"version": "8.3.0",
|
"version": "8.4.0-alpha.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
"yaml": "2.8.0"
|
"yaml": "2.8.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.20.4 <19.0.0 || >=20.18.0 <21.0.0 || >=22.12.0 <23.0.0"
|
"node": ">=18.20.4 <19.0.0 || >=20.18.0 <21.0.0 || >=22.12.0 <23.0.0 || >=24.11.0 <25.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parse-server",
|
"name": "parse-server",
|
||||||
"version": "8.3.0",
|
"version": "8.4.0-alpha.2",
|
||||||
"description": "An express module providing a Parse-compatible API server",
|
"description": "An express module providing a Parse-compatible API server",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
},
|
},
|
||||||
"types": "types/index.d.ts",
|
"types": "types/index.d.ts",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.20.4 <19.0.0 || >=20.18.0 <21.0.0 || >=22.12.0 <23.0.0"
|
"node": ">=18.20.4 <19.0.0 || >=20.18.0 <21.0.0 || >=22.12.0 <23.0.0 || >=24.11.0 <25.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"parse-server": "bin/parse-server"
|
"parse-server": "bin/parse-server"
|
||||||
|
|||||||
@@ -653,6 +653,80 @@ describe('Parse.File testing', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('URI-backed file upload is disabled to prevent SSRF attack', () => {
|
||||||
|
const express = require('express');
|
||||||
|
let testServer;
|
||||||
|
let testServerPort;
|
||||||
|
let requestsMade;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
requestsMade = [];
|
||||||
|
const app = express();
|
||||||
|
app.use((req, res) => {
|
||||||
|
requestsMade.push({ url: req.url, method: req.method });
|
||||||
|
res.status(200).send('test file content');
|
||||||
|
});
|
||||||
|
testServer = app.listen(0);
|
||||||
|
testServerPort = testServer.address().port;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
if (testServer) {
|
||||||
|
await new Promise(resolve => testServer.close(resolve));
|
||||||
|
}
|
||||||
|
Parse.Cloud._removeAllHooks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not access URI when file upload attempted over REST', async () => {
|
||||||
|
const response = await request({
|
||||||
|
method: 'POST',
|
||||||
|
url: 'http://localhost:8378/1/classes/TestClass',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
file: {
|
||||||
|
__type: 'File',
|
||||||
|
name: 'test.txt',
|
||||||
|
_source: {
|
||||||
|
format: 'uri',
|
||||||
|
uri: `http://127.0.0.1:${testServerPort}/secret-file.txt`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(response.status).toBe(201);
|
||||||
|
// Verify no HTTP request was made to the URI
|
||||||
|
expect(requestsMade.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not access URI when file created in beforeSave trigger', async () => {
|
||||||
|
Parse.Cloud.beforeSave(Parse.File, () => {
|
||||||
|
return new Parse.File('trigger-file.txt', {
|
||||||
|
uri: `http://127.0.0.1:${testServerPort}/secret-file.txt`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await expectAsync(
|
||||||
|
request({
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/octet-stream',
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
url: 'http://localhost:8378/1/files/test.txt',
|
||||||
|
body: 'test content',
|
||||||
|
})
|
||||||
|
).toBeRejectedWith(jasmine.objectContaining({
|
||||||
|
status: 400
|
||||||
|
}));
|
||||||
|
// Verify no HTTP request was made to the URI
|
||||||
|
expect(requestsMade.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deleting files', () => {
|
describe('deleting files', () => {
|
||||||
|
|||||||
@@ -1077,9 +1077,9 @@ module.exports.FileUploadOptions = {
|
|||||||
fileExtensions: {
|
fileExtensions: {
|
||||||
env: 'PARSE_SERVER_FILE_UPLOAD_FILE_EXTENSIONS',
|
env: 'PARSE_SERVER_FILE_UPLOAD_FILE_EXTENSIONS',
|
||||||
help:
|
help:
|
||||||
"Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!(h|H)(t|T)(m|M)(l|L)?$)` which allows any file extension except HTML files.",
|
"Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?![xXsS]?[hH][tT][mM][lL]?$)` which allows any file extension except those MIME types that are mapped to `text/html` and are rendered as website by a web browser.",
|
||||||
action: parsers.arrayParser,
|
action: parsers.arrayParser,
|
||||||
default: ['^(?!(h|H)(t|T)(m|M)(l|L)?$)'],
|
default: ['^(?![xXsS]?[hH][tT][mM][lL]?$)'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
module.exports.DatabaseOptions = {
|
module.exports.DatabaseOptions = {
|
||||||
|
|||||||
@@ -235,7 +235,7 @@
|
|||||||
* @property {Boolean} enableForAnonymousUser Is true if file upload should be allowed for anonymous users.
|
* @property {Boolean} enableForAnonymousUser Is true if file upload should be allowed for anonymous users.
|
||||||
* @property {Boolean} enableForAuthenticatedUser Is true if file upload should be allowed for authenticated users.
|
* @property {Boolean} enableForAuthenticatedUser Is true if file upload should be allowed for authenticated users.
|
||||||
* @property {Boolean} enableForPublic Is true if file upload should be allowed for anyone, regardless of user authentication.
|
* @property {Boolean} enableForPublic Is true if file upload should be allowed for anyone, regardless of user authentication.
|
||||||
* @property {String[]} fileExtensions Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!(h|H)(t|T)(m|M)(l|L)?$)` which allows any file extension except HTML files.
|
* @property {String[]} fileExtensions Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?![xXsS]?[hH][tT][mM][lL]?$)` which allows any file extension except those MIME types that are mapped to `text/html` and are rendered as website by a web browser.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -594,8 +594,8 @@ export interface PasswordPolicyOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FileUploadOptions {
|
export interface FileUploadOptions {
|
||||||
/* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!(h|H)(t|T)(m|M)(l|L)?$)` which allows any file extension except HTML files.
|
/* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?![xXsS]?[hH][tT][mM][lL]?$)` which allows any file extension except those MIME types that are mapped to `text/html` and are rendered as website by a web browser.
|
||||||
:DEFAULT: ["^(?!(h|H)(t|T)(m|M)(l|L)?$)"] */
|
:DEFAULT: ["^(?![xXsS]?[hH][tT][mM][lL]?$)"] */
|
||||||
fileExtensions: ?(string[]);
|
fileExtensions: ?(string[]);
|
||||||
/* Is true if file upload should be allowed for anonymous users.
|
/* Is true if file upload should be allowed for anonymous users.
|
||||||
:DEFAULT: false */
|
:DEFAULT: false */
|
||||||
|
|||||||
@@ -4,34 +4,8 @@ import Parse from 'parse/node';
|
|||||||
import Config from '../Config';
|
import Config from '../Config';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
const triggers = require('../triggers');
|
const triggers = require('../triggers');
|
||||||
const http = require('http');
|
|
||||||
const Utils = require('../Utils');
|
const Utils = require('../Utils');
|
||||||
|
|
||||||
const downloadFileFromURI = uri => {
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
http
|
|
||||||
.get(uri, response => {
|
|
||||||
response.setDefaultEncoding('base64');
|
|
||||||
let body = `data:${response.headers['content-type']};base64,`;
|
|
||||||
response.on('data', data => (body += data));
|
|
||||||
response.on('end', () => res(body));
|
|
||||||
})
|
|
||||||
.on('error', e => {
|
|
||||||
rej(`Error downloading file from ${uri}: ${e.message}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const addFileDataIfNeeded = async file => {
|
|
||||||
if (file._source.format === 'uri') {
|
|
||||||
const base64 = await downloadFileFromURI(file._source.uri);
|
|
||||||
file._previousSave = file;
|
|
||||||
file._data = base64;
|
|
||||||
file._requestTask = null;
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class FilesRouter {
|
export class FilesRouter {
|
||||||
expressRouter({ maxUploadSize = '20Mb' } = {}) {
|
expressRouter({ maxUploadSize = '20Mb' } = {}) {
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
@@ -247,8 +221,6 @@ export class FilesRouter {
|
|||||||
}
|
}
|
||||||
// if the file returned by the trigger has already been saved skip saving anything
|
// if the file returned by the trigger has already been saved skip saving anything
|
||||||
if (!saveResult) {
|
if (!saveResult) {
|
||||||
// if the ParseFile returned is type uri, download the file before saving it
|
|
||||||
await addFileDataIfNeeded(fileObject.file);
|
|
||||||
// update fileSize
|
// update fileSize
|
||||||
const bufferData = Buffer.from(fileObject.file._data, 'base64');
|
const bufferData = Buffer.from(fileObject.file._data, 'base64');
|
||||||
fileObject.fileSize = Buffer.byteLength(bufferData);
|
fileObject.fileSize = Buffer.byteLength(bufferData);
|
||||||
|
|||||||
Reference in New Issue
Block a user