From 27fa8b24b264e3ffb55ff99ff438ba66fd99eb04 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Oct 2020 09:28:46 -0400 Subject: [PATCH 1/4] Update file adapter docs --- _includes/parse-server/file-adapters.md | 50 ++++++++++++------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/_includes/parse-server/file-adapters.md b/_includes/parse-server/file-adapters.md index af29efeab..74d242fc9 100644 --- a/_includes/parse-server/file-adapters.md +++ b/_includes/parse-server/file-adapters.md @@ -17,15 +17,13 @@ When using `Postgres`, you will need to configure `S3Adapter`, `GCSAdapter`, or If you are using `Mongo` and don't need file encryption, there are no additional steps needed to use the `GridStoreAdapter`. If you'd like to enable file encryption follow these instructions to configure Parse Server to use `GridStoreAdapter` with file encryption. -***Notice: If you are coming from an older version of Parse Server versions <= 4.2.0, you should remove `fileKey` from your configurations as it is not being used anyways since legacy parse.com. `fileKey` has been repurposed for file encryption.*** - -### Set up file encryption (available in parse-server 4.3.0+) +### Set up file encryption (available in parse-server 4.4.0+) The `GridStoreAdapter` can encrypt files at rest in `Mongo` using AES256-GCM, allowing the adapter to detect if files are tampered with. To use, simply do any of the following: -- Use the environment variable `PARSE_SERVER_FILE_KEY` -- Pass in --fileKey in the command line when starting your server -- Initialize ParseServer with `fileKey="Your file encryptionKey"`. +- Use the environment variable `PARSE_SERVER_ENCRYPTION_KEY` +- Pass in --encryptionKey in the command line when starting your server +- Initialize ParseServer with `encryptionKey="Your file encryptionKey"`. An example starting your Parse Server in `index.js` is below: @@ -35,7 +33,7 @@ const api = new ParseServer({ cloud: process.env.PARSE_SERVER_CLOUD || __dirname + '/cloud/main.js', appId: process.env.PARSE_SERVER_APPLICATION_ID || 'myAppId', masterKey: process.env.PARSE_SERVER_MASTER_KEY || '', - fileKey: process.env.PARSE_SERVER_FILE_KEY, //Add your file key here. Keep it secret + encryptionKey: process.env.PARSE_SERVER_ENCRYPTION_KEY, //Add your file key here. Keep it secret ... }); ``` @@ -48,23 +46,23 @@ When this is the case, it is recommended to start up a development parse-server ```javascript //You probably want to back up your unencrypted files before doing this. //This can take awhile depending on how many files and how large they are. It will attempt to rotate the key of all files in your filesSubDirectory -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey(); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey(); console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` ### Rotating your encryption key (available in parse-server 4.4.0+) -Periodically you may want to rotate your fileKey for security reasons. When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter with the new key and do the following in your `index.js` (you will need your `oldKey`): +Periodically you may want to rotate your encryptionKey for security reasons. When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter with the new key and do the following in your `index.js` (you will need your `oldKey`): ```javascript //This can take awhile depending on how many files and how large they are. It will attempt to rotate the key of all files in your filesSubDirectory -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey({oldKey: oldKey}); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey({oldKey: oldKey}); console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` ### Removing file encryption (available in parse-server 4.4.0+) -When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. Different from the previous examples, don't initialize your fileAdapter with a `fileKey`. Pass in your `oldKey` to `rotateFileKey()`. +When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. Different from the previous examples, don't initialize your fileAdapter with a `encryptionKey`. Pass in your `oldKey` to `rotateEncryptionKey()`. ```javascript const api = new ParseServer({ @@ -72,24 +70,24 @@ const api = new ParseServer({ cloud: process.env.PARSE_SERVER_CLOUD || __dirname + '/cloud/main.js', appId: process.env.PARSE_SERVER_APPLICATION_ID || 'myAppId', masterKey: process.env.PARSE_SERVER_MASTER_KEY || '', - //No fileKey here + //No encryptionKey here ... }); //This can take awhile depending on how many files and how larger they are. It will attempt to rotate the key of all files in your filesSubDirectory //It is not recommended to do this on the production server, deploy a development server to complete the process. -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey({oldKey: oldKey}); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey({oldKey: oldKey}); console.log('Files rotated to unencrypted with noKey: ' + rotated); console.log('Files that couldn't be rotated to unencrypted with noKey: ' + notRotated); ``` ### Rotating the key for a subset of files -This is useful if for some reason there were errors and some of the files weren't rotated and returned in `notRotated`. The process is the same as the previous examples, but pass in your `oldKey` along with the array of `fileNames` to `rotateFileKey()`. +This is useful if for some reason there were errors and some of the files weren't rotated and returned in `notRotated`. The process is the same as the previous examples, but pass in your `oldKey` along with the array of `fileNames` to `rotateEncryptionKey()`. ```javascript //This can take awhile depending on how many files and how large they are. It will attempt to rotate the key of all files in your filesSubDirectory -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey({oldKey: oldKey, fileNames: ["fileName1.png","fileName2.png"]}); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey({oldKey: oldKey, fileNames: ["fileName1.png","fileName2.png"]}); console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` @@ -324,22 +322,20 @@ var api = new ParseServer({ }) ``` -***Notice: If used with Parse Server versions <= 4.2.0, DO NOT PASS in `PARSE_SERVER_FILE_KEY` or `fileKey` from parse-server. Instead pass your key directly to `FSFilesAdapter` using your own environment variable or hardcoding the string. Parse Server versions 4.3.0+ can pass in `PARSE_SERVER_FILE_KEY` or `fileKey`.*** - ### Using `FSAdapter` with multiple instances of Parse Server When using parse-server-fs-adapter across multiple Parse Server instances it's important to establish "centralization" of your file storage (this is the same premise as the other file adapters, you are sending/recieving files through a dedicated link). You can accomplish this at the file storage level by Samba mounting (or any other type of mounting) your storage to each of your parse-server instances, e.g if you are using Parse Server via docker (volume mount your SMB drive to `- /Volumes/SMB-Drive/MyParseApp1/files:/parse-server/files`). All Parse Server instances need to be able to read/write to the same storage in order for parse-server-fs-adapter to work properly with parse-server. If the file storage isn't centralized, parse-server will have trouble locating files and you will get random behavior on client-side. ### Set up file encryption (available in parse-server-fs-adapter 1.1.0+) The `FSAdapter` can encrypt files at rest for local storage using AES256-GCM, allowing the adapter to detect if files are tampered with. -To use, simply do the same as above, but add a `fileKey`: +To use, simply do the same as above, but add a `encryptionKey`: ```javascript var FSFilesAdapter = require('@parse/fs-files-adapter'); var fsAdapter = new FSFilesAdapter({ "filesSubDirectory": "my/files/folder", // optional - "fileKey": "someKey" //mandatory if you want to encrypt files + "encryptionKey": "someKey" //mandatory if you want to encrypt files }); var api = new ParseServer({ @@ -357,23 +353,23 @@ When this is the case, it is recommended to start up a development parse-server ```javascript //You probably want to back up your unencrypted files before doing this. //This can take awhile depending on how many files and how large they are. It will attempt to rotate the key of all files in your filesSubDirectory -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey(); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey(); console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` ### Rotating your encryption key (available in parse-server-fs-adapter 1.1.0+) -Periodically you may want to rotate your `fileKey` for security reasons. When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter with the new key and do the following in your `index.js` (you will need your `oldKey`): +Periodically you may want to rotate your `encryptionKey` for security reasons. When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter with the new key and do the following in your `index.js` (you will need your `oldKey`): ```javascript //This can take awhile depending on how many files and how large they are. It will attempt to rotate the key of all files in your filesSubDirectory -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey({oldKey: oldKey}); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey({oldKey: oldKey}); console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` ### Removing file encryption (available in parse-server-fs-adapter 1.1.0+) -When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. Different from the previous examples, don't initialize your fileAdapter with a `fileKey`. Pass in your `oldKey` to `rotateFileKey()`. +When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. Different from the previous examples, don't initialize your fileAdapter with a `encryptionKey`. Pass in your `oldKey` to `rotateEncryptionKey()`. ```javascript const api = new ParseServer({ @@ -381,24 +377,24 @@ const api = new ParseServer({ cloud: process.env.PARSE_SERVER_CLOUD || __dirname + '/cloud/main.js', appId: process.env.PARSE_SERVER_APPLICATION_ID || 'myAppId', masterKey: process.env.PARSE_SERVER_MASTER_KEY || '', - filesAdapter: new FSFilesAdapter(), //No fileKey supplied + filesAdapter: new FSFilesAdapter(), //No encryptionKey supplied ... }); //This can take awhile depending on how many files and how larger they are. It will attempt to rotate the key of all files in your filesSubDirectory //It is not recommended to do this on the production server, deploy a development server to complete the process. -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey({oldKey: oldKey}); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey({oldKey: oldKey}); console.log('Files rotated to unencrypted with noKey: ' + rotated); console.log('Files that couldn't be rotated to unencrypted with noKey: ' + notRotated); ``` ### Rotating the key for a subset of files -This is useful if for some reason there were errors and some of the files weren't rotated and returned in `notRotated`. The process is the same as the previous examples, but pass in your `oldKey` along with the array of `fileNames` to `rotateFileKey()`. +This is useful if for some reason there were errors and some of the files weren't rotated and returned in `notRotated`. The process is the same as the previous examples, but pass in your `oldKey` along with the array of `fileNames` to `rotateEncryptionKey()`. ```javascript //This can take awhile depending on how many files and how large they are. It will attempt to rotate the key of all files in your filesSubDirectory -const {rotated, notRotated} = await api.filesAdapter.rotateFileKey({oldKey: oldKey, fileNames: ["fileName1.png","fileName2.png"]}); +const {rotated, notRotated} = await api.filesAdapter.rotateEncryptionKey({oldKey: oldKey, fileNames: ["fileName1.png","fileName2.png"]}); console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` From 4812461d5b8c1e7d71c4bc39b38be9d7458a7a42 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Oct 2020 09:48:15 -0400 Subject: [PATCH 2/4] Add file adapter to postgres database docs --- _includes/parse-server/database.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_includes/parse-server/database.md b/_includes/parse-server/database.md index ccf72fe94..4d30a1b40 100644 --- a/_includes/parse-server/database.md +++ b/_includes/parse-server/database.md @@ -34,6 +34,8 @@ The postgres database adapter will be automatically loaded when you pass a valid postgres://localhost:5432/db?ssl=boolean&rejectUnauthorized=boolean&ca=/path/to/file&pfx=/path/to/file&cert=/path/to/file&key=/path/to/file&passphrase=string&secureOptions=number&client_encoding=string&application_name=string&fallback_application_name=string&max=number&query_timeout=idleTimeoutMillis=number&poolSize=number&binary=boolean&keepAlive=boolean ``` +When using Postgres with your Parse app, you need to manage your indexes yourself. + Details about the configuration options can be found on [pg-promise](https://github.com/vitaly-t/pg-promise/wiki/Connection-Syntax). Some useful combinations are below: * SSL with verification - `postgres://localhost:5432/db?ca=/path/to/file` @@ -41,9 +43,9 @@ Details about the configuration options can be found on [pg-promise](https://git ### Caveats +* You will need to configure a [file adapter](#configuring-file-adapters) in order to store files. * Join tables are resolved in memory, there is no performance improvements using Postgres over MongoDB for relations or pointers. * Mutating the schema implies running ALTER TABLE, therefore we recommend you setup your schema when your tables are not full. -* Properly index your tables to maximize the performance. * The postgres URL for 4.2.0 and below only supports the following configuration options: ``` From d67a42e40887940792eda5deb9d50ddc0305c255 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Oct 2020 09:58:26 -0400 Subject: [PATCH 3/4] Fixed available versions --- _includes/parse-server/file-adapters.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/_includes/parse-server/file-adapters.md b/_includes/parse-server/file-adapters.md index 74d242fc9..949823379 100644 --- a/_includes/parse-server/file-adapters.md +++ b/_includes/parse-server/file-adapters.md @@ -17,8 +17,8 @@ When using `Postgres`, you will need to configure `S3Adapter`, `GCSAdapter`, or If you are using `Mongo` and don't need file encryption, there are no additional steps needed to use the `GridStoreAdapter`. If you'd like to enable file encryption follow these instructions to configure Parse Server to use `GridStoreAdapter` with file encryption. -### Set up file encryption (available in parse-server 4.4.0+) -The `GridStoreAdapter` can encrypt files at rest in `Mongo` using AES256-GCM, allowing the adapter to detect if files are tampered with. +### Set up file encryption +File encryption is available in parse-server 4.4.0+. The `GridStoreAdapter` can encrypt files at rest in `Mongo` using AES256-GCM, allowing the adapter to detect if files are tampered with. To use, simply do any of the following: - Use the environment variable `PARSE_SERVER_ENCRYPTION_KEY` @@ -40,7 +40,7 @@ const api = new ParseServer({ Be sure not to lose your key or change it after encrypting files. -### Enabling encryption on a server that already has unencrypted files (available in parse-server 4.4.0+) +### Enabling encryption on a server that already has unencrypted files When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter as above with the new key and do the following after initialization in your `index.js`: ```javascript @@ -51,7 +51,7 @@ console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` -### Rotating your encryption key (available in parse-server 4.4.0+) +### Rotating your encryption key Periodically you may want to rotate your encryptionKey for security reasons. When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter with the new key and do the following in your `index.js` (you will need your `oldKey`): ```javascript @@ -61,7 +61,7 @@ console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` -### Removing file encryption (available in parse-server 4.4.0+) +### Removing file encryption When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. Different from the previous examples, don't initialize your fileAdapter with a `encryptionKey`. Pass in your `oldKey` to `rotateEncryptionKey()`. ```javascript @@ -325,8 +325,8 @@ var api = new ParseServer({ ### Using `FSAdapter` with multiple instances of Parse Server When using parse-server-fs-adapter across multiple Parse Server instances it's important to establish "centralization" of your file storage (this is the same premise as the other file adapters, you are sending/recieving files through a dedicated link). You can accomplish this at the file storage level by Samba mounting (or any other type of mounting) your storage to each of your parse-server instances, e.g if you are using Parse Server via docker (volume mount your SMB drive to `- /Volumes/SMB-Drive/MyParseApp1/files:/parse-server/files`). All Parse Server instances need to be able to read/write to the same storage in order for parse-server-fs-adapter to work properly with parse-server. If the file storage isn't centralized, parse-server will have trouble locating files and you will get random behavior on client-side. -### Set up file encryption (available in parse-server-fs-adapter 1.1.0+) -The `FSAdapter` can encrypt files at rest for local storage using AES256-GCM, allowing the adapter to detect if files are tampered with. +### Set up file encryption +File encryption is available in parse-server-fs-adapter 1.1.0+. The `FSAdapter` can encrypt files at rest for local storage using AES256-GCM, allowing the adapter to detect if files are tampered with. To use, simply do the same as above, but add a `encryptionKey`: @@ -347,7 +347,7 @@ var api = new ParseServer({ Be sure not to lose your key or change it after encrypting files. -### Enabling encryption on a server that already has unencrypted files (available in parse-server-fs-adapter 1.1.0+) +### Enabling encryption on a server that already has unencrypted files When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter as above with the new key and do the following after initialization in your `index.js`: ```javascript @@ -358,7 +358,7 @@ console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` -### Rotating your encryption key (available in parse-server-fs-adapter 1.1.0+) +### Rotating your encryption key Periodically you may want to rotate your `encryptionKey` for security reasons. When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. On the development server, initialize the file adapter with the new key and do the following in your `index.js` (you will need your `oldKey`): ```javascript @@ -368,7 +368,7 @@ console.log('Files rotated to newKey: ' + rotated); console.log('Files that couldn't be rotated to newKey: ' + notRotated); ``` -### Removing file encryption (available in parse-server-fs-adapter 1.1.0+) +### Removing file encryption When this is the case, it is recommended to start up a development parse-server (or a separate process from your main process) that has the same configuration as your production server. Different from the previous examples, don't initialize your fileAdapter with a `encryptionKey`. Pass in your `oldKey` to `rotateEncryptionKey()`. ```javascript From 2118bc068c3db850f783e83cf23b1a4b960df41d Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 24 Oct 2020 14:38:13 -0400 Subject: [PATCH 4/4] Add default file directory --- _includes/parse-server/file-adapters.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_includes/parse-server/file-adapters.md b/_includes/parse-server/file-adapters.md index 949823379..49f8126a0 100644 --- a/_includes/parse-server/file-adapters.md +++ b/_includes/parse-server/file-adapters.md @@ -306,13 +306,13 @@ new GCSAdapter(projectId, keyfilePath, bucket, options) ## Configuring `FSAdapter` -To use the `FSAdapter`, simply initialize your Parse Server in `index.js` by doing the following: +To use the [FSAdapter](https://github.com/parse-community/parse-server-fs-adapter), simply initialize your Parse Server in `index.js` by doing the following: ```javascript var FSFilesAdapter = require('@parse/fs-files-adapter'); var fsAdapter = new FSFilesAdapter({ - "filesSubDirectory": "my/files/folder" // optional + "filesSubDirectory": "my/files/folder" // optional, defaults to ./files }); var api = new ParseServer({ @@ -323,7 +323,7 @@ var api = new ParseServer({ ``` ### Using `FSAdapter` with multiple instances of Parse Server -When using parse-server-fs-adapter across multiple Parse Server instances it's important to establish "centralization" of your file storage (this is the same premise as the other file adapters, you are sending/recieving files through a dedicated link). You can accomplish this at the file storage level by Samba mounting (or any other type of mounting) your storage to each of your parse-server instances, e.g if you are using Parse Server via docker (volume mount your SMB drive to `- /Volumes/SMB-Drive/MyParseApp1/files:/parse-server/files`). All Parse Server instances need to be able to read/write to the same storage in order for parse-server-fs-adapter to work properly with parse-server. If the file storage isn't centralized, parse-server will have trouble locating files and you will get random behavior on client-side. +When using [parse-server-fs-adapter](https://github.com/parse-community/parse-server-fs-adapter) across multiple Parse Server instances it's important to establish "centralization" of your file storage (this is the same premise as the other file adapters, you are sending/recieving files through a dedicated link). You can accomplish this at the file storage level by Samba mounting (or any other type of mounting) your storage to each of your parse-server instances, e.g if you are using Parse Server via docker (volume mount your SMB drive to `- /Volumes/SMB-Drive/MyParseApp1/files:/parse-server/files`). All Parse Server instances need to be able to read/write to the same storage in order for parse-server-fs-adapter to work properly with parse-server. If the file storage isn't centralized, parse-server will have trouble locating files and you will get random behavior on client-side. ### Set up file encryption File encryption is available in parse-server-fs-adapter 1.1.0+. The `FSAdapter` can encrypt files at rest for local storage using AES256-GCM, allowing the adapter to detect if files are tampered with. @@ -334,7 +334,7 @@ To use, simply do the same as above, but add a `encryptionKey`: var FSFilesAdapter = require('@parse/fs-files-adapter'); var fsAdapter = new FSFilesAdapter({ - "filesSubDirectory": "my/files/folder", // optional + "filesSubDirectory": "my/files/folder", // optional, defaults to ./files "encryptionKey": "someKey" //mandatory if you want to encrypt files });